学习SpringMVC(一-1-2-25)

来源:互联网 发布:矩阵力学的主要创立者 编辑:程序博客网 时间:2024/05/21 19:34

学习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属性为修改后的


学习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>  

学习SpringMVC(十五)之CRUD操作


使用SpringMVC完成相应的CRUD操作,静态数据来模仿从数据库中取数据

下面从创建的类说起,一共定义了5个类,分类是DepartmentDao,EmployeeDao,Department,Employee,EmployeeHandler

代码如下:

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. package com.cgf.springmvc.crud.dao;  
  2. import java.util.Collection;  
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5.   
  6. import org.springframework.beans.factory.annotation.Autowired;  
  7. import org.springframework.stereotype.Repository;  
  8.   
  9. import com.cgf.springmvc.crud.entities.Department;  
  10. import com.cgf.springmvc.crud.entities.Employee;  
  11.   
  12. @Repository  
  13. public class EmployeeDao {  
  14.   
  15.     private static Map<Integer, Employee> employees = null;  
  16.       
  17.     @Autowired  
  18.     private DepartmentDao departmentDao;  
  19.       
  20.     static{  
  21.         employees = new HashMap<Integer, Employee>();  
  22.   
  23.         employees.put(1001, new Employee(1001, "E-AA", "aa@163.com", 1, new Department(101, "D-AA")));  
  24.         employees.put(1002, new Employee(1002, "E-BB", "bb@163.com", 1, new Department(102, "D-BB")));  
  25.         employees.put(1003, new Employee(1003, "E-CC", "cc@163.com", 0, new Department(103, "D-CC")));  
  26.         employees.put(1004, new Employee(1004, "E-DD", "dd@163.com", 0, new Department(104, "D-DD")));  
  27.         employees.put(1005, new Employee(1005, "E-EE", "ee@163.com", 1, new Department(105, "D-EE")));  
  28.     }  
  29.       
  30.     private static Integer initId = 1006;  
  31.       
  32.     public void save(Employee employee){  
  33.         if(employee.getId() == null){  
  34.             employee.setId(initId++);  
  35.         }  
  36.           
  37.         employee.setDepartment(departmentDao.getDepartment(employee.getDepartment().getId()));  
  38.         employees.put(employee.getId(), employee);  
  39.     }  
  40.       
  41.     public Collection<Employee> getAll(){  
  42.         return employees.values();  
  43.     }  
  44.       
  45.     public Employee get(Integer id){  
  46.         return employees.get(id);  
  47.     }  
  48.       
  49.     public void delete(Integer id){  
  50.         employees.remove(id);  
  51.     }  
  52. }  
[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. package com.cgf.springmvc.crud.dao;  
  2. import java.util.Collection;  
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5.   
  6. import org.springframework.stereotype.Repository;  
  7.   
  8. import com.cgf.springmvc.crud.entities.Department;  
  9.   
  10. @Repository  
  11. public class DepartmentDao {  
  12.   
  13.     private static Map<Integer, Department> departments = null;  
  14.       
  15.     static{  
  16.         departments = new HashMap<Integer, Department>();  
  17.           
  18.         departments.put(101, new Department(101, "D-AA"));  
  19.         departments.put(102, new Department(102, "D-BB"));  
  20.         departments.put(103, new Department(103, "D-CC"));  
  21.         departments.put(104, new Department(104, "D-DD"));  
  22.         departments.put(105, new Department(105, "D-EE"));  
  23.     }  
  24.       
  25.     public Collection<Department> getDepartments(){  
  26.         return departments.values();  
  27.     }  
  28.       
  29.     public Department getDepartment(Integer id){  
  30.         return departments.get(id);  
  31.     }  
  32.       
  33. }  

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. package com.cgf.springmvc.crud.entities;  
  2.   
  3. public class Department {  
  4.   
  5.     private Integer id;  
  6.     private String departmentName;  
  7.   
  8.     public Department() {  
  9.         // TODO Auto-generated constructor stub  
  10.     }  
  11.       
  12.     public Department(int i, String string) {  
  13.         this.id = i;  
  14.         this.departmentName = string;  
  15.     }  
  16.   
  17.     public Integer getId() {  
  18.         return id;  
  19.     }  
  20.   
  21.     public void setId(Integer id) {  
  22.         this.id = id;  
  23.     }  
  24.   
  25.     public String getDepartmentName() {  
  26.         return departmentName;  
  27.     }  
  28.   
  29.     public void setDepartmentName(String departmentName) {  
  30.         this.departmentName = departmentName;  
  31.     }  
  32.   
  33.     @Override  
  34.     public String toString() {  
  35.         return "Department [id=" + id + "departmentName=" + departmentName  
  36.                 + "]";  
  37.     }  
  38.       
  39. }  

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. package com.cgf.springmvc.crud.entities;  
  2.   
  3. import java.util.Date;  
  4.   
  5. import javax.validation.constraints.NotNull;  
  6.   
  7. import org.hibernate.validator.constraints.Email;  
  8. import org.hibernate.validator.constraints.NotEmpty;  
  9. import org.springframework.format.annotation.DateTimeFormat;  
  10. import org.springframework.format.annotation.NumberFormat;  
  11.   
  12. public class Employee {  
  13.   
  14.     private Integer id;  
  15.       
  16.     @NotNull  
  17.     private String lastName;  
  18.   
  19.     @Email  
  20.     private String email;  
  21.     //1 male, 0 female  
  22.     private Integer gender;  
  23.       
  24.     private Department department;  
  25.       
  26.       
  27.     @DateTimeFormat(pattern="yyyy-MM-dd")  
  28.     private Date birth;  
  29.       
  30.     @NumberFormat(pattern="#,###,###.#")  
  31.     private Float salary;  
  32.   
  33.     public Integer getId() {  
  34.         return id;  
  35.     }  
  36.   
  37.     public void setId(Integer id) {  
  38.         this.id = id;  
  39.     }  
  40.   
  41.     public String getLastName() {  
  42.         return lastName;  
  43.     }  
  44.   
  45.     public void setLastName(String lastName) {  
  46.         this.lastName = lastName;  
  47.     }  
  48.   
  49.     public String getEmail() {  
  50.         return email;  
  51.     }  
  52.   
  53.     public void setEmail(String email) {  
  54.         this.email = email;  
  55.     }  
  56.   
  57.     public Integer getGender() {  
  58.         return gender;  
  59.     }  
  60.   
  61.     public void setGender(Integer gender) {  
  62.         this.gender = gender;  
  63.     }  
  64.   
  65.     public Department getDepartment() {  
  66.         return department;  
  67.     }  
  68.   
  69.     public void setDepartment(Department department) {  
  70.         this.department = department;  
  71.     }  
  72.   
  73.     public Date getBirth() {  
  74.         return birth;  
  75.     }  
  76.   
  77.     public void setBirth(Date birth) {  
  78.         this.birth = birth;  
  79.     }  
  80.   
  81.     public Float getSalary() {  
  82.         return salary;  
  83.     }  
  84.   
  85.     public void setSalary(Float salary) {  
  86.         this.salary = salary;  
  87.     }  
  88.   
  89.     @Override  
  90.     public String toString() {  
  91.         return "Employee [id=" + id + "lastName=" + lastName + "email="  
  92.                 + email + ", gender=" + gender + "department=" + department  
  93.                 + ", birth=" + birth + "salary=" + salary + "]";  
  94.     }  
  95.   
  96.     public Employee(Integer id, String lastName, String email, Integer gender,  
  97.             Department department) {  
  98.         super();  
  99.         this.id = id;  
  100.         this.lastName = lastName;  
  101.         this.email = email;  
  102.         this.gender = gender;  
  103.         this.department = department;  
  104.     }  
  105.   
  106.     public Employee() {  
  107.         // TODO Auto-generated constructor stub  
  108.     }  
  109. }  
[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. package com.cgf.springmvc.crud.handlers;  
  2.   
  3. import java.util.Map;  
  4.   
  5. import org.springframework.beans.factory.annotation.Autowired;  
  6. import org.springframework.stereotype.Controller;  
  7. import org.springframework.web.bind.annotation.ModelAttribute;  
  8. import org.springframework.web.bind.annotation.PathVariable;  
  9. import org.springframework.web.bind.annotation.RequestMapping;  
  10. import org.springframework.web.bind.annotation.RequestMethod;  
  11. import org.springframework.web.bind.annotation.RequestParam;  
  12.   
  13. import com.cgf.springmvc.crud.dao.DepartmentDao;  
  14. import com.cgf.springmvc.crud.dao.EmployeeDao;  
  15. import com.cgf.springmvc.crud.entities.Employee;  
  16.   
  17. @RequestMapping(value="/springmvc")  
  18. @Controller  
  19. public class EmployeeHandler {  
  20.       
  21.     @Autowired  
  22.     private EmployeeDao employeeDao;  
  23.       
  24.     @Autowired  
  25.     private DepartmentDao departmentDao;  
  26.       
  27.     @RequestMapping(value="/list")  
  28.     public String emps(Map<String,Object> map){  
  29.         map.put("emplists", employeeDao.getAll());  
  30.         return "list";  
  31.     }  
  32.       
  33.     @RequestMapping(value="/addUi",method=RequestMethod.GET)  
  34.     public String empsAddUI(Map<String,Object> map){  
  35.         map.put("department", departmentDao.getDepartments());  
  36.         map.put("employee", new Employee());  
  37.         return "input";  
  38.     }  
  39.       
  40.     @RequestMapping(value="/add",method=RequestMethod.POST)  
  41.     public String empsAdd(Employee employee,Map<String,Object> map){  
  42.         employeeDao.save(employee);  
  43.         //map.put("emplists", employeeDao.getAll());  
  44.         return "redirect:list";  
  45.     }  
  46.       
  47.     @RequestMapping(value="/delete/{id}",method=RequestMethod.DELETE)  
  48.     public String empsDelete(@PathVariable("id")Integer id,Map<String,Object> map){  
  49.         employeeDao.delete(id);  
  50.         map.put("emplists", employeeDao.getAll());  
  51.         return "list";  
  52.     }  
  53.       
  54.     @RequestMapping(value="/EditUi/{id}",method=RequestMethod.GET)  
  55.     public String empsEditUI(@PathVariable("id")Integer id,Map<String,Object> map){  
  56.         map.put("department", departmentDao.getDepartments());  
  57.         map.put("employee", employeeDao.get(id));  
  58.         return "input";  
  59.     }  
  60.       
  61.     @ModelAttribute  
  62.     public void emps(@RequestParam(value="id",required=false)Integer id,Map<String,Object> map){  
  63.         if(id!=null){  
  64.             map.put("employee", employeeDao.get(id));  
  65.         }  
  66.           
  67.     }  
  68.       
  69.     @RequestMapping(value="/add",method=RequestMethod.PUT)  
  70.     public String empsEdit(Employee employee,Map<String,Object> map){  
  71.         employeeDao.save(employee);  
  72.         map.put("emplists", employeeDao.getAll());  
  73.         return "list";  
  74.     }  
  75.   
  76.   
  77. }  
在index.jsp中:首页用来显示所有的员工,是个GET请求

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <h2>SpringMVC CRUD</h2>  
  2.    <a href="springmvc/list">显示所有员工信息</a>  
在input.jsp中;该页面有两个用处,一个是对添加员工进行操作(post请求),另一个用来对员工信息的修改(put请求)

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <form:form action="springmvc/add" method="POST" modelAttribute="employee">  
  2.     <c:if test="${employee.id==null }">  
  3.     LastName:<form:input path="lastName"/> <br>  
  4.     </c:if>  
  5.     <c:if test="${employee.id!=null }">  
  6.         <form:hidden path="id"/>  
  7.         <input type="hidden" name="_method" value="PUT">  
  8.     </c:if>  
  9.     Email:<form:input path="email"/>  
  10.     <form:errors path="email"></form:errors><br>  
  11.     <%  
  12.         Map<String,String> genders=new HashMap();  
  13.         genders.put("1", "Male");  
  14.         genders.put("0","Female");  
  15.         request.setAttribute("genders", genders);  
  16.      %>  
  17.     Gender:<form:radiobuttons path="gender" items="${genders }"/><br>  
  18.     Department:<form:select path="department.id"   
  19.         items="${department}" itemLabel="departmentName" itemValue="id"></form:select>  
  20.     <input type="submit" value="Submit" />  
  21.    </form:form>  
在list.jsp中:显示所有员工信息,在DELETE操作中,将GET请求,通过JQUERY完成转化为DELETE请求

[html] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;"><span style="font-size:18px;"><%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>  
  2. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>  
  3. <%  
  4. String path = request.getContextPath();  
  5. String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  6. %>  
  7.   
  8. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  9. <html>  
  10.   <head>  
  11.     <base href="<%=basePath%>">  
  12.       
  13.     <title>My JSP 'list.jsp' starting page</title>  
  14.       
  15.     <meta http-equiv="pragma" content="no-cache">  
  16.     <meta http-equiv="cache-control" content="no-cache">  
  17.     <meta http-equiv="expires" content="0">      
  18.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  19.     <meta http-equiv="description" content="This is my page">  
  20.     <!-- 
  21.     <link rel="stylesheet" type="text/css" href="styles.css"> 
  22.     -->  
  23.     <script type="text/javascript" src="scripts/jquery-1.9.1.min.js"></script>  
  24.     <script type="text/javascript">  
  25.         $(function(){  
  26.             $(".delete").click(function(){  
  27.                 var href=$(this).attr("href");  
  28.                 $("form").attr("action",href).submit();  
  29.                 return false;  
  30.             });  
  31.         })    
  32.   
  33.     </script>  
  34.   </head>  
  35.     
  36.   <body>  
  37.     
  38.   <form action="" method="post">  
  39.   <input type="hidden" name="_method" value="DELETE">  
  40.   </form>  
  41.     
  42.    <c:if test="${empty requestScope.emplists }">  
  43.             没有任何员工信息  
  44.     </c:if>  
  45.       
  46.     <c:if test="${!empty requestScope.emplists }">  
  47.             <table border="1">  
  48.                 <tr>  
  49.                     <th>ID</th>  
  50.                     <th>LastName</th>  
  51.                     <th>Email</th>  
  52.                     <th>Gender</th>  
  53.                     <th>Department</th>  
  54.                     <th>Edit</th>  
  55.                     <th>Delete</th>  
  56.                 </tr>  
  57.                   
  58.                 <c:forEach items="${requestScope.emplists}" var="emps">  
  59.                     <tr>  
  60.                         <td>${emps.id }</td>  
  61.                         <td>${emps.lastName}</td>  
  62.                         <td>${emps.email }</td>  
  63.                         <td>${emps.gender==0 ? 'Female':'male'}</td>  
  64.                         <td>${emps.department.departmentName }</td>  
  65.                         <td><a href="springmvc/EditUi/${emps.id}">Edit</a></td>  
  66.                         <td><a class="delete" href="springmvc/delete/${emps.id}">Delete</a></td>  
  67.                     </tr>  
  68.                 </c:forEach>  
  69.             </table>  
  70.     </c:if>  
  71.     <a href="springmvc/addUi">添加员工信息</a>  
  72.   </body>  
  73. </html></span>  
  74. </span>  
注意:

对静态资源的处理,需要在spring.xml文件中配置<mvc:default-servlet-handler/>default-servlet-handler将在 SpringMVC 上下文中定义一个 DefaultServletHttpRequestHandler,它会对进入DispatcherServlet的请求进行筛查, 如果发现是没有经过映射的请求, 就将该请求交由WEB应用服务器默认的Servlet 处理. 如果不是静态资源的请求,才由 DispatcherServlet 继续处理

学习SpringMVC(十六)之数据绑定流程

1.SpringMVC主框架将ServletRequest对象及目标方法的入参实例传递给WebDataBinderFactory实例,以创建DataBinder实例对象


2.DataBinder调用装配在SpringMVC上下文中的ConversionService组件进行数据类型转换、数据格式化工作。将Servlet中的请求信息填充到入参对象中

3.调用Validator组件对已经绑定了请求消息的入参对象进行数据合法性校验,并最终生成数据绑定结果。


4.SpringMVC抽取BindingResult中的入参对象和校验错误对象,将它们赋给处理方法的响应入参。

我在38行打了一个断点,来看数据绑定流程





学习SpringMVC(十七)之自定义类型转换器


本节的主要内容就是将表单提交的字符串转化为对象

在index.jsp中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:18px;"><h2>SpringMVC 自定义转换器</h2>  
  2.   <form action="springmvc/testConversion">  
  3.   Employee:<input type="text" name="employee">  
  4.   <input type="submit" value="提交">  
  5.   </form></span>  
在Controller中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;">package com.cgf.springmvc.handlers;  
  2. import java.util.Map;  
  3. import org.springframework.beans.factory.annotation.Autowired;  
  4. import org.springframework.stereotype.Controller;  
  5. import org.springframework.web.bind.annotation.RequestMapping;  
  6. import org.springframework.web.bind.annotation.RequestParam;  
  7. import com.cgf.springmvc.crud.dao.EmployeeDao;  
  8. import com.cgf.springmvc.crud.entities.Employee;  
  9.   
  10. @RequestMapping(value="/springmvc")  
  11. @Controller  
  12. public class MyConversion {   
  13.     @Autowired  
  14.     private EmployeeDao employeeDao;  
  15.       
  16.     @RequestMapping(value="/testConversion")  
  17.     public String testConversion(@RequestParam(value="employee")Employee employee,  
  18.             Map<String,Object> map){  
  19.         employeeDao.save(employee);  
  20.         //map.put("emplists", employeeDao.getAll());  
  21.         return "redirect:list";  
  22.     }  
  23.   
  24. }</span>  
之后要自定义一个类型转换器,该类要实现Converter接口

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. package com.cgf.springmvc.conversion;  
  2. import org.springframework.core.convert.converter.Converter;  
  3. import org.springframework.stereotype.Component;  
  4. import com.cgf.springmvc.crud.entities.Department;  
  5. import com.cgf.springmvc.crud.entities.Employee;  
  6.   
  7. @Component  
  8. public class MyConversionService implements Converter<String,Employee>{  
  9.   
  10.     public Employee convert(String source) {  
  11.         // TODO Auto-generated method stub  
  12.         //cgf-cgf@sina.com-0-105  
  13.         if(source!=null){  
  14.             String []args=source.split("-");  
  15.             if(args!=null&&args.length==4){  
  16.             String lastName=args[0];  
  17.             String email=args[1];  
  18.             int gender=Integer.parseInt(args[2]);  
  19.             Department department=new Department();  
  20.             department.setId(Integer.parseInt(args[3]));  
  21.             Employee e=new Employee(null, lastName, email, gender, department);  
  22.             System.out.println(source+"--conversion--"+e);  
  23.             return e;  
  24.         }  
  25.     }  
  26.         return null;  
  27.   }  
  28. }  
最后要在springmvc.xml中配置一个ConversionServiceFactoryBean

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <bean name="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">  
  2. <property name="converters">  
  3. <set>  
  4.     <ref bean="myConversionService"></ref>  
  5. </set>  
  6. </property>  
[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>  

学习SpringMVC(十八)之JSR303数据校验

JSR303是Java为Bean数据合法性校验提供的标准框架

hibernate Validator是JSR 303的一个参考实现,除支持所有标准的校验注解外,它

还支持以下的扩展注解

@Email @Length @NotEmpty @Range

校验步骤:

①.使用 JSR 303 验证标准

②.加入 hibernate validator 验证框架的 jar 包

③.在 SpringMVC 配置文件中添加 <mvc:annotation-driven />,它会默认装配好一个

LocalValidatorFactoryBean,通过在处理方法的入参上标注@Valid注解,就可以未完成数据绑定后执行数据校验的工作

④.需要在 bean 的属性上添加对应的注解
⑤.在目标方法 bean 类型的前面添加 @Valid 注解
2).验证出错转向到哪一个页面 ?

注意: 需校验的 Bean 对象和其绑定结果对象或错误对象时成对出现的,它们之间不允许声明其他的入参

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="color:#009900;">@RequestMapping(value="/add",method=RequestMethod.POST)  
  2.     public String empsAdd(</span><span style="background-color: rgb(255, 255, 255);"><span style="color:#ff0000;">@Valid Employee employee,Errors result</span></span><span style="color:#ff0000;">,Map<String,Object> map</span><span style="color:#009900;">){  
  3.         //map.put("emplists", employeeDao.getAll());  
  4.         if(result.getErrorCount()>0){  
  5.             System.out.println("出错啦");  
  6.             for(FieldError error:result.getFieldErrors()){  
  7.                 System.out.println(error.getField()+error.getDefaultMessage());  
  8.             }  
  9.             map.put("department", departmentDao.getDepartments());  
  10.             return "input";  
  11.         }  
  12.         employeeDao.save(employee);  
  13.         return "redirect:list";  
  14.     }</span>  

学习SpringMVC(十九)之显示错误消息和国际化

一.在页面显示错误消息:如要显示email的错误或显示全部的错误

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:24px;"><form:errors path="email"></form:errors></span>  
[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:24px;"><form:errors path="*"></form:errors>  
  2. </span>  
二.错误消息的国际化

1.配置国际化资源文件i18n.properties


2.在springmvc.xml中配置ResourceBundleMessageSource

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <!-- 配置国际资源化文件 -->  
  2. <bean name="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">  
  3.         <property name="basename" value="i18n"></property>  
  4. </bean>  

 

学习SpringMVC(二十)之返回JSON

首先要加入三个JAR包:


其次在Controller中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;">package com.cgf.springmvc.handlers;  
  2. import java.util.Collection;  
  3. import org.springframework.beans.factory.annotation.Autowired;  
  4. import org.springframework.stereotype.Controller;  
  5. import org.springframework.web.bind.annotation.RequestMapping;  
  6. import org.springframework.web.bind.annotation.ResponseBody;  
  7. import com.cgf.springmvc.crud.dao.EmployeeDao;  
  8. import com.cgf.springmvc.crud.entities.Employee;  
  9.   
  10. @RequestMapping(value="/springmvc")  
  11. @Controller  
  12. public class MyJson {  
  13.       
  14.     @Autowired  
  15.     private EmployeeDao employeeDao;  
  16.       
  17.     <span style="color:#ff0000;">@ResponseBody</span>  
  18.     @RequestMapping(value="/testJSON")  
  19.     public  Collection<Employee> testJson(){  
  20.         return employeeDao.getAll();  
  21.     }  
  22.   
  23. }</span>  
在index.jsp中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <script type="text/javascript" src="scripts/jquery-1.9.1.min.js"></script>  
  2. <script type="text/javascript">  
  3. $(function(){  
  4.     $("#test_json").click(function(){  
  5.         var url=this.href;  
  6.         var args={};  
  7.         $.post(url,args,function(data){  
  8.             for(var i=0;i<data.length;i++){  
  9.                     var id=data[i].id;  
  10.                     var lastName=data[i].lastName;  
  11.                     alert(id+"---"+lastName);  
  12.             }  
  13.         });  
  14.     return false;  
  15.     });  
  16. })        
  17. </script>  
[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <h2>SpringMVC JSON</h2>  
  2. <a href="springmvc/testJSON" id="test_json">Test Json</a><br>  

学习SpringMVC(二十一)之通过超链接切换Locale


1.配置国际化文件 


2.在springmvc.xml中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;"><!-- 配置国际资源化文件 -->  
  2. <bean name="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">  
  3.         <property name="basename" value="i18n"></property>  
  4. </bean>  
  5. <bean name="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean>  
  6. <!-- 装配拦截器 -->  
  7. <mvc:interceptors>  
  8.     <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean>  
  9. </mvc:interceptors></span>  

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <!-- 配置直接转发页面 -->  
  2. <!-- 可以直接相应转发的页面,而无须再经过Handler方法 -->  
  3. <mvc:view-controller path="/i18n" view-name="i18n1"/>  
  4. <mvc:view-controller path="/i18n1" view-name="i18n2"/>  

3.在index.jsp中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;">  <fmt:message key="i18n.password"></fmt:message>  
  2.     <a href="i18n">I18N1 PAGE</a>  
  3.       
  4.     <br><br>  
  5.     <a href="i18n1?locale=zh_CH">中文</a>  
  6.       
  7.     <br><br>  
  8.     <a href="i18n1?locale=en_US">英文</a></span>  

 

学习SpringMVC(二十二)之文件上传

文件上传的步骤:

1.在index.jsp中写一个表单:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:24px;"> <form action="springmvc/testFileUpload" method="POST" <span style="color:#ff0000;">enctype="multipart/form-data"></span>  
  2.         File: <input type="file" name="file"/>  
  3.         Desc: <input type="text" name="desc"/>  
  4.         <input type="submit" value="Submit"/>  
  5. </form></span>  

2.写一个controller:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:24px;">package com.cgf.springmvc.handlers;  
  2. import org.springframework.stereotype.Controller;  
  3. import org.springframework.web.bind.annotation.RequestMapping;  
  4. import org.springframework.web.bind.annotation.RequestParam;  
  5. import org.springframework.web.multipart.MultipartFile;  
  6. @RequestMapping(value="/springmvc")  
  7. @Controller  
  8. public class MyTestFileUpload {   
  9.     @RequestMapping(value="/testFileUpload")  
  10.     public String testFileUpload(<span style="color:#ff0000;">@RequestParam(value="file")MultipartFile file,</span>  
  11.             @RequestParam(value="desc")String desc){  
  12.         System.out.println(desc);  
  13.         System.out.println("file name:"+file.getOriginalFilename());  
  14.         return "success";  
  15.     }  
  16.   
  17. }</span>  
3.在springmvc.xml中配置CommonsMultipartResolver

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:24px;"><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
  2.         <property name="defaultEncoding" value="UTF-8"></property>  
  3.         <property name="maxUploadSize" value="1024000"></property>    
  4. </bean></span>  

学习SpringMVC(二十三)之拦截器相关

1.自定义一个拦截器的步骤:

第一步,创建一个类实现HandlerInterceptor接口

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:24px;">package com.cgf.springmvc.interceptors;  
  2. import javax.servlet.http.HttpServletRequest;  
  3. import javax.servlet.http.HttpServletResponse;  
  4. import org.springframework.web.servlet.HandlerInterceptor;  
  5. import org.springframework.web.servlet.ModelAndView;  
  6. public class MySecondInterceptors implements HandlerInterceptor{  
  7.     <span style="color:#ff0000;">/** 
  8.      * 在渲染视图之后被调用; 
  9.      * 可以用来释放资源 
  10.      */</span>  
  11.     public void afterCompletion(HttpServletRequest arg0,  
  12.             HttpServletResponse arg1, Object arg2, Exception arg3)  
  13.             throws Exception {  
  14.         // TODO Auto-generated method stub  
  15.         System.out.println("MySecondInterceptors afterCompletion");  
  16.     }  
  17.     <span style="color:#ff0000;">/** 
  18.      * 该方法在目标方法调用之后,渲染视图之前被调用; 
  19.      * 可以对请求域中的属性或视图做出修改 
  20.      *  
  21.      */</span>  
  22.     public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,  
  23.             Object arg2, ModelAndView arg3) throws Exception {  
  24.         // TODO Auto-generated method stub  
  25.         System.out.println("MySecondInterceptors postHandle");  
  26.     }  
  27.     <span style="color:#ff0000;">/** 
  28.      * 可以考虑作权限,日志,事务等等 
  29.      * 该方法在目标方法调用之前被调用; 
  30.      * 若返回TURE,则继续调用后续的拦截器和目标方法 
  31.      * 若返回FALSE,则不会调用后续的拦截器和目标方法 
  32.      *  
  33.      */</span>  
  34.     public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,  
  35.             Object arg2) throws Exception {  
  36.         // TODO Auto-generated method stub  
  37.         System.out.println("MySecondInterceptors preHandle");  
  38.         return true;  
  39.     }  
  40.   
  41. }  
  42. </span>  
第二步,在springmvc.xml中配置:

<mvc:interceptors>,如果在其中配置了<mvc:interceptor>,则可以指定拦截器的路径

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:24px;"><!-- 装配拦截器 -->  
  2. <mvc:interceptors>  
  3.     <bean class="com.cgf.springmvc.interceptors.MyInterceptors"></bean>  
  4.     <mvc:interceptor>  
  5.     <mvc:mapping path="/springmvc/testFileUpload"/>  
  6.         <bean class="com.cgf.springmvc.interceptors.MySecondInterceptors"></bean>  
  7.     </mvc:interceptor>  
  8.     <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean>  
  9. </mvc:interceptors></span>  

多个拦截器的执行顺序


学习SpringMVC(二十四)之异常处理


SpringMVC通过HandlerExceptionResolver处理程序的异常,包括Handler映射,数据绑定以及目标方法执行时发生的异常。



1.在@ExceptionHandler 方法的入参中可以加入 Exception 类型的参数, 该参数即对应发生的异常对象

2.@ExceptionHandler方法的入参中不能传入 Map.若希望把异常信息传导页面上,需要使用 ModelAndView作为返回值
3.@ExceptionHandler 方法标记的异常有优先级的问题.会先处理匹配度高的异常

直接上实例:

在Controller中:

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:18px;"><span style="font-family:SimSun;font-size:18px;">package com.cgf.springmvc.handlers;  
  2. import org.springframework.stereotype.Controller;  
  3. import org.springframework.web.bind.annotation.ExceptionHandler;  
  4. import org.springframework.web.bind.annotation.RequestMapping;  
  5. import org.springframework.web.bind.annotation.RequestParam;  
  6. import org.springframework.web.servlet.ModelAndView;  
  7. @RequestMapping(value="/springmvc")  
  8. @Controller  
  9. public class MyException {    
  10.     <span style="color:#ff0000;">@ExceptionHandler(value={Exception.class})</span>  
  11.     public ModelAndView myException(Exception ex){  
  12.         ModelAndView mv=new ModelAndView("error");  
  13.         mv.addObject("exception", ex);  
  14.         return mv;  
  15.     }     
  16.     @RequestMapping(value="/testException")  
  17.     public String testException(@RequestParam(value="id")int id){  
  18.         System.out.println("id=:"+10/id);  
  19.         return "success";         
  20.     }  
  21.   
  22. }</span></span>  
在springmvc.xml中:需要配置<mvc:annotation-driven/>

在index.jsp中;

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:18px;"><span style="font-family:SimSun;">  <h1>异常处理</h1>  
  2.   <a href="springmvc/testException?id=1">Test Exception</a>  
  3.   <br></span></span>  
4.@ControllerAdvice: 如果在当前 Handler 中找不到 @ExceptionHandler 方法来出来当前方法出现的异常, 

则将去@ControllerAdvice 标记的类中查找 @ExceptionHandler 标记的方法来处理异常.

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:18px;">package com.cgf.springmvc.handlers;  
  2. import org.springframework.web.bind.annotation.ControllerAdvice;  
  3. import org.springframework.web.bind.annotation.ExceptionHandler;  
  4. import org.springframework.web.servlet.ModelAndView;  
  5.   
  6. <span style="background-color: rgb(255, 255, 255);"><span style="color:#ff0000;">@ControllerAdvice</span></span>  
  7. public class MyArithmeticException {  
  8.       
  9.     @ExceptionHandler(value={ArithmeticException.class})  
  10.     public ModelAndView myException(Exception ex){  
  11.         System.out.println("MyArithmeticException");  
  12.         ModelAndView mv=new ModelAndView("error");  
  13.         mv.addObject("exception", ex);  
  14.         return mv;  
  15.     }  
  16.   
  17. }</span>  

5.ResponseStatusExceptionResolver处理用@ResponseStatus标识的异常类或异常方法

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <span style="font-family:SimSun;font-size:18px;">package com.cgf.springmvc.handlers;  
  2. import org.springframework.http.HttpStatus;  
  3. import org.springframework.web.bind.annotation.ResponseStatus;  
  4. @ResponseStatus(reason="用户名与密码不匹配",value=HttpStatus.FORBIDDEN)  
  5. public class UserNameNotMatchPasswordException extends RuntimeException{  
  6.     /** 
  7.      *  
  8.      */  
  9.     private static final long serialVersionUID = 1L;  
  10. }</span>  

6.配置SimpleMappingExceptionResolver来映射异常

[java] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. <bean id="simpleMappingExceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
  2. <property name="exceptionAttribute" value="exception"></property>  
  3. <property name="exceptionMappings">  
  4.     <props>  
  5.     <!-- 全限定名、视图名 -->  
  6.         <prop key="java.lang.ArrayIndexOutOfBoundsException">error</prop>  
  7.     </props>  
  8. </property>  
  9. </bean>  

学习SpringMVC(二十五)之SpringMVC运行流程


1.请求发送给在WEB.XML中配置的DispatcherServlet

2.查找SpringMVC中是否存在相应的映射

2.1如果不存在,则看配置文件中是否配置了<mvc:default-servlet-handler/>。若配置了,则去调用相应的目标资源;若无,则返回404页面,控制台打印:


2.2如果存在,则通过HandlerMapping,获取HandlerExcecutionChain对象




3.获取HandlerAdapter对象



4.之后通过HandlerExcecutionChain对象调用拦截器的preHandle方法,再由HandlerAdapter对象,调用目标方法得到ModelAndView对象,之后调用postHandle方法,如果有异常,则通过异常解析器,处理异常,获取新的ModelAndView对象

5.再由视图解析器得到View,渲染视图,最后调用afterCompletion方法




0 0
原创粉丝点击