Spring MVC深入学习

一、MVC思想

  • MVC思想简介:
       MVC并不是java所特有的设计思想,也不是Web应用所特有的思想,它是所有面向对象程序设计语言都应该遵守的规范;MVC思想将一个应用部分分成三个基本部分:Model(模型)、View(视图)和Controller(控制器),这三个部分以最少的耦合协同工作,从而提高应用的可扩展性和可维护性;
  • MVC特点:
    • 多视图对应一个模型。按MVC模式,一个模型对应多个视图,可以减少代码的复制和维护量,这样一旦模式改变,易于维护;
    • 模型返回的数据和显示的逻辑分离。模型数据可以使用任何的显示技术,例如jsp、velocity模板或直接产生excel文档等;
    • 应用被分割为三层,降低了各层之间的耦合,提高了应用的可扩展性;
    • 控制层的概念很有效,他把不同的模型和不同的视图组合在一起,完成不同的请求。因此,控制层可以说包含了用户请求权限的概念;
    • MVC更符合软件工程化管理的精神,每一层的组件具有相似的特点,有利于通过工程化和工具化的方法产生管理程序代码;

二、SpringMvc的前端控制器DispatcherServlet

在许多的MVC框架中,都包含一个用于调度控制的Servlet。Spring MVC也提供了一个名为org.springframework.web.servlet.DispatcherServlet的Servlet充当前端控制器,所有的请求驱动都围绕这个DispatcherServlet来分派请求。

DispatcherServlet是一个Servlet(继承自httpServlet基类),在使用时需要把他配置到web.xml文件中,配置信息如下:

<servlet>
    <!-- servlet的名称 -->
    <servlet-name>springmvc</servlet-name>
    <!-- servlet对应的java类 -->
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    
    <!-- 当前Servlet的参数信息 -->
    <init-param>
        <!-- contextConfigLocation是参数名称,该参数的值包含SpringMVC的核心配置文件路径-->
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/springmvc-config.xml</param-value>
    </init-param>

    <!-- 在tomcat启动时立即加载servlet -->
    <load-on-startup>1</load-on-startup>
</servlet>
<!-- servlet映射声明 -->
<servlet-mapping>
    <!-- 请求对用的servlet名称 -->
    <servlet-name>springmvc</servlet-name>
    <!-- 监听当前所有请求 -->
    <url-pattern>/</url-pattern>
</servlet-mapping>

三、SpringMvc的后端控制器Handle(两种配置方式)

  • 实现Controller接口
  • 注解(重点)

   DispatcherServlet在Spring当中充当前端控制器的角色,他的核心功能是分发请求,请求会被分发给对应处理的java类,Spring MVC 中称为Handle;Controller接口的实现类只能处理一个单一请求动作,而Spring2.5之后新增的基于注解的控制器可以支持同时处理多个请求动作,并且无需实现任何接口,更加灵活

四、Spring MVC注解

  • @Controller注解

         org.springframework.stereotype.Controller注解类型用于指示Spring类的实例是一个控制器,@Controller用于标记一个类,使用它标记的类就是一个SpringMVC Controller对象,即一个控制器类Spring使用扫描机制查找应用程序中所有基于注解的控制器类。分发处理器会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping注解,使用了的方法才是真正处理请求的处理器。
 
        保证spring能找到控制器,需完成两件事:
    • 在SpringMVC核心配置文件头文件引入spring-context;
    • 使用<context:component-scan/>开启注解扫描(扫描被@Controller、@Service、@repository、@component等注解的类);
  • @RequestMapping注解

    org.springframework.web.bind.annotation.RequestMapping注解类型指示Spring用哪一个类或方法来请求动作,该注解可用于类或方法
 
        @RequestMapping可以用来注释一个控制器类,在这种情况下,所有方法都将映射为相对于类级别的请求,如下:
@Controller
@RequestMapping(value="/user")
public class UserController{
       @RequestMapping(value="/register")
        public String register(){
            return "register";
        }
        @RequestMapping(value="/login")
        public String login(){
            return "login";
        }
}   

由于UserController类中加了value="/user"的@RequestMapping注解,因此所有相关路径都要加上“/user”,此时方法被映射到如下请求:

http://localhost:8080/user/register

http://localhost:8080/user/login

    • @RequestMapping注解支持的常用属性
      • value属性:是@RequestMapping注解默认属性,若只有唯一属性,则可省略属性名
                      @RequestMapping(value="/hello")= @RequestMapping("/hello")
      • method属性:表明该方法仅处理的HTTP请求方式
                    @RequestMapping(value="/hello",method=RequestMethod.POST),只支持post;如果没有指定method属性,则方法可以处理任意HTTP请求方式
      • consumes属性:表明处理请求的提交内容类型;
      • produces属性:表明返回的内容类型;
      • params属性:指定request中必须包含某些参数时,才让该方法处理;
      • headers属性:指定request中必须包含某些指定的header值,才让该方法处理请求;
    • 请求处理方法可以出现的参数类型(SpringMVC默认支持的参数,可出现可不出现,取决于是否用到)_Spring+Mybatis企业应用实战P30
      • HttpServletRequest对象
      • HttpServletResponse对象
      • HttpSession对象
      • Model对象
      • ModelMap对象
      • ......
  • @RequestParam注解

        org.springframework.web.bind.annotation.RequestParam注解类型用于将指定的请求参数赋值给方法中的形参
    • @RequestParam注解支持的常用属性
      • name:String类型;指定请求头绑定的名称
      • value:String类型;name属性的别名
      • required:boolean类型;指定参数是否必须绑定(默认值为true);
      • defaultValue:String类型;如果没有传递参数而是用的默认值
@RequestMapping(value="/login")
public ModelAndView login(@RequestParam("loginname") String loginname,
                          @RequestParam("password") String password){
        return ......;
}
  • @PathVariable注解

         org.springframework.web.bind.annotation.PathVariable注解类型可以非常方便地获得请求URL的中的动态参数;
    • @PathVariable注解支持属性
      • value:String类型,表示绑定的名称,若省略则默认绑定同名参数
@RequestMapping(value="/pathVariableTest/{userId}")
public void pathVariableTest(@PathVariable Integer userId)

假如请求的URL为“http://localhost:8080/DataBindingTest/pathVariableTest/1”,则自动将URL中的模板变量{userId}绑定到通过@PathVariable注解的同名参数上,即userId变量将被赋值为1。

  • @RequestHeader注解

        org.springframework.web.bind.annotation.RequestHeader注解类型用于将请求的头信息区数据映射到功能处理方法的参数上
    • @RequestHeader注解支持的属性
      • name:String类型;指定请求头绑定的名称
      • value:String类型;name属性的别名
      • required:boolean类型;指定参数是否必须绑定;
      • defaultValue:String类型;如果没有传递参数而是用的默认值
@RequestMapping(value="/requestHeaderTest")
public void requestHeaderTest(@RequestHeader("User-Agent") String userAgent,
                              @RequestHeader(value="Accept") String[] accepts)

以上配置自动将请求头“User-Agent”的值赋到userAgent变量上,并将“Accept”请求头的值赋到accepts参数上

  • @CookieValue注解

        org.springframework.web.bind.annotation.CookieValue用于将请求的Cookie数据映射到功能处理方法的参数上
    • @CookieValue注解支持的属性
      • name:String类型;指定请求头绑定的名称
      • value:String类型;name属性的别名
      • required:boolean类型;指定参数是否必须绑定;
      • defaultValue:String类型;如果没有传递参数而是用的默认值
@RequestMapping(value="/cookieValueTest")
public void cookieValueTest(@CookieValue(value="JSESSIONID",defaultValue="") String sessionId)

以上配置会自动将JSESSIONID值设置到sessionId参数上,defaultValue表示Cookie中没有JSESSIONID时默认为空

  • @SessionAttributes注解(只能声明类,不能声明方法)

        org.springframework.web.bind.annotation.SessionAttributes注解类型允许我们有选择的指定Model中的哪些属性需要转存到HttpSession当中
    • @SessionAttributes注解支持的属性
      • names属性:String[]类型,Model中属性名称,即存储在HttpSession当中的属性名称;
      • value属性:String[]类型,names属性的别名;
      • types属性:Class<?>[]类型,用来指定放入HttpSession当中的对象类型
@Controller
//将Model中属性名为user的属性放入HttpSession对象当中
@SessionAttributes("user")
public class SessionAttributesController{
    
    @RequestMapping(value="/login")
    public String login(@RequestParam("loginname") String loginname,
                        @RequestParam("password") String password,
                        Model model){
         //创建User对象,装载用户信息
         User user = new User();
         user.setLoginname(loginname);
         user.setPassword(password);
         //将user对象添加到Model当中
         model.addAttribute("user",user);
         return "welcome";
    }
}

JSP页面测试以上@SessionAttributes注解:

${requestScope.user.username}//页面显示admin
${sessionScope.user.username}//页面显示admin

结论:User对象被成功设置到了HttpSession对象当中

@SessionAttributes注解如下写法: @SessionAttributes(types={User.class},value="user") 

还可以设置多个对象到HttpSession当中:

  • @ModelAttribute注解

        org.springframe.web.bind.annotation.ModelAttribute注解类型将请求参数绑定到Model对象
    • @ModelAttribute注解支持的属性(仅一个)
      • value属性:String类型,表示绑定的属性名称
        
    Notice被@ModelAttribute注释的方法会在Cobtroller每个方法执行前被执行,因此在一个Controller映射到多个URL时,要谨慎使用!
    @ModelAttribute注解使用情况:
    • @ModelAttribute(value="")注释返回具体类的方法@ModelAttribute("loginname") public String userModel1(@RequestParam("logginname") String loginname){ return loginname; }
    • @ModelAttribute注释void返回值的方法
      @ModelAttribute
      public void userModel2(@RequestParam("loginname") String loginname,
                             @RequestParam("password") String password,
                             Model model){
          model.addAttribute("loginname",loginname);
          model.addAttribute("password",password);
      }
    • @ModelAttribute注释返回具体类的方法
      @ModelAttribute
      public User userModel3(@RequestParam("loginname") String loginname,
                             @RequestParam("password") String password){
           return new User(loginname,password);
      }
    • @ModelAttribute和@RequestMapping同时注释一个方法@RequestMapping(value="/login") @ModelAttribute(value="username") public String login4(){ return "admin"; }
    • @ModelAttribute注释一个方法的参数
      @ModelAttribute("user")
      public User userModel5(@RequestParam("loginname") String loginname,
                             @RequestParam("password") String password){
          User user = new User();
          user.setLoginname(loginname);
          user.setPassword(password);
          return user;
      }
      @RequestMapping(value="/login5")
      public String login5(@ModelAttribute("user") User user){
          user.setUsername("管理员");
          return "result5";
      }

      不管@ModelAttribute注解在什么情况下使用,model对象中的属性名都是@ModelAttribute的属性value值(有value存在情况下)或返回类型对象名(没有value存在情况下);model对象中的值是方法返回值(有返回值情况下)或自己填充model(没有返回值情况下)

五、SpringMVC框架乱码解决方案

  • POST提交中文乱码解决

     在web.xml中添加过滤器:
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
       <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
       </init-param>
</filter>
<filter-mapping>
     <filter-name>CharacterEncodingFilter</filter-name>
     <url-pattern>/*</url-pattern>
</filter-mapping>
  • GET请求中文乱码解决(两种方法)

    • 修改tomcat配置文件添加编码与工程编码一致,如下:
      <Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
    • 对参数进行重新编码:String userName = new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8")ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码

六、SpringMVC框架运转在执行handler(Controller)时,Spring会额外做一些工作:

  • 消息转换:将请求信息(如json、xml等数据)封装成一个对象,将对象转换为指定的相应信息;
  • 数据转换:对请求信息进行数据转换,如String转换成Integer、Double等;
  • 数据格式化:如将字符串转化成格式化数字或格式化日期;
  • 数据验证:验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中;
 
  • 特殊情况(解决日期类型参数转换问题):由于日期数据有很多种格式,所以springmvc没办法把字符串转换成日期类型。所以需要自定义参数绑定。前端控制器接收到请求后,找到注解形式的处理器适配器,对RequestMapping标记的方法进行适配,并对方法中的形参进行参数绑定。在springmvc这可以在处理器适配器上自定义Converter进行参数绑定。如果使用<mvc:annotation-driven/>可以在此标签上进行扩展。

     解决方案:

      自定义转换器Converter

Public class DateConverter implements Converter<String, Date> {
      @Override
      public Date convert(String source) {
           SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
           try {
                 return simpleDateFormat.parse(source);
           } catch (ParseException e) {
                 e.printStackTrace();
           }
           Return null;
      }
}

      配置Converter(在SpringMVC核心配置文件中)——第一种

<!-- 加载注解驱动 -->
      <mvc:annotation-driven conversion-service="conversionService"/>
      <!-- 转换器配置 -->
      <bean id="conversionService"
           class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
           <property name="converters">
                 <set>
                      <!-- 自己配置的日期转换器,如果还有其他转换器,可以继续在这里添加bean -->
                      <bean class="cn.itcast.spring mvc.convert.DateConverter"/>
                 </set>
           </property>
      </bean>

      第二种配置方式:此方法需要独立配置处理器映射器、适配器,不再使用<mvc:annotation-driven/>

<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"
      xmlns:context="http://www.springframework.org/schema/context"
      xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"xmlns:mvc="http://www.springframework.org/schema/mvc"
      xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.0.xsd">
      <!-- 扫描带Controller注解的类 -->
      <context:component-scanbase-package="cn.itcast.springmvc.controller"/>
     
      <!-- 转换器配置 -->
      <beanid="conversionService"
           class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
           <propertyname="converters">
                 <set>
                      <beanclass="cn.itcast.springmvc.convert.DateConverter"/>
                 </set>
           </property>
      </bean>

      <!-- 自定义webBinder -->
      <beanid="customBinder" class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
           <propertyname="conversionService"ref="conversionService"/>
      </bean>

      <!--注解适配器 -->
      <beanclass="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
           <propertyname="webBindingInitializer"ref="customBinder"></property>
      </bean>

      <!-- 注解处理器映射器 -->
      <beanclass="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
      
      <!-- 加载注解驱动 -->
      <!-- <mvc:annotation-driven/> -->

      <!-- 视图解析器 -->
      <beanclass="org.springframework.web.servlet.view.InternalResourceViewResolver">
           <propertyname="viewClass"
                 value="org.springframework.web.servlet.view.JstlView"/>
           <!-- jsp前缀 -->
           <propertyname="prefix"value="/WEB-INF/jsp/"/>
           <!-- jsp后缀 -->
           <propertyname="suffix"value=".jsp"/>
      </bean>
</beans>

 七、消息转换:将JSON、XML消息封装成对象,转换为相应的响应信息

  • @RequestBody注解

        org.springframework.web.bind.annotation.RequestBody注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到Controller中方法的参数上;
        前台页面get或post提交数据时,数据编码格式由请求头的ContentType制定,可分以下情况:
    • application/x-www-form-urlencoded,这种情况的数据@RequestParam、@ModelAttribute也可以处理,@RequestBody也能处理(name1=value1&name2=value2........)
    • multipart/form-data,@RequestBody不能处理这种数据(有file处理时)
    • application/json、application/xml等格式数据,必须用@RequestBody处理     
  • 转换Json数据

      Spring MVC提供了处理JSON格式请求/响应的HttpMessageConverter: MappingJackson2HttpMessageConverter
   利用Jackson开源类包处理JSON格式的请求和响应消息(Spring官方说明,Spring MVC默认使用MappingJackson2HttpMessageConverter转换JSON格式数据,jackson开源类包可将java对象转换成json对象和xml文档,或逆转)
    • 示例:接收JSON格式的数据

       JSP页面:

<%@ page language="java" contentType="text/html;charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>测试接收JSON格式的数据</title>
<script type="text/javascript" src="js/jquery-1.11.0.min.js"/>
<script type="text/javascript" src="js/json2.js"/>
<script type="text/javascript">

$(document).ready(function(){
    testRequestBody();
});

function testRequestBody(){
    $.ajax("${pageContext.request.contextPath}/json/testRequestBody"//请求url
        {dataType:"json",    //预期服务器返回的数据类型
             type:"post",    //请求方式post或get
         contentType:"application/json"  //发送信息至服务器时的内容编码格式
         //发送到服务器的数据
         data:JSON.stringify({id:1,name:"Spring MVC企业应用实战"}),
         async:true,//默认设置下,所有请求为异步,若false,则发送同步请求
         //请求成功后的回掉函数
         success:function(data){
            console.log(data);
            $("#id").html(data.id);
            $("#name").html(data.name);
            $("#author").html(data.author);
          },
          //请求出错时调用的函数
          error:function(){
             alert("数据发送失败");
          }
    });
}
</script>
</head>
<body>
编号:<span id="id"></apan>

书名:<span id="name"></span>

作者:<span id="author></span>

</body>
</html>

      Controller:

@Controller
@RequestMapping("/json")
public class BookController{
    private static final Log logger = LogFactory.getLog(BookController.class);
    //@RequestBody根据json数据,转换成对应的Object
    @RequestMapping(value="/testRequestBody")
    public void setJson(@RequestBody Book book,
                        HttpServletResponse response) throws Exception{
        //ObjectMapper类是jackson库的主要类。他提供一些功能将java对象转换成对应的JSON格式数据
        ObjectMapper mapper = new ObjectMapper();
        //将book对象转换成为json输出
        logger.info(mapper.writeValueAsString(book));
          book.setAuthor("肖文姬");
        response.setContentType("text/html;charset=UTF-8");
        //将book对象转换成json写出到客户端
        response.getWriter().println(mapper.writeValueAsString(book));
    }
} 

setJson方法的第一个参数@RequestBody Book book表示,使用@RequestBody注解获取到json数据后,将json数据设置到对应的book对象属性中去,参数response用于输出响应数据到客户端。

      Book类:定义三个属性(id、name、author)

      SpringMVC核心配置文件:

<!-- 注解扫描 -->
<context:component-scan base-package="org.fkit.controller"/>
<!-- 注解驱动 -->
<mvc:annotation-driven/>

<!-- 使用默认的Servlet来响应静态文件 -->
<mvc:default-servlet-handler/>

<!-- 视图解析器 -->
<bean id="viewResoler" class="org.springframework.web.servlet.view.InternalResourceViewResoler">
    <!-- 前缀 -->
    <property name="prefix">
        <value>/WEB-INF/content/</value>
    </property>
    <!-- 后缀 -->
    <property name="suffix">
        <value>.jsp</value>
    </property>
</bean>

<mvc:default-servlet-handler/>使用默认的Servlet来响应静态文件,因为在web.xml文件中使用了DispatcherServlet截获所有请求url,而引入<script type="text/javascript" src="js/jquery-1.11.0.min.js"/>的时候,DispatcherServlet会将“/”看成请求路径,找不到他的时候会报404错误。而当配置文件加上这个默认的Servlet时,Servlet在找不到它时会去找静态的内容,即js目录

    • 示例:自定义HttpMessageConverter接收JSON格式数据(不使用默认jackson开源类包):说明:使用其他开源类包配置HttpMessageConverter(fastjson)

      Controller:

@Controller
@RequestMapping("/json")
public class BookController{
    private static final Log logger = LogFactory.getLog(BookController.class);
    //@RequestBody根据json数据,转换成对应的Object
    @RequestMapping(value="/testRequestBody")
    public void setJson(@RequestBody Book book,
                        HttpServletResponse response) throws Exception{
        //JSONObject-lib包是一个beans,collections,maps,java arrays和xml和JSON互相转换的包

        //使用JSONObject将book对象转换成为json输出
        logger.info(JSONObject.toJSONString(book));
        book.setAuthor("肖文姬");
        response.setContentType("text/html;charset=UTF-8");
        //将book对象转换成json写出到客户端
        response.getWriter().println(JSONObject.toJSONString(book));
    }
}    

      Springmvc-config.xml(核心配置文件):

<!-- 注解扫描 -->
<context:component-scan base-package="org.fkit.controller"/>

<!-- 注解驱动,摒弃默认配置HttpMessageConverter,自定义配置HttpMessageConverter -->
<mvc:annotation-driven>
    
    <!-- 设置不使用默认的消息转换器 -->
    <mvc:message-converter register-defaults="false">
        <!-- 配置Spring的转换器 -->
        <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
        <bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"/>
        <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
        <bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/>

        <!-- 配置fastjson中实现HttpMessageConverter接口的转换器 -->
        <!-- FastJsonHttpMessageConverter是fastjson中实现了HttpMessageConverter接口的类 -->
        <bean id="fastJsonHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
              <!-- 加入支持的媒体类型;返回contentType -->
              <property name="supportedMediaTypes">
                    <list>
                        <!-- 这里顺序不能反,一定先写text/html,不然IE下会出现下载提示 -->
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                    </list>
              </property>
        </bean>
    </mvc:message-converter>

</mvc:annotation-driver>

<!-- 使用默认的Servlet来响应静态文件 -->
<mvc:default-servlet-handler/>

<!-- 视图解析器 -->
<bean id="viewResoler" class="org.springframework.web.servlet.view.InternalResourceViewResoler">
    <!-- 前缀 -->
    <property name="prefix">
        <value>/WEB-INF/content/</value>
    </property>
    <!-- 后缀 -->
    <property name="suffix">
        <value>.jsp</value>
    </property>
</bean>

本项目说明:自定义实现HttpMessageConverter时,关闭默认使用的MappingJackson2HttpMessageConverter消息转换器,不使用jackson开源类包,而是选择了更好的fastjson包,把转换器配置成FastJsonHttpMessageConverter类型,这个类实现了HttpMessageConverter接口;

JSP页面和java文件同上一个项目;

总结:由上两个项目可知:处理JSON格式的开源类包使用jackson和fastjson,只是HttpMessageConverter的实现不同;

  • @ResponseBody注解

          org.springframework.web.bind.annotation.ResponseBody注解用于将Controller的方法返回的对象,通过适当的消息转换器转为指定格式后,写入Response对象的body数据区。通常当返回的数据不是html标签页面,而是其他某种格式的数据时(如json、xml等)使用它。
    • 示例:返回JSON格式数据

      Controller:

@Controller
@RequestMapping("/json")
public class BookController{
    @RequestMapping(value="/testResponseBody")
    //@ResponseBody会将集合数据转换为json格式并将其返回客户端
    @ResponseBody
    public Object getJson(){
        List<Book> list = new ArrayList<Book>();
        list.add(new Book(1,"Spring MVC 企业应用之战","肖文姬"));
        list.add(new Book(2,"轻量级javaee企业应用之战","李刚"));
        return list;
    }
}

      JSP页面:

<%@ page language="java" contentType="text/html;charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>测试返回JSON格式的数据</title>
<script type="text/javascript" src="js/jquery-1.11.0.min.js"/>
<script type="text/javascript" src="js/json2.js"/>
<script type="text/javascript">

$(document).ready(function(){
    testResponseBody();
});

function testResponseBody(){
    $.post("${pageContext.request.contextPath}/json/testResponseBody",null,
            function(data){
                $.each(data,function(){
                    var tr = $("<tr align='center'/>");
                    $("<td/>").html(this.id).appendTo(tr);
                    $("<td/>").html(this.name).appendTo(tr);
                    $("<td/>").html(this.author).appendTo(tr);
                    $("#booktable").append(tr);
                })
    },"json");
}
</script>
</head>
<body>
<table id="booktable" border="1" style="border-collapse:collapse;">
    <tr align="center">
        <th>编号</th>
        <th>书名</th>
        <th>作者</th>
    </tr>
</table>
</body>
</html>
  • 转换XML格式数据

        Spring MVC提供了处理XML格式请求/响应的HttpMessageConverter,如jaxb2RootElementHttpMessageConverter通过JAXB2读写XML消息,并将消息转换到注解@XmlRootElement和@XmlType作用的类中;
       Spring官方说明,Spring MVC默认使用了Jaxb2RootElementHttpMessageConverter转换xml格式数据,JAXB(Java Architecture for XML Binding)可以将JSON和XML互转;
       JAXB是一项可以根据XML Schema产生Java类的技术,在过程中,JAXB提供了将XML实例文档反向生成Java对象的方法,并能将Java对象的内容重新写到XML文档中。
       JAXB常用注解:@XmlRootElement、@XmlElement,等等
 
    • 示例:接收XML格式的数据

      JSP页面:

<%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>测试接收XML格式的数据</title>
<script type="text/javascript" src="js/jquery-1.11.0.min.js"/>
<script type="text/javascript" src="js/json2.js"/>
<script type="text/javascript">

$(document).ready(function(){
    sendXml();
});

function sendXml(){
    var xmlData = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><book><id>1</id><name>疯狂Java 讲义</name><author>李刚</author></book>";
    $.ajax("${pageContext.request.contextPath}/sendXml",//发送请求的URL字符串
            {
                type:"post",//请求方式post或get
                contentType:"application/xml",//发送信息至服务器时的内容编码类型
                //发送到服务器的数据
                data:xmlData,
                async:true,//默认设置下,异步请求;若false则发送同步请求
            });
}
</script>
</head>
<body>
</body>
</html>

      Book类:

//@XmlRootElement表示XML文档的根元素
@XmlRootElement
public class Book implements Serializable{
    private Integer id;
    private String name;
    private String author;
    
    public Book(){
        super();
    }
    public Book(Integer id,String name,String author){
        this.id=id;
        this.name=name;
        this.author=author;
    }

    public Integer getId(){
        return id;
    }
    //该属性作为xml的element
    @XmlElement
    public void setId(Integer id){
        this.id=id;
    }
    public Integer getName(){
        return name;
    }
    //该属性作为xml的element
    @XmlElement
    public void setName(String name){
        this.name=name;
    }
    public Integer getAuthor(){
        return author;
    }
    //该属性作为xml的element
    @XmlElement
    public void setAuthor(String author){
        this.author =author ;
    }

    @Override
    public String toString(){
        return "Book[id="+id+",name="+name+",author="+author+"]";
    }
}

      BookController:

@Controller
public class BookController{
    private static final Log logger = LogFactory.getLog(BookController.class);
    //@RequestBody会自动将xml数据绑定到Book对象
    @RequestMapping(value="/sendXml,method=RequestMethod.POST")
    public void sendXml(@RequestBody Book book){
        logger.info(book);
        logger.info("接收xml数据成功");
    }
    
    //@ResponseBody会将Book自动转换为xml数据返回
    @RequestMapping(value="/readXml",method=RequestMethod.POST)
    public @ResponseBody Book readXml() throws Exception{
        //通过JAXBContext的newInstance()方法,传递一个class就可以获得一个上下文
        JAXBContext context = JAXBContext.newInstance(Book.class);
        
        //创建一个Unmarshall对象
        Unmarshaller unmar = context.createUnmarshaller();
        InputStream is = this.getClass().getResourceAsStream("/book.xml");

        //Unmarshall对象的unmarshall方法可以进行xml到Java对象的转换
        Book book = (Book)unmar.unmarshall(is);
        logger.info(book);
        return book;
    }
}

springmvc-config.xml核心配置文件中注解驱动<mvc:annotation-driven/>,默认配置了jaxb2RootElementHttpMessageConverter作为转换器处理xml数据转换

    • 示例:返回xml格式数据

      JSP页面:

<%@ page language="java" contentType="text/html;charset=UTF-8" 
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>测试接收XML格式的数据</title>
<script type="text/javascript" src="js/jquery-1.11.0.min.js"/>
<script type="text/javascript" src="js/json2.js"/>
<script type="text/javascript">

$(document).ready(function(){
    readXml();
});

function readXml(){
    $.ajax("${pageContext.request.contextPath}/readXml",//发送请求的URL字符串
            {
                dataType:"text",//预期服务器返回的数据类型
                type:"post",//请求方式post或get
                async:true,//默认设置下,异步请求;若false则发送同步请求
                success:function(xml){
                    //获得xml数据的id,name,author
                    var id=$("id",xml).text();
                    var name=$("name",xml).text();
                    var author=$("author",xml).text();
                    var tr = $("<tr align='center'/>");
                    $("<td/>").html(id).appendTo(tr);
                    $("<td/>").html(name).appendTo(tr);
                    $("<td/>").html(author).appendTo(tr);
                    $("#booktable").append(tr);
                },
                //请求出错时调用的函数
                error:function(){
                    alert("数据接收失败");
                }
            });
}
</script>
</head>
<body>
<table id="booktable" border="1" style="border-collapse:collapse;">
    <tr align="center">
        <th>编号</th>
        <th>书名</th>
        <th>作者</th>
    </tr>
</table>
</body>
</html>
待续。。。      

 

猜你喜欢

转载自www.cnblogs.com/wly1-6/p/10401594.html