SpringMvc @ResponseBody

 
 

一. @Response使用条件

1.引入依赖jackson-databind 或者其他类型的json转换,比如gson、fastjson

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.8.1</version>
    </dependency>

2.最小配置,<mvc:annotation-driven/>

最低满足上面两个条件,即可在@RequestMapping的方法上添加注解@ResponseBody,将结果用JSON直接返回给客户端.

 

二. @Response在最小配置、jackson的jar包情况下,json中包含的日期类型字段都是以时间戳long类型返回

直接说结论,各位可以尽管测试,使用jackson的情况下,转换的json日期类型字段都会以时间戳long类型展示;
jackson最简单的API使用方式普及下,当然你也可以倒数第二行调用 writeValueAsString这样更加简单:
   public static void main(String[] args) throws IOException {
        JsonEncoding encoding = JsonEncoding.UTF8;
        ObjectMapper mapper = new ObjectMapper();
        JsonGenerator generator =mapper.getFactory().createGenerator(new File("E:\\home\\1.txt"),encoding);
        ObjectWriter writer = mapper.writer();
        Date date = new Date();
        writer.writeValue(generator,date);
        generator.flush();
    }
查看输出文件的信息: Spring底层就是按照这个API 调用方式来生成JSON ,我们没有对ObjectMapper做任何配置,所以生成日期类型都是返回其时间戳;
SpringMvc 4.3中@ResponseBody时间类型是返回时间戳类型,至于其他版本测试就可以知道是否直接返回时间戳类型;

  image

二.1  Jackson Api层面记录如何取消这种时间类型生成方式

下面用mapper代替你的new ObjectMapper()
方式一. mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
                 说明:mapper  configure设置需要在 createGenerator  以及  获取writer之前才有效!
方式二. mapper.setDateFormat(new SimpleDateFormat("yyyy--MM--dd HH:mm:ss"));
                  说明:这种方式扩展性更好,可以日期自定义格式化,相比较方式一更符合开发需求;
方式三. 实体属性上标注注解 @JsonFormat
public static void main(String[] args) throws IOException {
        JsonEncoding encoding = JsonEncoding.UTF8;
        ObjectMapper mapper = new ObjectMapper();
        JsonGenerator generator =mapper.getFactory().createGenerator(new File("E:\\home\\1.txt"),encoding);
        ObjectWriter writer = mapper.writer();
        PrivateMyDate date = new PrivateMyDate();
        writer.writeValue(generator,date);
        generator.flush();
}

static class PrivateMyDate{
  @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
  public Date now=new Date();
}
效果图如下:@JsonFormat是Jackson的,而不是Spring的!

image_thumb31[1]

  说明:方式三应该是日常开发中最方便的,只需要在实体类上添加@JsonFormat,可以满足各种类型的日期格式

 


三. Jack序列化对象转为JSON的限制条件

三.1 Jackson API使用注意事项点:
之前偷懒, 属性修饰符、getter方法都没有写 , 误打误撞发现Jackson抛出异常
com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class xxx and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
当结合Spring @ResponseBody一起使用,那异常可能就是另外一种表现形式(当然下面这种异常不仅仅可能是这个Jackson Api使用注意事项引起的)
java.lang.IllegalArgumentException: No converter found for return value of type: class demo2.MyDate

 

三.1.1异常引起原因:比如尝试序列化Json这样一个实体类,就会抛出第一种异常,在Spring就会抛出第二种异常
public class PrivateMyDate {
    String name="123";
    int age=18;
}
三.1.2 异常原因说明:  Jackson2默认地序列化成JSON,实体类属性或者对应属性getter方法为 public类型,才能够将该属性成功转为Json ; 如果只是少数字段不为public类型,那这些少数字段就不会出现在转换后的Json中;如果所有字段都不是public且没有public的getter方法,就会抛出上面第一种异常 ;
 
三.1.3 异常解决方案:
方案一.最直接的方案

         如果有权操作实体类,给对应实体类添加标准的getter方法(public类型,jackson默认是标准的)

方案二.全局级别方案

          obejctMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);

           说明:ANY 代表转换成JSON时候  FIELD即属性可以为任意类型,public、protected、default、private类型都可以
方案三.实体级别方案
           实体类上标注 @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)即可

 

三.1.4 Jackson2结合Spring4.x实现全局级别的@JsonFormat以及 @JsonAutoDetect
自己修改了下原来<mvc:annotation-driven/>达到了全局级别的效果,不用再在实体类上添加@JsonFormat以及@JsonAutoDetect; 简单说明下原理:新增了MappingJackson2HttpMessageConverter,自己配置了一个ObjectMapper,其中visibility属性篇幅较长,如果遇到第一种异常的话可以加上;
<mvc:annotation-driven>
    <mvc:message-converters>
        <bean id="mappingJackson" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            &l
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值