什么是SpringMVC
原名springWebMVC是spring子框架一个子项目,用于实现web层mvc功能。类似struts2。相对于struts2而言,可以和spring框架无缝整合。开发效率更高,编写更加简洁,性能和安全性更高。
使用
- 导入相关依赖
- 配置springmvc核心》》servlet web.xml
/表示所有经过springmvc的请求(不带后缀的) 如/abc 但/abc.action就不行
由于以上配置导致了springMVC将捕获web容器的所有请求,包括静态资源的请求如js、css等,springMVC会将它们当成普通的请求来处理,因此找不到对应处理器将导致错误。
那么如何让Spring框架能够捕获所有URL的请求,同时又将静态资源的请求转由Web容器处理呢?
这就需要添加一条配置
<mvc:default-servlet-handler/>
或者
关于此配置的作用:
- 1
- 2
- 配置spring的配置文件
- 编写Controller层代码
方法返回值底层为ModelAndView类型
@requestMapping注解的属性
工作流程
数据流入流出
- 流入
获取客户端传递的数据,只要在对应的controller对应的方法添加参数,若数据为基本类型 和String数组,参数名称和请求参数名一致即可,若获取的为对象,spring会mvc会自动实例化,请求参数名为对象的属性名(对象必须有set方法)。数组也一样。
图中,如果u中通样有名为ck的数组,那么两个都有值。
若要传入的数据为对象且对象中包含引用类型 如:
这就需要在表单中的name属性:
若传入的对象为集合类型
自定义类型转换器
表单上传的都是string类型,但是springmvc却能接收,因为它做了自动的类型装换。但是若是对象中有一个Date类型,但是只能接收2000/11/11这种格式的时间,使用其他格式的日期格式就会出错。只能使用自定义的类型转换器。
实现方法:
创建一个类实现Converter接口(所有的类型转换都必须实现这个接口)
在xml中配置
- 流出
返回值
返回值为json
测试异步请求,在使用到jquery时发现静态资源jquery.min.js被拦截需要在xml中配置过滤静态资源
各种注解及细节
@Controller标注控制层
@RequestParam把请求中指定名称的参数给控制器中的形参赋值
@RequestMapping(“/url”)代表请求映射,若写在类上代表命名空间。
@RequestBody用于获得请求体的内容(key=value&&key=value)get请求不适用,因为get请求没有请求体
如果springmvc的参数有@RequestBody注解(接收json字符串格式数据),ajax必须将date属性值转为json字符串,不能为json对象(js对象,会自动转为key=value形式)。并且,修改contentType的值为:application/json; charset=UTF-8,这样加了@RequestBody注解的属性才能自定映射到值。
当ajax需要传递的数据是json对象时如
此时默认的context-type和表单的一样x-www-form-urlencoded
在congtroller中就可以使用@RequestParam
@PathVariable
@PostMapping @GetMapping @DeleteMapping @PutMapping都代表请求映射,只是每个方法的请求方法不同
@RequestHeader获取请求头的值
@CookieValue获取指定cookie的值
@ModeAttribute方法会在控制器的其他方法前执行,一般用于提交的数据不完整的情况,如表单中只有name和age没有data。
有两种方法
有返回值
无返回值
@SessionAttributes 只能写在类上
@ResponseBody 代表返回结果,一般在异步请求使用,若不加这个则会吧返回结果当成响应页面。
@RestController写在类的上面,代表@ResponseBody和@Controller
注解解析器
关于转发和重定向
在写明 redirect 或forward 时,注解解析器不会使用。
异常处理
创建自定义异常类
创建异常处理器对象需要继承HandelExceptionResolve接口
在xml中配置
自定义拦截器
创建一个类实现HanderInterceptor接口
三个方法的功能如下
boolean preHandle 在控制层controller方法执行之前调用,返回true进行后续操作,返回false不允许进入控制层
void postHandle在控制层方法调用之后,视图解析器之前执行,常用于通过该方法请求域中的数据及返回的页面做修改
void afterCompletion 在视图解析器之后调用,用于一些清理工作。
在xml中配置
上传下载
- 上传
springmvc实现上传文件需要进行配置
<!--配置文件上传-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--文件编码方式-->
<property name="defaultEncoding" value="utf-8"></property>
<!--文件最大上传大小(单位kb)-->
<property name="maxUploadSize" value="1024000"></property>
</bean>
上传文件请求方式必须是post
获取文件名
String oldName = headImage.getOriginalFilename();
获取文件后缀
String suffix = oldName.substring(oldName.lastIndexOf("."));
通过uuid给文件重新命名
String newName = UUID.randomUUID().toString() + suffix;
获取文件存储位置的真实路径
String realPath = request.getServletContext().getRealPath("/upload");
创建文件,将图片写入
String path = realPath + File.separator + newName;
File fileImage = new File(path);
if (!fileImage.exists()){
fileImage.mkdirs();
}
headImage.transferTo(fileImage);
- 下载
@RequestMapping("/imageDownload")
public ResponseEntity<byte[]> imageDownload(String fileName, HttpServletRequest req) throws IOException {
String path = req.getServletContext().getRealPath("/upload") + File.separator + fileName;
//获取头部信息
HttpHeaders headers = new HttpHeaders();
//设置返回类型是流
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
//指定文件以附件形式下载,并指定下载之后的文件名
headers.setContentDispositionFormData("attachment",fileName);
byte[] bytes = FileUtils.readFileToByteArray(new File(path));
//参数: 数组,头部信息,请求装态(创建)
return new ResponseEntity<byte[]>(bytes, headers, HttpStatus.CREATED);
}
方法2