使用HttpMessageConverter处理JSON

HttpMessageConverter<T>工作原理:

  HttpMessageConverter<T> 是 Spring3.0 新添加的一个接口,负责将请求信息转换为一个对象(类型为 T)并绑定到处理方法的入参中,或将对象(类型为T)输出为响应信息。对此SpringMVC提供了两种实现途径:

  1. 使用@RequestBody/@ResponseBody注解对处理方法进行标注。
  2. 使用HttpEntity<T>/ResponseEntity<T>作为处理方法的入参或返回值。

      当控制器处理方法使用到@RequestBody/@ResponseBody 或者 HttpEntity<T>/ResponseEntity<T>时,Spring首先根据请求头或响应头的Accept属性选择匹配的HttpMessageConverter,进而根据参数类型或泛型类型的过滤得到匹配的HttpMessageConverter,若找不到可用的HttpMessageConverter将会报错。
      
      下图展示了HttpMessageConverter<T>的工作原理:
    image_1b1e5tcdhui21hgpn6eqo3ba01t.png-204.3kB

      DispatcherServlet默认装配了RequestMappingHandlerAdapter,我们查看Spring源码发现RequestMappingHandlerAdapter默认装配了如下的HttpMessageConverter:
      image_1b1eccehf393hvg135teo0105o3u.png-210.6kB

HttpMessageConverter<T>使用示例

  在开始介绍HttpMessageConverter<T>的用法之前,需要先导入jar包:
  
image_1b1e4vo451r1j1pc1qmm1sc5127n9.png-3.9kB

  在导入以上jar包后,RequestMappingHandlerAdapter会自动额外装配一个HttpMessageConverter对象,用于在Java对象和JSON对象之间进行转换:
  image_1b1ecs9khgn721bln28qrao04b.png-248.1kB
  
  下面的三个示例分别展示了@ResponseBody、@RequestBody和ResponseEntity<T>的使用方法,HttpEntity<T>用法类似。
  
示例一:通过@RequestBody注解将目标方法返回的Java对象转为HttpOutputMessage,并在页面中通过AJAX获取:

jsp:

&lt;%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%&gt;
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;
&lt;title&gt;index jsp&lt;/title&gt;
&lt;script type="text/javascript"
    src="${pageContext.request.contextPath }/scripts/jquery-1.9.1.min.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
    $(function() {
        $("#testJson").click(function() {
            var url = $(this).attr("href");
            var arg = {
                "time" : new Date()
            };
            $.get(url, arg, function(data) {
                for (var i = 0; i &lt; data.length; i++)
                    alert(data[i].id + ":" + data[i].lastName);
            });
            return false;
        });
    })
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;a href="testJson" id="testJson"&gt;Test Json&lt;/a&gt;
&lt;/body&gt;
&lt;/html&gt;

controller:

    @ResponseBody
    @RequestMapping("/testJson")
    public Collection&lt;Employee&gt; testJson(){
        return employeeDao.getAll();
    }

运行后浏览器会依次弹出“data[i].id + “:” + data[i].lastName”的提示信息:
image_1b1e5htql1qbvqkm45h1br01pi4m.png-8.8kB
image_1b1e5iuc215auou3m7164dubo13.png-9.8kB
image_1b1e5j6681i2i1jtk1t71fi010mv1g.png-10.2kB

          …
          
示例二:通过@RequestBody注解实现实现文件上传的功能:

jsp:

&lt;form action="testRequestBody" method="post" enctype="multipart/form-data"&gt;
    File:&lt;input type="file" name="file" /&gt;
    Description:&lt;input type="text" name="des" /&gt;
    &lt;input type="submit" value="Submit" /&gt;
    &lt;/form&gt;

controller:

    @ResponseBody
    @RequestMapping("/testRequestBody")
    public String testRequestBody(@RequestBody String body){
        System.out.println(body);

        //return "helloworld!"+new Date()保证了方法执行完后不会匹配任何一个页面
        return "helloworld!"+new Date();
    }

运行程序,我们上传一个test.txt文件,其中存储了某一jsp页面的信息,并在Description中输入文本值“MY TEXT”:

image_1b1eatgr614ev90sl1a1bvqlo134.png-4.4kB

提交之后,HttpMessageConverter会把上传的文件和文本值转换为一个String类型的对象,并在控制台输出:

image_1b1ea9rkce0gv63gt42mbdum2a.png-51.8kB

而且浏览器上也显示了helloworld!+时间:

image_1b1eab44h162210eaalel771c802n.png-11.8kB

注意,如果在spring的配置文件中注册了CommonsMultipartResolver类型的bean实例,如下:

&lt;bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver"&gt;
    &lt;/bean&gt;

那么@RequestBody就不能正常将上传的文件类型转换为String类型在控制台输出了,原因暂时我还不太清楚。

示例三:通过@ResponseEntity<T>实现文件下载的功能:

jsp:

&lt;a href="testResponseEntity"&gt;Test ResponseEntity&lt;/a&gt;

在根目录下的file目录下保存了示例二中的test.txt:

image_1b1ec0e011pq61o0v1nipd41j6f3h.png-3.2kB

controller:

@ResponseBody
    @RequestMapping("/testResponseEntity")
    public ResponseEntity&lt;byte[]&gt; testResponseEntity(HttpSession session) throws IOException{
        byte[] body = null;
        ServletContext context = session.getServletContext();
        InputStream in = context.getResourceAsStream("/file/test.txt");
        body = new byte[in.available()];
        in.read(body);

        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Disposition", "attachment;filename=test.txt");

        HttpStatus statusCode = HttpStatus.OK;

        ResponseEntity&lt;byte[]&gt; entity = new ResponseEntity&lt;byte[]&gt;(body, headers, statusCode);

        return entity;
    }

运行程序,点击超链接Test ResponseEntity后发现可以正确下载test.txt文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值