知识清单
基础知识清单
SpringMVC框架(重点)
MVC在B/S系统中的应用方式
SpringMVC框架原理(DispatcherServlet前端控制器、处理器映射器、处理器适配器、视图解析器)
SpringMVC入门程序
需求:商品列表查询
常用的处理器映射器,处理器适配器
注解的处理器映射器,处理器适配器用于注解开发(重点)
注解开发基础
SpringMVC与Struts的区别
高级知识清单(第二部分)
使用SpringMVC上传图片
集合参数的绑定
validation校验器
异常处理器的使用(用于系统异常处理)
Restful支持
拦截器
SpringMVC框架
SpringMVC是什么?
springmvc是Spring的一个模块,提供web层解决方案(就与MVC设计架构)
MVC在B/S系统中的应用
MVC是一种设计模式,在B/S中的应用如下图所示:
SpringMVC的框架
执行过程大致如下:
第一步:用户发起request请求,请求至DispatcherServlet前端控制器。
第二步:DispatcherServlet前端控制器请求HandlerMapping处理器映射器查找Handler。DispatcherServlet: 前端控制器,相当于中央调度器,各个组件都和前端控制器进行交互,降低了各个组件之间的耦合度。
第三步:HandlerMapping处理器映射器,根据url及一些配置规则(xml配置、注解配置)查找Handler,将Handler返回给DispatcherServlet前端控制器。
第四步:DispatcherServlet前端控制器调用适配器执行Handler,有了适配器通过适配器去扩展对不同Handler执行方式(比如:原始servlet开发,注解开发)
第五步:适配器执行Handler;Handler是后端控制器,可以当成模型 。
第六步:Handler执行完后后返回ModelAndView。ModelAndView: SpringMVC的一个对象,对model和view进行封装。
第七步:适配器将ModelAndView返回给DispatcherServlet前端控制器。
第八步:DispatcherServlet调用视图解析器进行视图解析,解析后生成view,视图解析器根据逻辑视图名解析出真正的视图。view:SpringMVC视图封装对象,提供了很多view,比如jsp、freemarker、pdf、execel....... 。
第九步:ViewResolver视图解析器给前端控制器返回view。
第十步:DispatcherServlet调用view的渲染视图的方法,将模型数据填充到request域。
第十一步:DispatcherServlet向用户响应结果(jsp页面、json数据......).
DispatcherServlet:前端控制器,由SpringMVC提供。
HandlerMapping:处理器映射器,由SpringMVC提供。
HandlerAdapter:处理器适配器,由SpringMVC提供。
Handler:处理器,需要程序员开发。
ViewResolver:视图解析器,由SpringMVC提供。
view:真正的视图页面,由程序员编写。
入门程序
需求
实现商品列表查询
需要的jar包
使用spring3.2.0(带springmvc模块) 如下图所示
前端控制器
在web.xml中进行配置
springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
springmvc
*.action
springmvc.xml
在springmvc.xml中配置springmvc架构的三大组件(处理器映射器、处理器适配器、视图解析器)
工程结构
处理器映射器
在springmvc.xml中进行配置:
BeanNameURLHandlerMapping:根据url( xxx.action ) 匹配Spring容器的name。
找到对应的Bean(程序员编写的Handler)
注意:所有处理器映射器都实现HandlerMapping接口 。
处理器适配器
在springmvc.xml中配置:
注意:所有的适配器都是实现了HandlerAdapter接口 。
程序员编写Handler要根据所配置的适配器的要求编写。
SimpleControllerHandlerAdapter适配器要求:通过supports方法知道Handler必须要实现哪个接口
查看HandlerAdapter(适配器接口)源代码如下:
public interface HandlerAdapter {
// 已经去除文档注释
boolean supports(Object handler);
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
long getLastModified(HttpServletRequest request, Object handler);
}
查看SimpleControllerHandlerAdapter适配器源码如下:
public class SimpleControllerHandlerAdapter implements HandlerAdapter {
public boolean supports(Object handler) {
return (handler instanceof Controller);
}
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return ((Controller) handler).handleRequest(request, response);
}
public long getLastModified(HttpServletRequest request, Object handler) {
if (handler instanceof LastModified) {
return ((LastModified) handler).getLastModified(request);
}
return -1L;
}
}
可以发现
SimpleControllerHandlerAdapter类型的 处理器适配器通过support方法根据Handler对象是否实现了Controller接口来进行判断是否支持Handler,凡是实现了Controller接口的类都可以被简单类型的处理器适配器匹配调用,简单处理器适配器通过在handle方法中调用Handler实现Controller接口的HandleRequest方法向前端控制器返回ModelAndView。
Handler的编写
需要实现Controller接口
public class ItemController1 implements Controller {
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 使用静态数据将商品信息展示在jsp页面上
// 商品列表
List itemsList = new ArrayList();
Items items_1 = new Items();
items_1.setName("联想笔记本");
items_1.setPrice(6000f);
items_1.setCreatetime(new Date());
items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
Items items_2 = new Items();
items_2.setName("苹果手机");
items_2.setPrice(5000f);
items_2.setDetail("iphone6苹果手机!");
itemsList.add(items_1);
itemsList.add(items_2);
ModelAndView modelAndView = new ModelAndView();
// 将数据填充到request
// request.setAttribute("itemList", itemsList);
modelAndView.addObject("itemsList", itemsList);
// 指定转发到JSP页面
modelAndView.setViewName("/WEB-INF/jsp/itemsList.jsp");
return modelAndView;
}
}
配置Handler
在springmvc.xml中配置Handler,由Spring管理Handler。
访问:http://localhost:8080/springmvc_first/itemList.action
异常
地址中Handler名称输入错误
HandlerMapping没有找到Handler,message中不显示jsp路径,这种错误一般是由于输入地址操作导致
要转向的JSP页面不存在
其它非注解处理器映射器和适配器
BeanNameUrlHandlerMapping(映射器)
根据请求url (xxx.action)匹配Spring容器中bean的name
找到对应的bean(程序编写的Handler)
SimpleUrlHandlerMapping(映射器)
itemController1
itemController1
注意:在springmvc.xml中配置了多个处理器映射器,多个处理器映射器就可以共存,不会排斥 。
SimpleControllerHandlerAdapter(适配器)
要求程序编写的Handler (controller)需要实现Controller接口。
HttpRequestHandlerAdapter(适配器)
在springmvc.xml中配置:HttpRequestHandlerAdapter
要求编写的Handler实现 HttpRequestHandler接口
配置HttpRequestHandlerAdapter适配器
开发Handler
public class ItemController2 implements HttpRequestHandler {
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 使用静态数据将商品信息展示在jsp页面上
// 商品列表
List itemsList = new ArrayList();
Items items_1 = new Items();
items_1.setName("联想笔记本");
items_1.setPrice(6000f);
items_1.setCreatetime(new Date());
items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
Items items_2 = new Items();
items_2.setName("苹果手机");
items_2.setPrice(5000f);
items_2.setDetail("iphone6苹果手机!");
itemsList.add(items_1);
itemsList.add(items_2);
request.setAttribute("itemsList", itemsList);
request.getRequestDispatcher("/WEB-INF/jsp/itemsList.jsp").forward(request, response);
}
}
可以发现。HttpRequestHandler的开发方式和原始的Servlet开发方式很相近
配置Handler
itemController1
itemController2
DispatcherServlet.properties
DispatcherServlet前端控制器加载DispatcherServlet.properties配置文件,从而默认加载各个组件。
如果在springmvc.xml中配置了处理器映射器和适配器,以springmvc.xml的为准。
注解映射器和适配器
注解映射器
Spring3.1之前默认加载器是org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping,3.1之后要使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping。
在springmvc.xml中配置RequestMappingHandlerMapping:
使用RequestMappingHandlerMapping 注解映射器需要在Handler中使用@Controller标识此类是一个控制器,使用@RequestMapping指定Handler方所对应的url。
注解适配器
Spring3.1之前默认加载映射器是org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter,3.1之后要使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
RequestMappingHandlerAdapter 注解适配器不要求Handler实现任何接口,但它需要和RequestMappingHandlerMapping注解映射器配对使用,主要解析Handler方法中的形参。在springmvc.xml中配置RequestMappingHandlerAdapter如下:
@Controller
public class ItemController3 {
// 商品列表,@RequestMapping中的url建议和方法名一致,方便开发维护
@RequestMapping("/queryItems")
public ModelAndView queryItems() throws ServletException, IOException {
// 使用静态数据将商品信息展示在jsp页面上
// 商品列表
List itemsList = new ArrayList();
Items items_1 = new Items();
items_1.setName("联想笔记本");
items_1.setPrice(6000f);
items_1.setCreatetime(new Date());
items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
Items items_2 = new Items();
items_2.setName("苹果手机");
items_2.setPrice(5000f);
items_2.setDetail("iphone6苹果手机!");
itemsList.add(items_1);
itemsList.add(items_2);
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("itemsList",itemsList);
// 指定逻辑视图名
modelAndView.setViewName("/WEB-INF/jsp/itemsList.jsp");
return modelAndView;
}
}
配置Handler
建议使用组件扫描,组件扫描可以扫描@Controller、@Service、@Component、@Repository
注意:要想使用注解扫描器,Spring的版本要在4.0以上,不然会抛出异常 。
小结
DispatcherServlet:前端控制器,相当于中央调度器,可以降低组件之间的耦合度。
HandlerMapping:处理器映射器,负责根据url查找Handler。
HandlerAdapter:处理器适配器,负责根据适配器要求的规则去执行处理器。可以通过扩展适配器支持不同类型的Handler。
ViewResolver:视图解析器,根据逻辑视图名解析成真正的视图。
注意:逻辑视图名只是在ModelAndView对象中设置视图时适用,对于原始的Servlet(使用request和response进行转发或重定向)不适用。
执行过程中关键源代码如下:
1.DispatcherServlet通过HandlerMapping查找Handler
2.DispatcherServlet通过适配器去执行Handler,得到ModelAndView (在DispatcherServlet中的doDispatch方法中执行整个流程)
3.视图解析
视图解析后得到一个view
4.进行视图渲染
所谓的视图渲染就是将Model中的数据填充到request域
springmvc入门源码
代码已经上传GitHub https://github.com/LX1993728/springmvc_first
web.xml
springmvc_first
springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
springmvc
*.action
index.html
index.htm
index.jsp
default.html
default.htm
default.jsp
springmvc.xml
itemController1
itemController2
itemsList.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
查询商品列表
ItemController1.java
package lx.springmvc.first;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import lx.springmvc.po.Items;
/**
* 入门程序,商品列表查询
*
* @author liuxun
*
*/
public class ItemController1 implements Controller {
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 使用静态数据将商品信息展示在jsp页面上
// 商品列表
List itemsList = new ArrayList();
Items items_1 = new Items();
items_1.setName("联想笔记本");
items_1.setPrice(6000f);
items_1.setCreatetime(new Date());
items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
Items items_2 = new Items();
items_2.setName("苹果手机");
items_2.setPrice(5000f);
items_2.setDetail("iphone6苹果手机!");
itemsList.add(items_1);
itemsList.add(items_2);
ModelAndView modelAndView = new ModelAndView();
// 将数据填充到request
// request.setAttribute("itemList", itemsList);
modelAndView.addObject("itemsList", itemsList);
// 指定转发到JSP页面
modelAndView.setViewName("/WEB-INF/jsp/itemsList.jsp");
return modelAndView;
}
}
ItemController2.java
package lx.springmvc.first;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.HttpRequestHandler;
import lx.springmvc.po.Items;
/**
* 入门程序,商品列表查询
*
* @author liuxun
*
*/
public class ItemController2 implements HttpRequestHandler {
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 使用静态数据将商品信息展示在jsp页面上
// 商品列表
List itemsList = new ArrayList();
Items items_1 = new Items();
items_1.setName("联想笔记本");
items_1.setPrice(6000f);
items_1.setCreatetime(new Date());
items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
Items items_2 = new Items();
items_2.setName("苹果手机");
items_2.setPrice(5000f);
items_2.setDetail("iphone6苹果手机!");
itemsList.add(items_1);
itemsList.add(items_2);
request.setAttribute("itemsList", itemsList);
request.getRequestDispatcher("/WEB-INF/jsp/itemsList.jsp").forward(request, response);
}
}
ItemController3.java
package lx.springmvc.first;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.servlet.ServletException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import lx.springmvc.po.Items;
/**
* 入门程序,商品列表查询
*
* @author liuxun
*
*/
@Controller
public class ItemController3 {
// 商品列表,@RequestMapping中的url建议和方法名一致,方便开发维护
@RequestMapping("/queryItems")
public ModelAndView queryItems() throws ServletException, IOException {
// 使用静态数据将商品信息展示在jsp页面上
// 商品列表
List itemsList = new ArrayList();
Items items_1 = new Items();
items_1.setName("联想笔记本");
items_1.setPrice(6000f);
items_1.setCreatetime(new Date());
items_1.setDetail("ThinkPad T430 联想笔记本电脑!");
Items items_2 = new Items();
items_2.setName("苹果手机");
items_2.setPrice(5000f);
items_2.setDetail("iphone6苹果手机!");
itemsList.add(items_1);
itemsList.add(items_2);
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("itemsList",itemsList);
// 指定逻辑视图名
modelAndView.setViewName("itemsList");
return modelAndView;
}
}
SpringMVC和Mybatis整合工程搭建
整合思路
在Mybatis和Spring整合的基础上 添加springmvc
Spring要管理springmvc编写的Handler(controller)、mybatis的SqlSessionFactory、mapper
第一步:整合Dao,Spring和mybatis整合
第二步:整合Service,Spring管理Service接口,Service中可以调用Spring容器中的dao (mapper)
第三步:整合controller,Spring管理controller接口,在controller调用Service
导入jar包
mybatis:3.2.7
Spring:3.2.0
mybatis的jar
mybatis和Spring整合包
Spring的相关Jar包(包括SpringMVC的包)
数据库驱动包
log4j日志
工程结构
配置文件
applicationContext-dao.xml——配置数据源、SqlSessionFactory、mapper扫描器
applicationContext-service.xml——配置Service接口
applicationContext-transaction.xml——事务管理
springmvc.xml——SpringMVC的配置,配置处理器映射器、适配器、视图解析器
SqlMapConfig.xml——mybatis的配置文件,配置别名、settings、mapper
applicationContext-dao.xml
配置mybatis的数据源、sqlSessionFactory、mapper扫描器
${jdbc.driver}
${jdbc.url}
${jdbc.username}
${jdbc.password}
applicationContext-transaction.xml
在此配置文件配置事务,声明式事务控制
前端控制器配置
springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:spring/springmvc.xml
springmvc
*.action
配置springmvc.xml
商品列表开发
需求
查询商品列表
mapper
功能描述:根据条件查询商品信息,返回商品列表
一般情况下对查询mapper需要自定义mapper
首先针对单表进行逆向工程,生成代码(包括PO类、mapper.xml、mapper.java)如下图所示:
mapper.xml
为了避免影响逆向工程生成的代码,一般不去修改,新建一个自定义的mapper(.xml和.java)
新建ItemsMapperCustom.xml 添加如下配置
and name like '%${itemsCustom.name.trim()}%'
and id = #{itemsCustom.id}
SELECT * FROM items
包装类:ItemsQueryVo
public class ItemsQueryVo {
// 商品信息
private ItemsCustom itemsCustom;
// setter与getter
......
}
mapper.java
新建接口ItemsMapperCustom.java
// 商品查询列表
public List findItemsList(ItemsQueryVo itemsQueryVo) throws Exception;
Service
public class ItemsServiceImpl implements ItemsService {
// 注入mapper
@Autowired
private ItemsMapperCustom itemsMapperCustom;
@Autowired
private ItemsMapper itemsMapper;
public List findItemsList(ItemsQueryVo itemsQueryVo) throws Exception {
return itemsMapperCustom.findItemsList(itemsQueryVo);
}
}
在applicationContext-service.xml中配置Service
controller
@Controller
public class ItemsController {
// 注入Service
@Autowired
private ItemsService itemsService;
@RequestMapping("queryItems")
public ModelAndView queryItems(HttpServletRequest request) throws Exception {
// 调用Service查询商品列表
List itemsList = itemsService.findItemsList(null);
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("itemsList", itemsList);
// 指定逻辑视图名
modelAndView.setViewName("itemsList");
return modelAndView;
}
}
jsp
在web.xml中配置Spring监听器
contextConfigLocation
classpath:spring/applicationContext-*.xml
org.springframework.web.context.ContextLoaderListener
注解开发基础
商品修改
需求
功能描述:商品信息修改
操作流程:
1.在商品列表页面点击修改链接。
2.打开商品修改页面,显示了当前商品的信息。
(根据商品的id查询商品信息)
3.修改商品信息,点击提交
(更新商品信息)
mapper
已使用逆向工程生成代码:
根据商品id查询商品信息
更新商品信息
Service
// 根据商品id查询商品信息
public ItemsCustom findItemsById(int id) throws Exception;
// 更新商品信息
/**
* 定义Service接口,遵循单一职责,将业务参数细化(不要使用包装类型,比如Map)
* @param id 修改商品的id
* @param itemsCustom 修改商品的信息
* @throws Exception
*/
public void updateItems(Integer id,ItemsCustom itemsCustom) throws Exception;
@RequestMapping
设置方法对应的url(完成url映射)
一个方法对应一个url
@RequestMapping("/queryItems")
public ModelAndView queryItems(HttpServletRequest request) throws Exception {
窄化请求映射
在Class上定义根路径
@Controller
//定义url的根路径,访问时 根路径+方法的url
@RequestMapping("/items")
public class ItemsController {
好处:重新规范系统的url,避免url冲突
限制http请求的方法
通过requestMapping限制url请求的http方法
如果限制请求必须是post,如果get请求就会抛出异常
商品修改方法,限制为http的get:
@RequestMapping(value="/editItems",method={RequestMethod.GET})
controller方法返回值
返回ModelAndView
@RequestMapping("/queryItems")
public ModelAndView queryItems(HttpServletRequest request) throws Exception {
// 调用Service查询商品列表
List itemsList = itemsService.findItemsList(null);
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("itemsList", itemsList);
// 指定逻辑视图名
modelAndView.setViewName("itemsList");
return modelAndView;
}
返回字符串
如果controller方法返回JSP页面,可以简单将方法返回值类型定义为字符串,最终返回逻辑视图名称
//方法返回字符串,字符串就是逻辑视图名,Model作用就是将数据填充到request域,在页面展示
@RequestMapping(value="/editItems",method={RequestMethod.GET})
public String editItems(Model model) throws Exception{
// 调用Service查询商品信息
ItemsCustom itemsCustom = itemsService.findItemsById(1);
//将模型数据传到jsp
model.addAttribute("item", itemsCustom);
return "editItem";
}
返回void
// 方法返回void
@RequestMapping(value="/editItems",method={RequestMethod.GET})
public void editItems(HttpServletRequest request,HttpServletResponse response) throws Exception{
// 调用Service查询商品信息
ItemsCustom itemsCustom = itemsService.findItemsById(1);
request.setAttribute("item", itemsCustom);
// 注意如果使用request转向页面,这里指定页面的完整路径
request.getRequestDispatcher("/WEB-INF/jsp/editItem.jsp").forward(request, response);
}
使用此方法,容易输出json、xml格式的数据:
通过response指定响应结果,例如响应json数据如下:
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("json串");
redirect重定向
如果方法重定向到另一个url,方法返回值为 "redirect:url路径",url路径一般指的具体的路径或别的请求路径 不能是虚拟视图名。
使用redirect进行重定向,request数据无法共享,url的地址栏会发生变化。
forward转发
使用forward进行请求转发,request数据可以共享,url地址栏不会改变。
方法返回值为"forward:url路径"
参数绑定
参数绑定过程
默认支持的参数类型
处理器方法形参中添加如下类型的参数,处理器适配器会默认识别并进行赋值的。
HttpServletRequest
通过request对象获取请求信息
HttpServletResponse
通过response处理响应信息
HttpSession
通过Session对象得到Session中存放的对象
Model
通过model向页面传递数据,如下:
// 调用Service查询商品信息
ItemsCustom itemsCustom = itemsService.findItemsById(id);
//将模型数据传到jsp
model.addAttribute("item", itemsCustom);
页面通过${item.xxx}获取对象的属性值
@RequestParam
如果request请求的参数名和controller方法的形参参数名一致,适配器自动进行参数绑定。如果不一致可以通过@RequestParam指定request请求的参数名(value属性)绑定到哪个方法形参上。
对于必须要传入的参数,通过@RequestParam中的属性required设置为true,设置后如果不传入此参数则会报错。
对于有些参数如果不传入,还需要设置默认值,使用@RequestParam中属性defaultvalue设置默认值。
可以绑定简单类型
可以绑定整型、字符串、单精/双精度、日期、布尔型
可以绑定简单pojo类型
简单pojo类型只包括简单类型的属性。
绑定过程:request请求的参数名称和pojo的属性名一致,就可以绑定成功。
问题:
如果controller方法形参中有多个pojo且pojo中有重复的属性,使用简单pojo绑定无法有针对性的绑定。
比如:方法形参中有items和User,pojo同时存name属性,从http请求过程的name无法有针对性的绑定到items或user。
可以绑定包装的pojo
包装的pojo里包括的pojo
页面参数定义:
包装类型的属性也是itemsCustom
按照上边的规则进行包装类型的绑定。
自定义绑定使用属性编辑器
SpringMVC没有提供对日期类型的绑定,需要自定义日期类型的绑定。
使用WebDataBinder(了解)
在controller类中定义
//自定义属性编辑器
@InitBinder
public void initBinder(WebDataBinder binder) throws Exception {
// Date.class必须是与controler方法形参pojo属性一致的date类型,这里是java.util.Date
binder.registerCustomEditor(Date.class, new CustomDateEditor(
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), true));
}
使用这种方法是无法在多个controller共用
使用WebBindingInitializer(了解)
使用WebBindingInitializer让多个控制器共用属性编辑器
自定义WebBindingInitializer,注入到处理器适配器中。
如果想使多个controller共用属性编辑器,需要共同注册相同的属性编辑器,可以实现PropertyEditorRegistrar接口,并且注入到webBindingInitializer中。
编写CustomPropertyEditor
public class CustomPropertyEditor implements PropertyEditorRegistrar {
public void registerCustomEditors(PropertyEditorRegistry binder) {
binder.registerCustomEditor(Date.class,
new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), true));
}
}
在springmvc.xml中添加如下配置
编写自定义转换器 实现PropertyEditorRegistrar接口
注册自定义的属性编辑器。
注册webBinder(org.springframework.web.bind.support.ConfigurableWebBindingInitializer类型),并将已经注册的属性编辑器注入到propertyEditorRegistrars的list属性集合中。
最后将已注册的webBinder注入到注解适配器中。
自定义参数绑定使用转换器(重点)
实现Converter接口
定义日期类型转换器和字符串去除前后空格的转换器
配置转换器
配置方式:
自定义转换器实现Converter 接口 K:原始数据类型 V:转换后的数据类型 自定义日期转换器
/**
* 自定义日期转换器
* @author liuxun
*
*/
public class CustomDateConverter implements Converter {
@Override
public Date convert(String source) {
// 进行日期转换
try {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
自定义去空格转换器
/**
* 自定义去除字符串前后空格的转换器
* @author liuxun
*
*/
public class StringTrimConverter implements Converter{
@Override
public String convert(String source) {
//去掉字符串两边空格,如果去除后为空设置为null
if (source!=null) {
source = source.trim();
if (source.equals("")) {
return null;
}
}
return source;
}
}
配置如下
注册FormattingConversionServiceFactoryBean,并将自定义的转换器注入到converters数组属性中
在web.xml中加入
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
CharacterEncodingFilter
/*
以上可解决post乱码问题
get乱码
对于get请求中文参数出现乱码解决方法有两个
修改Tomcat配置文件添加编码与工程一致 如下:
另外一种方法对参数进行重新编码:
String userName=new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")
ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码
(具体源码在第二篇中综合展示)