学习SpringMVC

来源:互联网 发布:个人注册域名有啥用 编辑:程序博客网 时间:2024/05/13 04:54

学习SpringMVC

 

学习SpringMVC(一)之helloworld

首先,来一个入门案例,带你进入helloworld!

1.创建WEB工程,导入JAR包


2.在WEB.XML文件中配置一个DispatcherServlet


3.编写一个Controller类

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <strong><span style="font-size:18px;">import org.springframework.stereotype.Controller;  
  2. import org.springframework.web.bind.annotation.RequestMapping;  
  3.   
  4. @Controller  
  5. public class HelloWorld {  
  6.       
  7.     @RequestMapping("/helloworld")  
  8.     public String hello(){  
  9.         System.out.println("hello cgf,welcome to springmvc again");  
  10.         return "hello";  
  11.     }  
  12.   
  13. }</span></strong>  
4.在springmvc.xml配置文件中,配置自动扫描的包和配置视图解析器

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <strong><span style="font-size:18px;"><?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xmlns:context="http://www.springframework.org/schema/context"  
  5.     xmlns:mvc="http://www.springframework.org/schema/mvc"  
  6.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
  7.         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd  
  8.         http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">  
  9. <!-- 配置自动扫描的包 -->  
  10. <context:component-scan base-package="com.cgf.springmvc.handlers"></context:component-scan>       
  11. <!-- 配置视图解析器 -->  
  12. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
  13. <property name="prefix" value="/WEB-INF/"></property>  
  14. <property name="suffix" value=".jsp"></property>  
  15. </bean>  
  16. </beans></span></strong>  
5.在WEB-INF/下创建一个hello.jsp

学习SpringMVC(二)之RequestMapping

1:@RequestMapping 除了修饰方法, 还可来修饰类


类定义处: 提供初步的请求映射信息。相对于 WEB 应用的根目录

方法处: 提供进一步的细分映射信息。 相对于类定义处的 URL。若类定义处未标注 @RequestMapping,则方法处标记的 URL相对于 WEB 应用的根目录

在前一讲中,是单单用来修饰方法,这一讲同时也用来修饰类,所以在index.jsp中加入了以下代码:


新写了一个controller

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;">package com.cgf.springmvc.handlers;  
  2.   
  3. import org.springframework.stereotype.Controller;  
  4. import org.springframework.web.bind.annotation.RequestMapping;  
  5.   
  6. <span style="color:#ff0000;">@RequestMapping("/springmvc")</span>  
  7. @Controller  
  8. public class MyRequestMapping {  
  9.     <span style="color:#ff0000;">@RequestMapping("/RequestMapping")</span>  
  10.     public String myRequestMapping(){  
  11.         System.out.println("myRequestMapping");  
  12.         return "hello";  
  13.     }  
  14.   
  15. }</span>  

2:RequestMapping 的value属性指定修饰的URL路径和method属性用来指定请求方式(GET,POST)

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;">package com.cgf.springmvc.handlers;  
  2.   
  3. import org.springframework.stereotype.Controller;  
  4. import org.springframework.web.bind.annotation.RequestMapping;  
  5.   
  6. <span style="color:#ff0000;">@RequestMapping("/springmvc")</span>  
  7. @Controller  
  8. public class MyRequestMapping {  
  9.     @RequestMapping(value="/RequestMapping",method="RequestMethod.POST")  
  10.     public String myRequestMapping(){  
  11.         System.out.println("myRequestMapping");  
  12.         return "hello";  
  13.     }  
  14.   
  15. }</span>  

3:RequestMapping的params属性和headers属性,用法简单,而且不太常用,这里就不会介绍了

4:@RequestMapping还支持ANT风格的URL映射

ANT风格支持3种通配符:

? ---匹配一个字符

*   ---匹配任意多个字符

** ---匹配多层路径

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;">package com.cgf.springmvc.handlers;  
  2.   
  3. import org.springframework.stereotype.Controller;  
  4. import org.springframework.web.bind.annotation.RequestMapping;  
  5.   
  6. <span style="color:#ff0000;">@RequestMapping("/springmvc")</span>  
  7. @Controller  
  8. public class MyRequestMapping {  
  9.     @RequestMapping(value="/RequestMapping/*/cgf")  
  10.     public String myRequestMapping(){  
  11.         System.out.println("myRequestMapping");  
  12.         return "hello";  
  13.     }  
  14.   
  15. }</span>  
<a href="springmvc/RequestMapping/cgf/cgf">test_Ant</a>

5:@PathVariable映射URL绑定的占位符,通过@PathVariable可以将URL中的占位符参数绑定到控制器处理方法的入参当中。如:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. @RequestMapping("/myPathVariable/{id}")  
  2.     public String myPathVariable(@PathVariable(value="id"int id){  
  3.         System.out.println("myPathVariable"+id);  
  4.         return "hello";  
  5.     }  
[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <a href="springmvc/myPathVariable/88888888">myPathVariable</a>  

6:HiddenHttpMethodFilter 浏览器的FORM表单只支持GET,POST请求,而DELETE,PUT方法并不支持,Spring3.0增加了一个过滤器,可以将POST转化为PUT或DELETE。

首先在WEB.XML文件中配置一个Filter

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <filter>  
  2.   <filter-name>HiddenHttpMethodFilter</filter-name>  
  3.   <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>  
  4.   </filter>  
  5.     
  6.   <filter-mapping>  
  7.   <filter-name>HiddenHttpMethodFilter</filter-name>  
  8.   <url-pattern>/*</url-pattern>  
  9.   </filter-mapping>  
  10.     

然后在index.jsp中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;"> <a href="springmvc/testRest/1">Get</a>  
  2.   <br>  
  3.    <form action="springmvc/testRest" method="post">  
  4.     <input type="submit" value="post">  
  5.   </form>  
  6.   <br>  
  7.    <form action="springmvc/testRest/1" method="post">  
  8.     <input type="hidden" name="_method" value="PUT">  
  9.     <input type="submit" value="put">  
  10.   </form>  
  11.   <br>  
  12.   <form action="springmvc/testRest/1" method="post">  
  13.     <input type="hidden" name="_method" value="DELETE">  
  14.     <input type="submit" value="delete">  
  15.   </form></span>  

最后在controller中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;"@RequestMapping(value="/testRest",method=RequestMethod.POST)  
  2.     public String myTestRest(){  
  3.         System.out.println("myTestRest POST");  
  4.         return "hello";  
  5.     }  
  6.       
  7.     @RequestMapping(value="/testRest/{id}",method=RequestMethod.PUT)  
  8.     public String myTestRestPut(@PathVariable(value="id"int id){  
  9.         System.out.println("myTestRest PUT"+id);  
  10.         return "hello";  
  11.     }  
  12.       
  13.     @RequestMapping(value="/testRest/{id}",method=RequestMethod.DELETE)  
  14.     public String myTestRestDelete(@PathVariable(value="id"int id){  
  15.         System.out.println("myTestRest Delete"+id);  
  16.         return "hello";  
  17.     }  
  18.       
  19.     @RequestMapping(value="/testRest/{id}",method=RequestMethod.GET)  
  20.     public String myTestRestGet(@PathVariable(value="id"int id){  
  21.         System.out.println("myTestRest Get"+id);  
  22.         return "hello";  
  23.     }</span>  

学习SpringMVC(三)之RequestParam

@RequestParam用来映射请求参数 

value ---参数名

required---参数是否必须,默认true

defaultValue---默认值

在controller中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;">@RequestMapping(value="springmvc")  
  2. @Controller  
  3. public class MyRequestParam {  
  4.       
  5.     @RequestMapping(value="/testRequestParam")  
  6.     public String testRequestParam(@RequestParam(value="username",required=false) String username,  
  7.             @RequestParam(value="id",required=false,defaultValue="0"int id){  
  8.         System.out.println("testRequestParam:"+username+" "+id);  
  9.         return "hello";  
  10.     }  
  11.   
  12. }</span>  
在index.jsp中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;"> <a href="springmvc/testRequestParam?username=cgf&&id=1413">testRequestParam</a></span> 

 

学习SpringMVC(四)之使用pojo作为参数

spring MVC会按请求参数名和POJO对象的属性名进行自动匹配,自动为该对象填充属性值。支持级联属性。

在controller中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;">import org.springframework.stereotype.Controller;  
  2. import org.springframework.web.bind.annotation.RequestMapping;  
  3. import com.cgf.springmvc.entities.User;  
  4. @RequestMapping(value="/springmvc")  
  5. @Controller  
  6. public class MyPojo {  
  7.     @RequestMapping(value="/testpojo")  
  8.     public String testPojo(User user){  
  9.         System.out.println("testPojo:"+user);  
  10.         return "hello";  
  11.     }  
  12.   
  13. }</span>  

在index.jsp中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;">  <form action="springmvc/testpojo" method="post">  
  2.     username:<input type="text" name="name" >  
  3.     password:<input type="password" name="password">  
  4.     province:<input type="text" name="address.province">  
  5.     city:<input type="text" name="address.city">  
  6.     <input type="submit" value="提交">  
  7.   </form></span>  


在POJO类中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;">public class User {  
  2.       
  3.     private String name;  
  4.     private String password;  
  5.     private Address address;  
  6.     public String getName() {  
  7.         return name;  
  8.     }  
  9.     public void setName(String name) {  
  10.         this.name = name;  
  11.     }  
  12.     public String getPassword() {  
  13.         return password;  
  14.     }  
  15.     public void setPassword(String password) {  
  16.         this.password = password;  
  17.     }  
  18.     public Address getAddress() {  
  19.         return address;  
  20.     }  
  21.     public void setAddress(Address address) {  
  22.         this.address = address;  
  23.     }  
  24.     @Override  
  25.     public String toString() {  
  26.         return "User [name=" + name + ", password=" + password + ", address="  
  27.                 + address + "]";  
  28.     }  
  29.       
  30.   
  31. }  
  32. </span>  

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;">public class Address {  
  2.       
  3.     private String city;  
  4.     private String province;  
  5.     public String getCity() {  
  6.         return city;  
  7.     }  
  8.     public void setCity(String city) {  
  9.         this.city = city;  
  10.     }  
  11.     public String getProvince() {  
  12.         return province;  
  13.     }  
  14.     public void setProvince(String province) {  
  15.         this.province = province;  
  16.     }  
  17.     @Override  
  18.     public String toString() {  
  19.         return "Address [city=" + city + ", province=" + province + "]";  
  20.     }  
  21.   
  22. }</span>  

学习SpringMVC(五)之使用Servlet原生API

可以使用Servlet原生API作为目标方法的入参,具体类型有以下几种:

1.HttpServletRequest

2.HttpServletResponse

3.HttpSession

4.Writer

5.Reader

6.OutputStream

7.InputStream

8.Java.security.Principal

在controller中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. @RequestMapping(value="/springmvc")  
  2. @Controller  
  3. public class MyServletAPI {  
  4.       
  5.     @RequestMapping(value="testServletAPI")  
  6.     public void testServletAPI(HttpServletRequest request,HttpServletResponse response,Writer out) throws IOException{  
  7.         System.out.println("testServletAPI"+request+response+out);  
  8.         out.write("springmvc testServletAPI");  
  9.         //return "hello";  
  10.           
  11.     }  
  12.   
  13. }  
在index.jsp中

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <a href="springmvc/testServletAPI">Test ServletAPI</a>  

 

学习SpringMVC(六)之ModelAndView

控制器的方法返回值如果是ModelAndView,则其包含视图信息,也包含模型数据信息。

添加模型数据:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. model.addObject(attributeName, attributeValue);  
[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. model.addAllObjects(modelMap)  

设置视图:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. void setView(View view)  
  2. void setView(String viewName)  

在Controller中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. @RequestMapping(value="/springmvc")  
  2. @Controller  
  3. public class MyModelAndView {     
  4.     @RequestMapping(value="/testModelAndView")  
  5.     public ModelAndView testModelAndView(){  
  6.         String viewName="success";  
  7.         //ModelAndView model=new ModelAndView(viewName);  
  8.         ModelAndView model=new ModelAndView();  
  9.         model.setViewName(viewName);  
  10.         model.addObject("time"new Date());  
  11.         return model;  
  12.           
  13.     }  
  14.   
  15. }  

在success.jsp中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. time:${requestScope.time }  
  2. <br>  
  3. time:${time}  

学习SpringMVC(七)之处理模型数据

1.将Map,Model做为方法入参,将其放到请求域(request)

在controller中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;">import java.util.Arrays;  
  2. import java.util.Map;  
  3. import org.springframework.stereotype.Controller;  
  4. import org.springframework.ui.Model;  
  5. import org.springframework.web.bind.annotation.RequestMapping;  
  6. import org.springframework.web.bind.annotation.SessionAttributes;  
  7. @RequestMapping(value="springmvc")  
  8. @Controller  
  9. public class MyMap {  
  10.       
  11.     public final String viewname="success";  
  12.       
  13.     @RequestMapping(value="testMap")  
  14.     public String testMap(Map<String,Object> map,Model model){  
  15.         map.put("names", Arrays.asList("CGF","WBJ","2016"));  
  16.         model.addAttribute("user""cgf");  
  17.         return viewname;  
  18.     }  
  19. }</span>  
在success.jsp中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;"> names:${requestScope.names }<br>  
  2.  name:${requestScope.user}<br></span>  

在index.jsp中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;"> <a href="springmvc/testMap">Test Map</a><br></span>  

2.将Map,Model做为方法入参,将其放到会话中(Session)

在Controller中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. @SessionAttributes(value={"username"},types={String.class})  
  2. @RequestMapping(value="/springmvc")  
  3. @Controller  
  4. public class MySessionAttributes {  
  5.     public final String viewname="success";  
  6.     @RequestMapping(value="/testSessionAttributes")  
  7.     public String testSessionAttributes(Map<String,Object> map){  
  8.         User user=new User("cgf""cgf-2016.5.16");  
  9.         map.put("myuser""myuser");  
  10.         map.put("username", user);  
  11.         return viewname;  
  12.     }  
  13.   
  14. }  
注意:@SessionAttributes 是能用来修饰类,不能用来修饰方法,它有两个属性(value,types),都是数组类型
在success.jsp中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. request user:${requestScope.username }<br>  
  2. session user:${sessionScope.username }<br>  
  3. request user:${requestScope.myuser }<br>  
  4. session user:${sessionScope.myuser }<br> 

学习SpringMVC(八)之ModelAttribute

首先,介绍下ModelAttribute的作用:

1.用@ModelAttribute修饰的方法,将再目标方法被调用前进行调用

2.可以解决这样一个问题:用户在提交表单时候,要求可以对用户名进行修改,但是密码不允许修改,这样在提交之后,在目标方法中的入参对象,将自动对用户名进行填充修改,但是这时候发现密码变为NULL,因为没有对密码传值,但是要求密码为原来用户的密码不变。

       2.1 可以通过查询数据库的信息,再密码传递过来

       2.2 也可以使用@ModelAttribute来解决这个问题

3.下面来看个案例

在index.jsp中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;"><form action="springmvc/testModelAttribute" method="post">  
  2.    <input type="hidden" name="id" value="1">  
  3.     username:<input type="text" name="name" value="CGF">  
  4.     <input type="submit" value="提交">  
  5.   </form></span>  

在controller中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;">import java.util.Map;  
  2. import org.springframework.stereotype.Controller;  
  3. import org.springframework.web.bind.annotation.ModelAttribute;  
  4. import org.springframework.web.bind.annotation.RequestMapping;  
  5. import org.springframework.web.bind.annotation.RequestParam;  
  6. import com.cgf.springmvc.entities.User;  
  7. import com.sun.org.glassfish.gmbal.ParameterNames;  
  8.   
  9. @RequestMapping(value="/springmvc")  
  10. @Controller  
  11. public class MyModelAttribute {   
  12.     public final String viewname="success";  
  13.       
  14.     @ModelAttribute  
  15.     public void updateUser(@RequestParam(value="id",required=false)Integer id,  
  16.             Map<String,Object> map){  
  17.         if(id!=null){  
  18.             User user=new User(1,"cgf2016""123456");  //模拟从数据库中获取数据  
  19.             System.out.println("模拟从数据库中获取数据:"+user);  
  20.             map.put("user", user);  
  21.         }  
  22.     }     
  23.     @RequestMapping(value="/testModelAttribute")  
  24.     public String testModelAttribute(User user1){  
  25.         System.out.println("testModelAttribute修改后:"+user1);  
  26.         return viewname;  
  27.     }  
  28.   
  29. }</span>  
这样就可以解决上述的问题

注意:map.put("user", user);   中的键user,应该为testModelAttribute(User user1)中的User的首字母小写
4.该案例的运行流程:

4.1 执行@ModelAttribute修饰的方法,把user,放到map当中

4.2 SpringMVC从map中取出User对象,然后把表单的请求参数附给User对象的属性值

4.3 SpringMVC将上述的对象传入目标方法当中


学习SpringMVC(九)之ModelAttribute源码分析

这里以前一章节的内容对ModelAttribute源码进行分析:

注:同学们可以去看下我的前一讲学习SpringMVC(八)之ModelAttribute

1.首先看下第一阶段的断点情况




还未调用ModelAttribute修饰方法前,map值为{}


调用它之后:map值为从数据库中


并将map键值对放到implicitModel中:


最后目标方法的参数数据如下:


2.如何解析目标方法的参数

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="color:#ff0000;">Object[] args = resolveHandlerArguments(handlerMethodToInvoke, handler, webRequest, implicitModel);</span>  
执行完这一语句,则name值改变,并且密码是从数据库中获取的
因为resolveHandlerArguments方法的代码很多,不好具体找到,所以我在USER类中的setName()上加了一个断点,便于分析



源码分析流程:

1.调用@ModelAttribute修饰的方法,实际上是把map中的键值对放入到implicitModel当中

2.解析请求处理器的目标参数,实际上该目标参数来自于WebDataBinder对象的target属性


 2.1 创建WebDataBinder对象时,需要先确定它的两个属性:target,objectName


下图中,name对应objectName,target对应bindObject

  2.1.1 确定objectName属性:

        若传入的attrName属性值为“ ”,则objectName为类名第一个字母小写,

        若有属性值,则objectName为@modelAttribute的value属性值

  2.1.2 确定target属性:                

        在implicitModel中查找attrName的键名,如果有,则取出返回。如果没有,则

        验证当前的controller是否用了@sessionAttribute来修饰,若使用了,则尝试从

        session中,获取attrName对应的属性值,若有,则取出,若无,则抛出异常;若

        当前controller没有用@sessionAttribute修饰,则通过反射机制创建一个,

        WebDataBinder对象。

返回WebDataBinder对象binder


在调用doBind(binder, webRequest, validate, validationHints, !assignBindingResult)之前,binder的

target属性为原来数据库的


在调用doBind(binder, webRequest, validate, validationHints, !assignBindingResult)之后,

binder的target属性为修改后的



0

学习SpringMVC(十)之确定目标方法POJO类型参数

SpringMVC 确定目标方法 POJO 类型入参的过程

1. 确定一个 key:
1). 若目标方法的 POJO 类型的参数木有使用 @ModelAttribute 作为修饰, 则 key 为 POJO 类名第一个字母的小写

2). 若使用了  @ModelAttribute 来修饰, 则key 为 @ModelAttribute 注解的 value 属性值. 

2. 在 implicitModel 中查找 key 对应的对象, 若存在, 则作为入参传入

1). 若在 @ModelAttribute 标记的方法中在 Map 中保存过, 且 key 和 1 确定的 key 一致, 则会获取到. 
3. 若 implicitModel 中不存在 key 对应的对象, 则检查当前的 Handler 是否使用 @SessionAttributes 注解修饰, 
若使用了该注解, 且 @SessionAttributes 注解的 value 属性值中包含了 key, 则会从 HttpSession 中来获取 key 所
对应的 value 值, 若存在则直接传入到目标方法的入参中. 若不存在则将抛出异常. 
4. 若 Handler 没有标识 @SessionAttributes 注解或 @SessionAttributes 注解的 value 值中不包含 key, 则
会通过反射来创建 POJO 类型的参数, 传入为目标方法的参数
5. SpringMVC 会把 key 和 POJO 类型的对象保存到 implicitModel 中, 进而会保存到 request 中. 


 

学习SpringMVC(十一)之视图和视图解析器

SpringMVC用于处理视图最重要的两个接口是ViewResolverViewViewResolver的主要作用是把一个逻辑上的视图名称解析为一个真正的视图,View接口的主要作用是用于处理视图,然后返回给客户端。

spring为我们提供了非常多的视图解析器,下面将列举一些视图解析器。

AbstractCachingViewResolver这是一个抽象类,这种视图解析器会把它曾经解析过的视图保存起来,然后每次要解析视图的时候先从缓存里面找,如果找到了对应的视图就直接返回,如果没有就创建一个新的视图对象,然后把它放到一个用于缓存的map中,接着再把新建的视图返回。使用这种视图缓存的方式可以把解析视图的性能问题降到最低。

UrlBasedViewResolver:它继承了AbstractCachingViewResolver,主要就是提供的一种拼接URL的方式来解析视图,它可以让我们通过prefix属性指定一个指定的前缀,通过suffix属性指定一个指定的后缀,然后把返回的逻辑视图名称加上指定的前缀和后缀就是指定的视图URL了。如prefix=/WEB-INF/jsps/,suffix=.jsp,返回的视图名称viewName=test/indx,则UrlBasedViewResolver解析出来的视图URL就是/WEB-INF/jsps/test/index.jsp。默认的prefix和suffix都是空串。

   URLBasedViewResolver支持返回的视图名称中包含redirect:前缀,这样就可以支持URL在客户端的跳转,如当返回的视图名称是”redirect:test.do”的时候,URLBasedViewResolver发现返回的视图名称包含”redirect:”前缀,于是把返回的视图名称前缀”redirect:”去掉,取后面的test.do组成一个RedirectView,RedirectView中将把请求返回的模型属性组合成查询参数的形式组合到redirect的URL后面,然后调用HttpServletResponse对象的sendRedirect方法进行重定向。

   同样URLBasedViewResolver还支持forword:前缀,对于视图名称中包含forword:前缀的视图名称将会被封装成一个InternalResourceView对象,然后在服务器端利用RequestDispatcher的forword方式跳转到指定的地址。    使用UrlBasedViewResolver的时候必须指定属性viewClass,表示解析成哪种视图,一般使用较多的就是InternalResourceView,利用它来展现jsp,但是当我们使用JSTL的时候我们必须使用JstlView。

   下面是一段UrlBasedViewResolver的定义,根据该定义,当返回的逻辑视图名称是test的时候,UrlBasedViewResolver将把逻辑视图名称加上定义好的前缀和后缀,即“/WEB-INF/test.jsp”,然后新建一个viewClass属性指定的视图类型予以返回,即返回一个url为“/WEB-INF/test.jsp”的InternalResourceView对象。

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <bean    
  2.    class="org.springframework.web.servlet.view.UrlBasedViewResolver">    
  3.    <property name="prefix" value="/WEB-INF/" />    
  4.    <property name="suffix" value=".jsp" />    
  5.    <property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView"/>    
  6. </bean>   

InternalResourceViewResolver它是URLBasedViewResolver的子类,所以URLBasedViewResolver支持的特性它都支持。在实际应用中InternalResourceViewResolver也是使用的最广泛的一个视图解析器。那么InternalResourceViewResolver有什么自己独有的特性呢?单从字面意思来看,我们可以把InternalResourceViewResolver解释为内部资源视图解析器,这就是InternalResourceViewResolver的一个特性。InternalResourceViewResolver会把返回的视图名称都解析为InternalResourceView对象,InternalResourceView会把Controller处理器方法返回的模型属性都存放到对应的request属性中,然后通过RequestDispatcher在服务器端把请求forword重定向到目标URL

      我们都知道存放在/WEB-INF/下面的内容是不能直接通过request请求的方式请求到的,为了安全性考虑,我们通常会把jsp文件放在WEB-INF目录下,而InternalResourceView在服务器端跳转的方式可以很好的解决这个问题。

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">    
  2.    <property name="prefix" value="/WEB-INF/"/>    
  3.    <property name="suffix" value=".jsp"></property>    
  4. </bean>    
总结:

        请求处理方法调用完成后,最终返回一个ModelAndView对象,对于那些返回String,View或ModelMap等类型的处理方法,SpirngMVC也会在内部将它们装配成一个ModelAndView对象,它包含了逻辑名和模型对象的视图。通过视图解析器(ViewResolver)得到真正的物理视图(View对象), 比如在InternalResourceViewResolver中定义了prefix=/WEB-INF/suffix=.jsp,然后请求的Controller处理器方法返回的视图名称为test,InternalResourceViewResolver会给它加上定义好的前缀和后缀,组成“/WEB-INF/test.jsp”的形式,然后把它当做一个InternalResourceView的url新建一个InternalResourceView对象返回,先把返回的模型属性都存放到对应的HttpServletRequest属性中,然后利用RequestDispatcher在服务器端把请求forword/WEB-INF/test.jsp


学习SpringMVC(十二)之mvc:view-controller标签


mvc:view-controller标签作用:

配置直接转发页面,可以直接相应转发的页面,而无须再经过Handler方法

例子:

在index.jsp中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;"><a href="success">success</a></span>  
点击该超链接,不会经过Handler方法,而直接转发到相应页面

在springmvc.xml中配置:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;"><mvc:view-controller path="/success" view-name="success"/></span>  


但如果就这样配置会导致其他经过Handler方法的请求,无法响应,此时要在Springmvc.xml中配置:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;"><mvc:annotation-driven/></span>  
mvc:annotation-driven 是一种简写形式,完全可以手动配置替代这种简写形式,简写形式可以让初学者快速应用默认配置方案。<mvc:annotation-driven /> 会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean,是spring MVC为@Controllers分发请求所必须的

学习SpringMVC(十三)之BeanNameViewResolver视图解析器

这里我将配置一个BeanNameViewResolver视图解析器,使用视图名称来解析视图

注意点:

在springmvc.xml文件中如果有多个视图解析器,可以进行优先级的设置,order 值越小优先级越高

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;"><!-- 配置一个BeanNameViewResolver视图解析器,使用视图名称来解析视图 -->  
  2. <bean class="org.springframework.web.servlet.view.BeanNameViewResolver">  
  3.     <property name="order" value="10" />  
  4. </bean>     
  5. <!-- 配置视图解析器 --><!--该视图解析器的order值为Integer.MAX_VALUE -->  
  6. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
  7. <property name="prefix" value="/WEB-INF/"></property>  
  8. <property name="suffix" value=".jsp"></property>  
  9. </bean></span>  
 1.写一个HelloView类,实现View接口

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:18px;">package com.cgf.springmvc.view;  
  2. import java.util.Date;  
  3. import java.util.Map;  
  4.   
  5. import javax.servlet.http.HttpServletRequest;  
  6. import javax.servlet.http.HttpServletResponse;  
  7.   
  8. import org.springframework.stereotype.Component;  
  9. import org.springframework.web.servlet.View;  
  10.   
  11. @Component  
  12. public class HelloView implements View{  
  13.   
  14.     public String getContentType() {  
  15.         // TODO Auto-generated method stub  
  16.         return "text/html";  
  17.     }  
  18.   
  19.     public void render(Map<String, ?> model, HttpServletRequest request,  
  20.             HttpServletResponse response) throws Exception {  
  21.         // TODO Auto-generated method stub  
  22.         response.getWriter().print("Welcome to View:"+new Date());  
  23.           
  24.     }  
  25.   
  26. }</span>  
2.再写一个目标方法
[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:18px;">package com.cgf.springmvc.handlers;  
  2.   
  3. import org.springframework.stereotype.Controller;  
  4. import org.springframework.web.bind.annotation.RequestMapping;  
  5.   
  6. @RequestMapping(value="/springmvc")  
  7. @Controller  
  8. public class MyView {  
  9.     @RequestMapping(value="/testMyView")  
  10.     public String testView(){  
  11.         System.out.println("testView");  
  12.         <strong><span style="color:#000099;">return "helloView";</span></strong>  
  13.     }  
  14. }</span>  
这里return的是视图名的第一个字母小写,springmvc会根据这个helloView名,去getBean,得到这个视图对象。

3.在index.jsp中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:18px;"><a href="springmvc/testMyView">Test MyView</a><br></span>  


学习SpringMVC(十四)之关于重定向

一般情况下,contrller方法返回的字符串的值会被当成逻辑视图名处理。

但是如果返回的字符串中带forward:或redirect:前缀时,SpringMVC会对他们进行特殊处理,将forward:和redirect:当成指示符,其后字符串作为URL来处理

例如:

forward:/index.jsp 将会完成一个到index.jsp页面的转发操作

redirect:/index.jsp 将会完成一个到index.jsp页面的重定向操作


在controller中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. package com.cgf.springmvc.handlers;  
  2. import org.springframework.stereotype.Controller;  
  3. import org.springframework.web.bind.annotation.RequestMapping;  
  4.   
  5. @RequestMapping(value="/springmvc")  
  6. @Controller  
  7. public class MyRedirect {  
  8.       
  9.     @RequestMapping(value="/testMyRedirect")  
  10.     public String testMyRedirect(){  
  11.         System.out.println("testMyRedirect");  
  12.         return "redirect:/index.jsp";  
  13.     }  
  14.   
  15. }  
在index.jsp页面中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <a href="springmvc/testMyRedirect">Test MyRedirect</a><br>  
0 0
原创粉丝点击