Spring MVC
Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面,是Spring框架提供的构建Web应用程序的全功能MVC模块。
需要的包:
spring所需要的包:
spring-aop-4.0.4.RELEASE.jar
spring-beans-4.0.4.RELEASE.jar
spring-context-4.0.4.RELEASE.jar
spring-core-4.0.4.RELEASE.jar
spring-expression-4.0.4.RELEASE.jar
commons-logging-1.1.1.jar(用来打印log)
spring WEB所需要的包:
spring-web-4.0.4.RELEASE.jar
Spring MVC所需要的包:
spring-webmvc-4.0.4.RELEASE.jar
核心DispatcherServlet配置:
springDispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
1
springDispatcherServlet
/
注意:
1、init-param用于配置spring mvc的配置文件的位置和名称
2、如果不配置init-param选项,则使用默认配置,默认的配置文件格式为/WEB-INF/[servlet-name]-servlet.xml
SpringMVC基本执行步骤
1、发起请求到前端控制器(DispatcherServlet)
2、DiapatcherServelt请求HandlerMapping根据相关配置文件查找Handler并返回
3、DispatcherServlet请求HandlerAdpter去执行handler并将执行结果ModelAndView返回
4、DispatcherServlet请求viewReloser去解析视图并将view返回
5、DispatcherServlet将模型填充到视图,进行视图渲染
6、DispatcherServlet将响应返回
SpringMVC使用的组件
(1)映射器(HandlerMapping)
(1)BeanNameUrlHandlerMapping(核心):将程序员定义的Action所对应的标签的name属性作为请求路径
(2)SimpleUrlHandlerMapping:将多个请求路径都交由<bean>标签为id的Action,即多个路径对应同一个Action
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/delete.action">userActionID</prop>
<prop key="/update.action">userActionID</prop>
</props>
</property>
</bean>
(3)RequestMappingHandlerMapping:注解映射器,3.1+使用
(2)适配器(HandlerAdapter)
(1)SimpleControllerHandlerAdapter:要求实现的Handler实现Controller接口
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
(2)HttpRequestHandlerAdapter:要求实现的Handler实现HttpRequestHandler接口
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter" />
(3)RequestMappingHandlerAdaoter:注解适配器,3.1+使用
<mvc:annotation-driven/>这个驱动可以代表RequestMappingHandlerMapping和RequestMappingHandlerAdaoter
(3)视图解析器(框架,默认)
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
对应自定义Action中的ModelAndView对象中的setViewName属性,
可以封装真实视图路径名,也可以封装视图路径的逻辑名,逻辑名需要配置prefix和suffix
(4)控制器
<bean name="/index.action" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
<property name="viewName" value="/index.jsp"/>
</bean>
ParameterizableViewController:将制定的url访问不经过Action,直接转发至指定视图
Action的创建
(1) 实现Controller接口,重写handleRequest方法,
public class HelloAction implements Controller{
public ModelAndView handleRequest(HttpServletRequest requqest,HttpServletResponse response) throws Exception {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject(“mess”,“mess”);
modelAndView.setViewName("/success.jsp");
return modelAndView;
}
}
(2) 继承AbstractCommandController类,重写handle方法
public class AdminAction extends AbstractCommandController{
public AdminAction(){
this.setCommandClass(Admin.class);
}
protected ModelAndView handle(HttpServletRequest request,HttpServletResponse response, Object obj, BindException bindException)throws Exception {
ModelAndView modelAndView = new ModelAndView();
Admin admin = (Admin) obj;
modelAndView.setViewName("/success.jsp");
return modelAndView;
}
}
日期转换器
对于日期类型不能自动转换,需要使用类型转换器:
局部日期转换器:
重写initBinder方法,此方法来自WebBindingInitializer接口
@InitBinder
public void initBinder(WebDataBinder binder, WebRequest request) {
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat(“yyyy-MM-dd HH:ss:mm”), true));
}
全局日期转换器:
在spring的xml文件进行配置:
定义日期转换类
public class DateHandler implements WebBindingInitializer {
public void initBinder(WebDataBinder binder, WebRequest request) {
binder.registerCustomEditor(Date.class,
new CustomDateEditor(new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”), true));
}
}
使用过滤器处理中文乱码
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
CharacterEncodingFilter
/*
注解
Spring2.5引入注解式处理器支持,并且提供了一组强大的注解:
需要通过处理器映射DefaultAnnotationHandlerMapping和处理器适配器AnnotationMethodHandlerAdapter来开启支持@Controller和@RequestMapping注解的处理器。
@Controller:用于标识是处理器类;
@RequestMapping:请求到处理器功能方法的映射规则(在此处可以定义访问路径和GET、POST限制)
@RequestParam:请求参数到处理器功能处理方法的方法参数上的绑定;
@ModelAttribute:请求参数到命令对象的绑定;
@SessionAttributes:用于声明session级别存储的属性,放置在处理器类上,通常列出模型属性(如@ModelAttribute)对应的名称,则这些属性会透明的保存到session中;
@InitBinder:自定义数据绑定注册支持,用于将请求参数转换到命令对象属性的对应类型;
在业务方法中参数的收集
(1)使用普通变量收集参数
public String add(int id,String name,Double sal) throws Exception{}
(2)使用Request,Response等传统web参数
public void add(HttpServletRequest request,HttpServletResponse response) throws Exception{}
(3)使用模型变量收集参数(Model可将信息封装传送到页面)
public String add(int id, Model model) throws Exception {
model.addAttribute(“id”, id);
return “/register.jsp”;
}
(4)使用实体模型收集参数
public String add(User user,Model model) throws Exception {
model.addAttribute(“user”,user);
return “/register.jsp”;
}
(5) 使用模型的包装模型收集参数
可以在业务控制方法中书写0个或多个模型来收集客户端的参数
1)如果多个模型中有相同的属性时,可以用user.name或admin.name来收集客户端参数
2)用一个新的模型将User和Admin再封装一次
public String add(Bean bean,Model model) throws Exception {
System.out.println(bean.getUser());
System.out.println(bean.getAdmin());
model.addAttribute(“bean”,bean);
return “/register.jsp”;
}
(6)使用数组收集参数
public String deleteMethod(int[] ids,Model model) throws Exception{
for(int id : ids){
System.out.print(id+" “);
}
return “/success.jsp”;
}
(7)使用List收集参数
在Bean中维护一个List:private List userList = new ArrayList();
public String addAll(Bean bean,Model model) throws Exception{
for(User user : bean.getUserList()){
System.out.println(user.getName()+”:"+user.getGender());
}
model.addAttribute(“message”,“批量增加用户成功”);
return “/success.jsp”;
}
结果的转发和重定向
public String delete(int id) throws Exception{
return “forward:/user/find.action”;//转发到find()
return “redirect:/user/find.action”;//重定向到find()
}
注意:在转发情况下,共享request域对象,会将参数从第一个业务控制方法传入第二个业务控制方法,重定向则不行
为web层返回JSON数据
(1)使用@ResponseBody注解方法返回值
public class UserAction {
public @ResponseBody User add(User user) throws Exception{
return user;
}
}
(2)在配置文件中添加json的适配器
SpringMVC与Struts2的区别:
1、Struts2是类级别的拦截, 一个类对应一个request上下文,SpringMVC是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应,所以说从架构本身上SpringMVC就容易实现restful url,而struts2的架构实现起来要费劲,因为Struts2中Action的一个方法可以对应一个url,而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了。
2、SpringMVC的方法之间基本上独立的,独享request response数据,请求数据通过参数获取,处理结果通过ModelMap交回给框架,方法之间不共享变量,而Struts2搞的就比较乱,虽然方法之间也是独立的,但其所有Action变量是共享的,这不会影响程序运行,却给我们编码 读程序时带来麻烦,每次来了请求就创建一个Action,一个Action对象对应一个request上下文。
3、由于Struts2需要针对每个request进行封装,把request,session等servlet生命周期的变量封装成一个一个Map,供给每个Action使用,并保证线程安全,所以在原则上,是比较耗费内存的。
4、拦截器实现机制上,Struts2有以自己的interceptor机制,SpringMVC用的是独立的AOP方式,这样导致Struts2的配置文件量还是比SpringMVC大。
5、SpringMVC的入口是servlet,而Struts2是filter(这里要指出,filter和servlet是不同的。以前认为filter是servlet的一种特殊),这就导致了二者的机制不同,这里就牵涉到servlet和filter的区别了。
6、SpringMVC集成了Ajax,使用非常方便,只需一个注解@ResponseBody就可以实现,然后直接返回响应文本即可,而Struts2拦截器集成了Ajax,在Action中处理时一般必须安装插件或者自己写代码集成进去,使用起来也相对不方便。
7、SpringMVC验证支持JSR303,处理起来相对更加灵活方便,而Struts2验证比较繁琐,感觉太烦乱。
8、spring MVC和Spring是无缝的。从这个项目的管理和安全上也比Struts2高(当然Struts2也可以通过不同的目录结构和相关配置做到SpringMVC一样的效果,但是需要xml配置的地方不少)。
9、设计思想上,Struts2更加符合OOP的编程思想, SpringMVC就比较谨慎,在servlet上扩展。
10、SpringMVC开发效率和性能高于Struts2。
11、SpringMVC可以认为已经100%零配置。