springMVC-8-jackson使用

springMVC默认的 Json 解决方案是 Jackson, 所以只需要导入 Jackson 的 jar, 即可使用

<!--Jackson-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.8</version>
        </dependency>
    </dependencies>

jackson 可以通过以下三个注解来实现对 json 数据的处理:

  • @ResponseBody
  • @RestController
  • @RequestBody

一、@ResponseBody

含义:把这个handler的返回值转成json返回给客户端, 所以此handler不会跳转到相关JSP页面, 如果返回的是字符串, 则不会转成Json, 直接返回

示例:

@ResponseBody
@RequestMapping(value="test")
//这个注解的意思是: 把这个handler的返回值转成json返回给客户端, 所以此handler不会跳转到相关JSP页面, 如果返回的是字符串, 则不会转成Json, 直接返回
public byte[] test(@RequestBody String requestBody){
    return "testString";
}

乱码问题:

注意: 此时由于未调用springMVC操作转json, 直接返回中文会有乱码问题, 需要我们设置编码格式, 设置方式为在@RequestMapping注解的参数中指定 value = "/test2", produces = "text/html;charset=utf-8"

@ResponseBody
@RequestMapping(value = "/responseBody",produces = "text/html;charset=utf-8" )
public String testResponseBody(){
    return "服务器数据";
}

二、@RestController

当我们在一个Controller中的所有handler前都要加@ResponseBody注解时, 我们可以在这个Controller前面加上@RestController注解, 这样, 其下的所有@ResponseBody注解都不需要加了, 同时, @RestController是一个复合注解, 其中集成了@Controller, 所以@Controller注解也可以省略,

@RestController
public class TestControl {

    private EmployeeDao employeeDao;
    @Autowired
    public void setEmployeeDao(EmployeeDao employeeDao) {
        this.employeeDao = employeeDao;
    }
    private DepartmentDao departmentDao;
    @Autowired
    public void setDepartmentDao(DepartmentDao departmentDao) {
        this.departmentDao = departmentDao;
    }
    //--------------------------------------------------//
    
    //测试requestBody
    @RequestMapping(value ="/testRequestBody",produces = "text/html;charset=utf-8")
    public Collection<Employee> getEmployee(){
        return employeeDao.getAll();
    }   
}

三、@RequestBody

@RequestBody 注解可以用来接收请求的 json 数据

示例:

index.jsp

<button class="btn btn-primary" onclick="send_json();">ajax</button>
<script type="text/javascript">
    function send_json() {
        //创建要转换成json的对象
        var data = {name:"wang"};
        //把这个对象转换成json数据
        var person = JSON.stringify(data);
        //$.ajax()内传入的是一个对象
        $.ajax({
            //url:"local:8080/testRequestBody
            url:"/testRequestBody",
            type: "post",
            data: person,
            dataType:"json",
            contentType:"application/json",
            success:function (res) {
                alert(res);
            }
        })
    }
</script>

control

//测试requestBody
@RequestMapping(value ="/testRequestBody",produces = "text/html;charset=utf-8")
public Collection<Employee> getEmployee(@RequestBody Person person){
    System.out.println(person);
    return employeeDao.getAll();
}

注意点:

1、我们这里因为转了json,所以之前在@RequestMapping(value = "/responseBody",produces = "text/html;charset=utf-8" )上的produces一定要删掉,不然就会因为不是json数据,客户端姐接受不了,而报406的错误

2、客户端传入的json数据不是一定要和pojo种的属性名一致

jsp中:

var data = {personName:"wang",personAge:"11"};

pojo

private String name;
private Integer age;

四、json的进阶操作

我们可以添加一些 person的注解来处理 Jackson 返回的 json 数据.

修改pojo

@Repository
public class Person {
    private String name;
    private Integer age;
    private Date date;
    省略。。。。
}

control

//测试requestBody
@RequestMapping(value ="/testRequestBody")
public Person getEmployee(@RequestBody Person person){
    System.out.println(person);
    //给jsp传一个带时间的数据,观察在jsp页面会怎么处理
    Person newPerson = new Person("zuo", 56, new Date());
    System.out.println("-------->>"+newPerson);
    return newPerson;
}

会发现

客户端:

服务端:

1、@JsonFormat

用户更改输出的 Date 类型数据的格式

@Repository
public class Person {
    private String name;
    private Integer age;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date date;
    省略。。。。
}

客户端:

服务端:(可见这种格式化是在实例化对象的时候就会进行的

访问结果:(日期已显示规范格式, 但默认时区非东八区)

修改

@Repository
public class Person {
    private String name;
    private Integer age;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private Date date;
    省略。。。。
}

访问结果:(东八区时间)

2、@JsonIgnore

添加了该属性的值将不会出现在返回的 json 数据中.

@Repository
public class Person {
    private String name;
    @JsonIgnore
    private Integer age;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private Date date;
	省略。。。
}

客户端:

服务端:

会发现:

传过来的json造好的实例化对象也没有给age注入age属性,结论:json数据转实例化对象和实例化对象转json时都会把@JsonIgnore注解的属性给忽略掉

3、@JsonProperty

默认情况下, json 中的 key 值和类中的属性名是相同的, 此注解用来重命名.

主要针对json转成pojo实例的过程

@Repository
public class Person {
    private String name;
    @JsonProperty(value = "AGE")
    private Integer age;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private Date date;
    ...
}

传出的数据age属性变成了AGE

4、@JsonSerialize

为展示的数据添加修饰器, 修饰器可自定义

可以理解为在json转成pojo实例的过程中,对一个特定的数据进行自定义的处理

创建 MySerializer.java:(用于将数据进行四舍五入并返回处理后的值)

//要增对哪个数据,就把他的类型写到这个继承类的泛型中
public class Myseralizer extends JsonSerializer<Double>{
    //在这个重写方法中处理数据
    //入参的Double value即为json中的数据,输出之后就会被用来创建实例化对象
    @Override
    public void serialize(Double value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        //四舍五入的操作
        String num = BigDecimal.valueOf(value).setScale(2,BigDecimal.ROUND_HALF_UP).toString();
        //用入参JsonGenerator gen进行输出
        //用gen的好处:可以选择不同的方法,输出不同类型的数据
        gen.writeNumber(num);
    }
}

在pojp中配置这个修饰器

@Repository
public class Person {
    private String name;
    @JsonProperty(value = "AGE")
    private Integer age;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private Date date;
    @JsonSerialize(using = Myseralizer.class)
    private Double salary;
}

control创建实例化对象给客户端也修改一下

//测试requestBody
@RequestMapping(value ="/testRequestBody")
public Person getEmployee(@RequestBody Person person){
    System.out.println(person);
    //给jsp传一个带时间的数据,观察在jsp页面会怎么处理
    Person newPerson = new Person("zuo", 56, new Date(),100000.873);
    System.out.println("-------->>"+newPerson);
    return newPerson;
}

index.jsp

var data = {name:"wang",age:"11",salary:"100000.873"};

客户端结果:(会发现数据被处理了,说明正常实例化对象数据也会被处理)

f

服务端:(会发现数据被处理了,说明json实例化对象数据也会被处理)

posted @ 2021-06-07 16:16  Coder-Wang  阅读(190)  评论(0编辑  收藏  举报