文章目录
1. 参数校验 - 使用hiebernate的校验包
1.1 常用注解
图片来自其他博客:https://blog.csdn.net/dh554112075/article/details/80790464
1.2 小案例
1. springMVC.xml的配置
<!--使有关SpringMVC的注解生效 ~ 配置校验参数的注解使用哪一个Class进行解析 -->
<mvc:annotation-driven validator="localValidatorFactoryBean" ></mvc:annotation-driven>
<!-- 声明需要使用到的校验器 - 交给容器管理 -->
<bean id="localValidatorFactoryBean" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="ProviderClass" value="org.hibernate.validator.HibernateValidator" ></property>
</bean>
2. add.jsp - 表单添加页面
<form action="${pageContext.request.contextPath}/users/addUI" method="post">
name:<input type="text" name="name">
<br/>
age:<input type="text" name="age">
<br/>
id:<input type="text" name="id">
<br/>
password:<input type="text" name="password">
<br/>
<input type="submit" value="添加">
</form>
3. User.java – javaBean对象
public class User {
String name;
Integer age;
// 账号密码不能为空 - 利用注解自行校验
@NotBlank
String id;
@NotBlank
String password;
}
4. UserServlet - 请求处理页面
@Controller
@RequestMapping("/users/")
public class UserServlet {
// 映射的地址应该是: /users/addUI
@RequestMapping(value="/addUI")
public String add() {
return "user/add";
}
@RequestMapping(value="/addUI", method=RequestMethod.POST)
public ModelAndView add2(@ModelAttribute(value="myUser") @Validated User user, Errors errors) {
ModelAndView mav = new ModelAndView();
if(errors.hasErrors()) {
List<FieldError> fieldErrors = errors.getFieldErrors();
for(FieldError fe : fieldErrors) {
System.out.println(fe.getField() + ":" + fe.getDefaultMessage());
}
mav.setViewName("user/add");
return mav;
}
mav.setViewName("redirect:/users/list");
return mav;
}
}
运行效果
如果不填id、password两个选项,则直接后面报有信息
2. 文件上传
2.1 单文件上传
步骤:
-
导入JAR包
-
配置springMVC - CommonsMultipartResolver
小案例
1. springMVC.xml的配置
<!--注意这里的ID名不可以省略,我也不知道为什么。一省略就出错-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="400000"></property>
</bean>
2. uploadTest.jsp – 前端页面
<body>
<form action="${pageContext.request.contextPath}/pages/upload"
method="post" enctype="multipart/form-data">
<input type="file" name="uploadFile"><br/>
<input type="submit" value="上传">
</form>
<div>
<h2>上传了文件:</h2>
<h5>
<c:choose>
<c:when test="${ not empty fileMessage.fileName}">
文件名:${fileMessage.fileName} <br/>
文件类型:${fileMessage.contentType} <br/>
文件大小${fileMessage.size } <br/>
请求参数名:${fileMessage.fileParamName}
</c:when>
<c:otherwise>
当前无文件上传
</c:otherwise>
</c:choose>
</h5>
</div>
</body>
3. FileMessage.java - 保存上传文件信息的Bean对象
public class FileMessage {
Object fileName;
Object contentType;
Object fileParamName;
Object size;
}
4. pageServelt.java - 请求处理控制器
@Controller
@RequestMapping(value = "pages")
public class PageServlet {
// 用来进行跳转到文件上传页面
@RequestMapping(value="upload", method= {
RequestMethod.GET})
public String upload() {
return "/page/uploadTest";
}
// 处理前端页面传过来的文件
@RequestMapping(value="upload", method= {
RequestMethod.POST})
public String upload(MultipartFile uploadFile, HttpSession session) {
// 获取文件的信息
Object contentType = uploadFile.getContentType();
Object fileName = uploadFile.getOriginalFilename();
Object size = uploadFile.getSize();
Object fileParamName = uploadFile.getName();
// 将文件的信息传入到fileMessage的Bean对象
top.linruchang.domain.FileMessage fm = new top.linruchang.domain.FileMessage();
fm.setContentType(contentType);
fm.setFileName(fileName);
fm.setFileParamName(fileParamName);
fm.setSize(size);
session.setAttribute("fileMessage", fm);
// 将上传的文件复制到桌面
try {
uploadFile.transferTo(new File("E:\\测试\\" + fileName));
} catch (IllegalStateException | IOException e) {
e.printStackTrace();
}
// 重定向到文件上传页面
return "redirect:/pages/upload";
}
}
运行效果
2.2 多文件上传
1. 跟上面的代码差不多
2. 注意的是:形参上必须写@RequestParam(“input的name名”),即使形参跟name一样也需要写,否则报错
// 处理前端多文件上传页面传过来的文件 - 切记形参上必须写@RequestParam("")
@RequestMapping(value="uploads", method= {
RequestMethod.POST})
public String uploads(@RequestParam("uploadFiles") MultipartFile[] uploadFiles) {
if(uploadFiles == null) {
System.out.println("上传的文件没有接收到");
}
for(MultipartFile mf : uploadFiles) {
Object fileName = mf.getOriginalFilename();
try {
mf.transferTo(new File("E:\\测试\\" + fileName));
} catch (IllegalStateException | IOException e) {
e.printStackTrace();
}
System.out.println("上传成功" + fileName);
}
// 重定向到文件上传页面
return "redirect:/pages/uploads";
}
3. 异常处理
3.1 使用步骤
3.2 简单使用 - 案例
1. 自定义异常
public class CustomException extends RuntimeException {
private static final long serialVersionUID = 1L;
public CustomException() {
super();
}
public CustomException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public CustomException(String message, Throwable cause) {
super(message, cause);
}
public CustomException(String message) {
super(message);
}
public CustomException(Throwable cause) {
super(cause);
}
}
2. 自定义异常处理器
public class MyExceptionHandler implements HandlerExceptionResolver{
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) {
ModelAndView mav = new ModelAndView();
if( ex instanceof CustomException) {
mav.setViewName("/exception/customException");
return mav;
}
return null;
}
}
3. springMVC.xml – 自定义异常处理器交给容器管理
<bean class="top.linruchang.exception.MyExceptionHandler"></bean>
4. 异常发生时的页面
<body>
<h1 style="color:red">请求执行时发生自定义异常</h1>
</body>
5. 自己模仿抛出一个异常出来
运行效果
4. JSON-Java对象之间的转换
4.1 使用步骤
使用步骤
-
导入JAR包
-
使用注解进行修饰JSON数据、Java对象的转换
@ReuqestBody:修饰形参对象-JSON数据转为Java对象
@ResponseBody:修饰具有返回值的方法 - 将Java对象转为JSON数据字符串
4.2 小案例
1. JSONTest.jsp – 前端页面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src='${pageContext.request.contextPath}/static/js/jquery-3.4.1.min.js' type='text/javascript'></script>
</head>
<body>
<button id="btn">发送json数据,并且返回json数据</button>
</body>
<script>
$(function() {
$("#btn").click(function() {
$.ajax({
type:"post",
url:"${pageContext.request.contextPath}/pages/JSONTest",
data: '{"name":"lrc", "age":18, "id":"lrcnb", "password":"123456"}',
contentType:"application/json;charset=utf-8",
success:function(data) {
console.log(data);
}
})
})
})
</script>
</html>
2. pageServlet.java - 控制器
@Controller
@RequestMapping(value = "pages")
public class PageServlet {
// 将请求跳转到JSONTest测试页面
@RequestMapping(value="JSONTest", method= {
RequestMethod.GET})
public String JSONTest() {
return "/page/JSONTest";
}
//JSON的转换 -- 处理AJAX请求
@RequestMapping(value="JSONTest", method= {
RequestMethod.POST})
@ResponseBody //将返回的Java对象转为Json数据字符串
public User JSONTest(@RequestBody User user) {
//json数据转为Java对象
System.out.println("json转为User对象:" + user);
return user;
}
}
运行效果
5. Restful - 请求地址编写风格
5.1 概念
一般我们更新都需要表单,然而只支持GET、POST两种请求方式,想要达成Restful风格要求,则需要隐藏表单值是请求方式、以及SPringMVC内置的过滤器进行更改对应的请求 - 当然也可以自己写过滤器更改请求方法
AJAX能发送多种请求方式
5.2 小案例
1. web.xml - 请求转换过滤器配置
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2. list.jsp - 数据显示页面
<body>
<table border="1">
<thead>
<tr>
<th>姓名</th>
<th>年龄</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<c:forEach items="${requestScope.users}" var="user">
<tr>
<td>${user.name}</td>
<td>${user.age}</td>
<td>
<a href="${pageContext.request.contextPath}/users/updateUI?name=${user.name}&age=${user.age}">修改</a>
<a href="${pageContext.request.contextPath}/users/deleteUI?name=${user.name}&age=${user.age}">删除</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
<br/><br/>
<a href="${pageContext.request.contextPath}/users/addUI">添加记录</a>
</body>
3. update.jsp - 数据更新页面
<body>
<form action="${pageContext.request.contextPath}/users/updateUI" method="post">
<input type="hidden" name="_method" value="put">
<input type="text" name="name" readonly="readonly" value="${requestScope.user.name}">
<input type="text" name="age" value="${requestScope.user.age}">
<input type="submit" >
</form>
</body>
4. UserServlet - 请求处理器
@Controller
@RequestMapping("/users/")
public class UserServlet {
// 保存用户的信息 -- 只是模拟,数据应该从数据库中取
static List<User> users = new ArrayList<User>();
static {
User user = new User();
user.setName("lrc");
user.setAge(25);
users.add(user);
}
// 默认处理 get请求 -- 处理其他的请求方式需要自己手动定义
// 映射的地址应该是: /users/list
// 客户真正的请求地址等于处理类上的@RequestMapping地址+方法类上的@RequestMapping上的注解
@RequestMapping("list")
public ModelAndView list() {
ModelAndView mav = new ModelAndView();
mav.addObject("users", users);
// 视图名 - 需要交给springmvc.XML配置的的InternalResourceViewResolver进行转换成真正的地址
mav.setViewName("user/list");
return mav;
}
@RequestMapping(value="/updateUI")
public ModelAndView update(User user) {
ModelAndView mav = new ModelAndView();
mav.addObject("user", user);
mav.setViewName("user/update");
return mav;
}
@RequestMapping(value="/updateUI", method=RequestMethod.PUT)
public ModelAndView update2(User user, HttpServletRequest req) {
System.out.println(req.getMethod());
System.out.println(user);
for(User user1 : users) {
if(user1.getName().equals(user.getName())) {
user1.setAge(user.getAge());
break;
}
}
ModelAndView mav = new ModelAndView();
mav.setViewName("redirect:/users/list");
return mav;
}
}
运行效果