说到SpringMVC,首先我们了解一下spring常用的jar包,以4.3版本为例。

Spring AOP:Spring的面向切面编程,提供AOP(面向切面编程)的实现
Spring Aspects:Spring提供的对AspectJ框架的整合
Spring Beans:Spring IOC的基础实现,包含访问配置文件、创建和管理bean等。
Spring Context:在基础IOC功能上提供扩展服务,此外还提供许多企业级服务的支持,有邮件服务、任务调度、JNDI定位,EJB集成、远程访问、缓存以及多种视图层框架的支持。
Spring Context Support:Spring context的扩展支持,用于MVC方面。
Spring Core:Spring的核心工具包
Spring expression:Spring表达式语言
Spring JDBC:对JDBC 的简单封装
Spring JMS:为简化jms api的使用而做的简单封装
Spring orm:整合第三方的orm实现,如hibernate,ibatis,jdo以及spring 的jpa实现
Spring tx:为JDBC、Hibernate、JDO、JPA等提供的一致的声明式和编程式事务管理。
Spring web:包含Web应用开发时,用到Spring框架时所需的核心类,包括自动载入WebApplicationContext特性的类、Struts与JSF集成类、文件上传的支持类、Filter类和大量工具辅助类。
Spring webmvc:包含SpringMVC框架相关的所有类。

SpringMvc的工作流程中离不开这几个对象:DispatcherServlet、HandlerMapping、HandlerAdapter、ViewResolver及自定义的controller等,这些对象完成的工作对于开发者来说都是不可见的,开发者并不需要关心这些对象是如何工作的,只需要在Handler(Controller)当中完成对请求的业务处理。

一.SpringMvc的工作流程:

这里借用一下别人的图,如图所示:

根据上图,Springmvc的工作流程可描述为:

      1. 用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获;
      2. DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;
      3. DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)方法)
       4.  提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
      HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
      数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
      数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
      数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中
      5.  Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;
      6.  根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;
      7. ViewResolver 结合Model和View,来渲染视图
      8. 将渲染结果返回给客户端。
 
其内部调用过程可用下图来说明:

 

Spring MVC提供了几种HandlerMapping实现: 
1. BeanNameUrlHandlerMapping(默认情况),他根据Controller Bean名称中指定的URL模式将请求映射到处理程序上。 
eg. <bean name="/welcome.htm" class="com.kevin.controller.WelcomeController">...</bean> 
当你访问http://******/welcome.htm这个URL时,DispatcherServlet通过BeanNameUrlHandlerMapping映射就找到了WelcomeController。 
2. ControllerClassNameHandlerMapping,它是按控制器类名称映射请求。 
3. SimpleUrlHandlerMapping,用定制的映射定义来映射请求。 我平时工作中基本上用的这种。

二. springmvc用到的注解

1、@Controller

在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,@Controller 标记一个类是Controller ,然后使用@RequestMapping 和@RequestParam 等一些注解用以定义URL 请求和Controller 方法之间的映射,这样的Controller 就能被外界访问到。此外Controller 不会直接依赖于HttpServletRequest 和HttpServletResponse 等HttpServlet 对象,它们可以通过Controller 的方法参数灵活的获取到。

在实际中有时会 用到@RestController,比@Controller多了一个@ResponseBody注解,controller中所有方法具有@ResponseBody的功能。

2、@RequestMapping

RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径,用于方法表示这个方法的URL访问地址。也可同时作用于类和方法上。

 1 @Controller
 2 @RequestMapping("/user")
 3 public class UserController {
 4 
 5     @RequestMapping("/user_list")
 6     public Object queryUserList(HttpServletRequest request, HttpServletResponse response) {
 7 .....
 8 .....
 9     }
10 }

页面访问需要用/user/user_list

RequestMapping注解有几个属性,在开发中也会用到。

1、 value, method;

value:     指定请求的实际地址;

method:  指定请求的method类型, GET、POST、PUT、DELETE等;

@RequestMapping (value= "testMethod" , method={RequestMethod. GET , RequestMethod. DELETE })
    public String testMethod() {
       return "method" ;
    }

限制客户端只能用get和delete方法。

2、consumes,produces

consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;

produces:    指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;

3、params,headers

params: 指定request中必须包含某些参数值是,才让该方法处理。

headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。

@RequestMapping (value= "test" , params={ "test1=value1" , "test2" , "!test3" })
    public String test() {
       System. out .println( "test Params..........." );
       return "test" ;
    }

该参数分别表示参数test1 的值必须等于value1 ,参数test2 必须存在,值可有可无,参数test3 必须不存在,只有当同时满足这三个参数条件时才会调用该方法。

3、@requestParam

常用来处理简单类型的绑定,它有required,value常用参数;,required 通过boolean设置是否是必须要传入的参数,默认为false,value 值表示接受的传入的参数类型。

4、@PathVariable

将参数绑定到URL上,一般用于GET模式参数较少的情况,Restful风格。

5、@RequestBody

用于读取Request请求的body部分数据,HttpMessageConverter将对象数据与 controller中方法的参数进行绑定。一般用于post方法,会要求数据格式(application/json, application/xml等),就是header 的Content-Type来指定。

7、@ResponseBody

用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区,一般用于返回json等数据。

8、@Resource和@Autowired

@Resource和@Autowired都是bean的注入,都可以写在字段和setter方法上。两者如果都写在字段上,那么就不需要再写setter方法。

不同的是@Autowired为Spring提供的注解,按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。

    @Autowired
    @Qualifier("userDao")
    private UserDao userDao; 

@Resource默认按照ByName自动注入,不是spring的注解,但是spring支持它。使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。

@Resource装配顺序:

①如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。

②如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。

③如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常。

④如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。

9、@Repository

用于注解repository层,查询数据库。

10、@SessionAttributes

用来绑定HttpSession中的attribute对象的值,便于在方法中的参数里使用。该注解有value、types两个属性,可以通过名字和类型指定要使用的attribute 对象。

@Controller
@RequestMapping ( "/test" )
@SessionAttributes (value={ "name" }, types={User. class })
public class MyController {
   
}

 

11、@ModelAttribute

该注解有两个用法,一个是用于方法上,一个是用于参数上;

用于方法上时:  通常用来在处理@RequestMapping之前,为请求绑定需要从后台查询的model;

用于参数上时: 用来通过名称对应,把相应名称的值绑定到注解的参数bean上;要绑定的值来源于

A) @SessionAttributes 启用的attribute 对象上;

B) @ModelAttribute 用于方法上时指定的model对象;

C) 上述两种情况都没有时,new一个需要绑定的bean对象,然后把request中按名称对应的方式把值绑定到bean中。

 1 @Controller
 2 @RequestMapping ( "/test" )
 3 public class MyController {
 4 
 5     @ModelAttribute ( "name" )
 6     public String getName() {
 7        System. out .println( "-------------name---------" );
 8        return "name" ;
 9     }
10     
11     @ModelAttribute ( "user" )
12     public User getUser(){
13        System. out .println( "---------getUser-------------" );
14        return new User(3, "user" );
15     }
16 
17     @RequestMapping ( "test" )
18     public void test( @ModelAttribute ( "name" ) String name, @ModelAttribute ( "user" ) User user){
19        
20     }
21 
22    
23 }

调用test()方法时会先调用getName(),getUser()。

posted on 2019-01-08 17:37  jameszheng  阅读(699)  评论(0编辑  收藏  举报