Java使用controller发送请求接收返回json并解决中文乱码和日期格式化

464 阅读6分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第28天,点击查看活动详情

controller发送请求接收返回json

现在两大转换json第三方工具主流就是jackson和fastjson(阿里巴巴)

1 引入jackson依赖(jar包)



 <!--jackson依赖 用来转化json-->

<dependency>

    <groupId>com.fasterxml.jackson.core</groupId>

    <artifactId>jackson-databind</artifactId>

    <version>2.9.8</version>

</dependency>





<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-web</artifactId>

    <version>2.3.0.RELEASE</version>

</dependency>

2 创建实体和controller

实体代码如下 toString 无参无参构造 getset

package com.wyh.entity;



 /**

 *  @program:  SpringBoot-Ajax-JSON

 *  @description:  User实体类

 *  @author:  魏一鹤

 *  @createDate:  2022-02-07 21:45

 **/



public class User {

    private String name;

    private int age;



    public User() {

    }



    @Override

    public String toString() {

        return "User{" +

                "name='" + name + ''' +

                ", age=" + age +

                ", sex='" + sex + ''' +

                '}' ;

    }



    public User(String name, int age, String sex) {

        this.name = name;

        this.age = age;

        this.sex = sex;

    }



    public String getName() {

        return name;

    }



    public void setName(String name) {

        this.name = name;

    }



    public int getAge() {

        return age;

    }



    public void setAge(int age) {

        this.age = age;

    }



    public String getSex() {

        return sex;

    }



    public void setSex(String sex) {

        this.sex = sex;

    }



    private String sex;

}

3 创建controller并且写方法请求并使用jackson进行json格式转化

@ResponseBody注解是spring提供的,直接处理返回JSON字符串就行

jackson主要处理对象的JSON数据格式

JSON对象数据格式,以"[]"进行包裹,每个对象用","进行分隔并且用"{}"括起来,最后一个数据没有","分隔

[{"name":"魏一鹤","age":1,"sex":"男"},{"name":"杨玉婷","age":2,"sex":"女"}]

package com.wyh.controller;



import com.fasterxml.jackson.core.JsonProcessingException;

import com.fasterxml.jackson.databind.ObjectMapper;

import com.wyh.entity.User;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;



 /**

 *  @program:  SpringBoot-Ajax-JSON

 *  @description:  用户中心控制器 返回接收JSON格式的数据

 *  @author:  魏一鹤

 *  @createDate:  2022-02-07 21:44

 **/

@Controller

public class UserController {

    //现在两大转换json第三方工具主流就是jackson和fastjson(阿里巴巴)

 //如果出现乱码,我们需要设置他的编码格式为utf-8,以及它返回的类型,通过@RequesMapping的produces属性来实现

    //produces:指定响应体返回类型和编码

 @RequestMapping(value = "/json1" ,produces = "application/json;charset=utf-8" )

    //正常返回的话会走视图解析器,但是json需要返回的是字符串,使用@ResponseBody就能完美解决

 @ResponseBody //响应 返回json格式的数据 将服务器端返回的对象转换为json对象响应回去

 //@RequestBody //接收 接收json格式的数据 将客户端返回的对象转换为json进行接收

  public String  json1() throws JsonProcessingException {

        //需要一个jackson的对象映射器 其实就是一个类 ObjectMapper 使用它可以直接将对象转换为json字符串

 ObjectMapper objectMapper = new ObjectMapper();

        //创建一个对象

 User user=new User( "魏一鹤" ,1, "男" );

        //输出Java对象

 System.out.println( "Java对象" +user);

        //将Java对象转换为JSON字符串 使用writeValueAsString方法把实体放进去即可转化json字符串 需要抛出异常

 String JSONUser = objectMapper.writeValueAsString(user);

        //输出JSON字符串

 System.out.println( "JSON字符串" +JSONUser);

        //由于使用了@ResponseBody注解 这里会将JSONUser以JSON字符串的格式直接返回 十分方便

  return JSONUser;

    }

}









@RequestMapping(value = "/json2" )

@ResponseBody

public String json2() throws JsonProcessingException {

    List<User> list=new ArrayList<>();

    User user1=new User( "魏一鹤" ,1, "男" );

    User user2=new User( "杨玉婷" ,2, "女" );

    list.add(user1);

    list.add(user2);

    ObjectMapper objectMapper = new ObjectMapper();

    String strJSON = objectMapper.writeValueAsString(list);

    return strJSON;

}

测试发现正常返回json字符串

输出如下

Java对象User{name='魏一鹤', age=1, sex='男'}

JSON字符串{"name":"魏一鹤","age":1,"sex":"男"}

项目启动保错(jackson版本问题导致项目启动失败)

出现这个错误是因为jackson依赖和springboot依赖版本有冲突,把jsckson的依赖版本从2.9.8换成 2.11.0即可

JSON中文乱码

如果出现乱码,我们需要设置他的编码格式为utf-8,以及它返回的类型,通过@RequesMapping的produces属性来实现,代码如下

produces:指定响应体返回类型和编码

@RequestMapping(value = "/json1" ,produces = "application/json;charset=utf-8" )

JSON处理Date格式

@RequestMapping(value = "/date1" )

@ResponseBody

public String date1() throws JsonProcessingException {

    //声明时间日期 注意是util下的

 Date date = new Date();

    //打印默认时间日期格式  Tue Feb 08 21:36:27 CST 2022

 System.out.println(date);

    //发现问题  时间默认返回的json字符串变成了时间戳类型的格式 Timestamp 1644327387386

  return   new ObjectMapper().writeValueAsString(date);

}

发现问题:时间默认返回的json字符串变成了时间戳类型的格式 Timestamp 1644327387386

处理问题:如何让它不返回时间戳?如何时间格式化问题

//关闭ObjectMapper的时间戳功能 通过objectMapper的configure方法关闭时间戳功能

**ObjectMapper objectMapper=new ObjectMapper();

objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);

**SimpleDateFormat simpleDateFormat = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );

**objectMapper.setDateFormat(simpleDateFormat);



@RequestMapping(value = "/date2" )

@ResponseBody

public String date2() throws JsonProcessingException {

     //1 如何让它不返回时间戳?   通过objectMapper的configure方法关闭时间戳功能

 ObjectMapper objectMapper=new ObjectMapper();

    objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);

     //2 时间格式化问题 自定义日期格式对象

 SimpleDateFormat simpleDateFormat = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );

     //3 让objectMapper指定日期格式为simpleDateFormat

 objectMapper.setDateFormat(simpleDateFormat);

    //声明Date

 Date date = new Date();

    //格式化日期并输出

    System.out.println(simpleDateFormat.format(date));//2022-02-08 22:01:12

    return objectMapper.writeValueAsString(date);//"2022-02-08 22:01:12"

}
  1. 封装JSON工具日期转化工具类

上述代码冗余 我们把公共代码提取出来进行封装成工具类,下次使用直接调用即可

工具类和公共方法

package com.wyh.util;



import com.fasterxml.jackson.core.JsonProcessingException;

import com.fasterxml.jackson.databind.ObjectMapper;

import com.fasterxml.jackson.databind.SerializationFeature;



import java.util.Date;

import java.text.SimpleDateFormat;



 /**

 *  @program:  SpringBoot-Ajax-JSON

 *  @description:  JSON日期格式化封装类

 *  @author:  魏一鹤

 *  @createDate:  2022-02-08 22:07

 **/

public class JSONDateUtil {



    //重载 把时间戳也进行封装

 //如果没有自定义时间格式的话就使用我们默认的yyyy-MM-dd HH:mm:ss"

 //如果调用方法在参数列表指明了自定义时间格式的话就使用参数列表的时间格式

  public static String JSONFormatDateUtil(Object object){

        return JSONFormatDateUtil(object, "yyyy-MM-dd HH:mm:ss" );

    }





    // JSON转换日期的公共方法,直接传递Date类型的参数使用ObjectMapper进行处理 需要抛出异常 得到格式化好之后的json日期类型

 // 把方法用static进行修饰是为了不用创建工具类对象就能直接通过“.”进行公共方法的调用

  public static String JSONFormatDateUtil(Object object,String dateFormat){

        //1 创建ObjectMapper工具类

 ObjectMapper objectMapper=new ObjectMapper();

        //2 通过ObjectMapper类的configure方法关闭时间戳功能

 objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);

        //3 创建时间格式化SimpleDateFormat类 自定义日期格式对象

 SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);

        //4 把自定义格式化好之后的日期类型给objectMapper的setDateFormat去用,用来转换时间格式

 objectMapper.setDateFormat(simpleDateFormat);

        //5 json转换时间格式得到json字符串日期类型

 //封装的时候尽量不要抛异常而是捕获异常 不然每次调用这个方法都要在其他地方进行抛异常

 String JSONDate = null;

        try {

            JSONDate = objectMapper.writeValueAsString(object);

        } catch (JsonProcessingException e) {

            e.printStackTrace();

        }

        //6 返回最终处理好的json字符串日期类型

  return JSONDate;

    }

}

使用工具类和公共方法

注意观察JSONDateUtil.JSONFormatDateUtil()的参数列表和返回的格式



   //使用工具类和公共方法

 @RequestMapping(value = "/date3" )

    @ResponseBody

    public String date3()  {

        //声明Date

 Date date = new Date();

        //使用工具类的公共方法把date进行传参转换格式

 String JSONDate = JSONDateUtil.JSONFormatDateUtil(date);

        //返回json日期类型

  return JSONDate; //"2022-02-08 22:31:11"

    }

}







 //使用工具类

@RequestMapping(value = "/date3" )

@ResponseBody

public String date3()  {

    //声明Date

 Date date = new Date();

    //使用工具类的公共方法把date进行传参转换格式

 String JSONDate = JSONDateUtil.JSONFormatDateUtil(date, "yyyy" ); 

    //返回json日期类型

  return JSONDate; //"2022"

}



 //使用工具类

@RequestMapping(value = "/date3" )

@ResponseBody

public String date3()  {

    //声明Date

 Date date = new Date();

    //使用工具类的公共方法把date进行传参转换格式

 String JSONDate = JSONDateUtil.JSONFormatDateUtil(date, "yyyy-MM-dd" );

    //返回json日期类型

  return JSONDate;  //"2022-02-08"

}