记录SpringMVC学习过程中的想要多留意的一些要点
使用SpringMVC后只需要编写处理器Handler(Controller)和视图View,其他组件(DispatcherServlet、ViewResolver)只需要配置好就行。
使用“/”作为DispatcherServlet的拦截方式,所有访问的地址都由DispatcherServlet进行解析,此方法可以实现REST风格的url。但是此方法会导致静态文件(jpg,js,css)被拦截后不能正常显示。
解决方法有:激活Tomcat的defaultServlet来处理静态文件,然后在springMVC-servlet.xml中配置<mvc:default-servlet-handler />
后,会在Spring MVC上下文中定义org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler
,它会对进入DispatcherServlet的URL进行筛查,如果发现是静态资源的请求,就将该请求转由Web应用服务器默认的Servlet处理,如果不是静态资源的请求,才由DispatcherServlet继续处理。
或者采用<mvc:resources />
如
<mvc:resources location="/,classpath:/META-INF/publicResources/" mapping="/resources/**"/>
以上配置将Web根路径"/"及类路径下 /META-INF/publicResources/ 的目录映射为/resources路径。
参考:Spring MVC静态资源处理<mvc:annotation-driven/>
这个类主要是用来向工厂中注册了:
- RequestMappingHandlerMapping
- BeanNameUrlHandlerMapping
- RequestMappingHandlerAdapter
- HttpRequestHandlerAdapter
- SimpleControllerHandlerAdapter
- ExceptionHandlerExceptionResolver
- ResponseStatusExceptionResolver
- DefaultHandlerExceptionResolver
上面几个Bean实例。
前两个是HandlerMapping接口的实现类,用来处理请求映射的。其中第一个是处理@RequestMapping注解的。第二个会将controller类的名字映射为请求url。中间三个是用来处理请求:@Controller注解的处理器,支持自定义方法参数和返回值、处理继承HttpRequestHandler的处理器、处理继承自Controller接口的处理器。后面三个是用来处理异常的解析器。
参考:[Spring MVC 解读——<mvc:annotation-driven/>]
相当于一个标签解决了大量手动配置工作。
(https://my.oschina.net/HeliosFly/blog/205343)
<context:component-scan base-package=“xxx”/>
很实用,这个标签让Spring 来扫描指定包下的类,注册被@Component,@Controller,@Service,@Repository等注解标记的组件.不管前端js有没有做校验,后端都需要对数据进行校验。controller校验页面请求的参数的合法性,service层主要校验关键业务参数。hibernate validation是个很好用的包,使用注解的形式在POJO上完成校验,还能实现分组校验。
在Controller的方法中,需要在要检验的pojo前加@Validated
,然后参数上必须加上BindingResult
,而且得在@Validated
后面。
自定义注解校验器方法:创建注解、创建验证类(要实现接口ConstraintValidator,包括initialize
和isValid
两个方法)、定义默认错误信息
参考:【SpringMVC学习06】SpringMVC中的数据校验异常处理:dao、service、controller出现异常都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理。springmvc提供全局异常处理器进行统一异常处理。配置
SimpleMappingExceptionResolver
可以将异常信息(包括自定义异常信息)显示在页面上。SpringMVC中可以使用@RequestBody,@ResponseBody注解实现Java对象和XML/JSON数据自动转换。使用
<mvc:annotation-driven/>
后,只需要在Controller的方法上使用@ResponseBody
注解就能返回对应的XML或者JSON数据。返回XML数据需要注意实体类上加@XmlRootElement
。返回JSON数据需要Jackson2或者GSON(Spring会自动把GsonHttpMessageConverter加进来),不需要实体类上加注解。如果Accept属性中包含了/,表示接受任意格式返回数据。
@RequestBody
注解在Controller类的参数上可以将XML或者JSON数据转换成JAVA类。
参考:
SpringMVC中使用@RequestBody,@ResponseBody注解实现Java对象和XML/JSON数据自动转换(上)
SpringMVC中使用@RequestBody,@ResponseBody注解实现Java对象和XML/JSON数据自动转换(下)
这两篇把原理讲的很清楚,非常钦佩作者的技术实力和撰文能力。数据回显:提交后,如果出现错误,将刚才提交的数据回显到刚才的提交页面。pringmvc默认对pojo数据进行回显。pojo数据传入controller方法后,springmvc自动将pojo数据放到request域,key等于pojo类型(首字母小写)。使用@ModelAttribute指定pojo回显到页面在request中的key。
直接使用model.addAttribute("xxx", xxx )
也能回显数据。Springmvc的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。在springmvc中,定义拦截器要实现
HandlerInterceptor
接口的三个方法:preHandle
(身份认证、身份授权)、postHandle
(公用的模型数据)、afterCompletion
(统一异常处理,统一日志处理)。
全局拦截器配置:
<!-- 配置拦截器 -->
<mvc:interceptors>
<!-- 多个拦截器,按顺序执行 -->
<mvc:interceptor>
<mvc:mapping path="/**"/> <!-- 表示拦截所有的url包括子url路径 -->
<bean class="xxx"/>
</mvc:interceptor>
...
</mvc:interceptors>
拦截器可以用来实现登陆认证(要点:在session中保存用户身份信息)。
参考:springmvc学习笔记(20)-拦截器
-
上传
需要的maven包:commons-fileupload
页面form中提交enctype="multipart/form-data"的数据时,需要springmvc对multipart类型的数据进行解析。
在springmvc.xml中配置multipart类型解析器:
<!-- 文件上传 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的最大尺寸为5MB -->
<property name="maxUploadSize" value="5242880"/>
<property name="defaultEncoding" value="utf-8"/>
</bean>
在上传文件之前,首先要创建一个虚拟目录来保存文件,这个虚拟目录会对应磁盘上的一个实际的目录。
后端代码(比如上传图片):
@RequestMapping("/editItemsSubmit")
public String editItemsSubmit(Model model, HttpServletRequest request,
Integer id,
@Validated(value = { MyValidator.class }) ItemsCustom itemsCustom,
BindingResult bindingResult,
MultipartFile items_pic)
throws Exception {
// 处理上传的单个图片
String originalFileName = items_pic.getOriginalFilename();// 原始名称
// 上传图片
if (items_pic != null && originalFileName != null && originalFileName.length() > 0) {
// 存储图片的物理路径
String pic_path = "D:\\temp";
// 新的图片名称
String newFileName = UUID.randomUUID()
+ originalFileName.substring(originalFileName
.lastIndexOf("."));
File newFile = new File(pic_path + newFileName);//新图片
items_pic.transferTo(newFile);// 将内存中的数据写入磁盘
itemsCustom.setPic(newFileName);// 将新图片名称写到itemsCustom中
} else {
//如果用户没有选择图片就上传了,还用原来的图片
ItemsCustom temp = itemsService.findItemsById(itemsCustom.getId());
itemsCustom.setPic(temp.getPic());
}
// 调用service更新商品信息,页面需要将商品信息传到此方法
itemsService.updateItems(id, itemsCustom);
return "success";
}
//itemsCustom是实体类
//items_pic名字与前端保持一致
参考:【SpringMVC学习08】SpringMVC中实现文件上传
- RestTemplate的使用:
- GET请求:
getForEntity
方法的返回值是一个ResponseEntity<T>
,ResponseEntity<T>
是Spring对HTTP请求响应的封装,包括了几个重要的元素,如响应码、contentType、contentLength、响应消息体等。responseEntity.getBody()
可以以xml或JSON型式返回类数据。 - POST请求:
postForEntity
与getForEntity
相似,可以传一个类给服务器。 - PUT请求:
put
与postForEntity
差不多,没有返回值。 - DELETE请求:
delete
参考:Spring RestTemplate中几种常见的请求方式
-
Controller里处理Session
session.getAttribute
、session.setAttribute
@SessionAttributes
value值代表我们需要把什么样的对象放入session,当我们把对象放入ModelMap这个对象的时候,如果给出的key也会自动放入session。只能注解于类或者接口。
还可以利用@ModelAttribute
与@SessionAttributes
相互配合,隐性的获取到放在session中的值。
参考:Spring MVC系列(四)之session处理---@SessionAttributes