前言
再用Spring/SpringBoot做API输出的时候,最多用到的是Json格式的了。为了简单高效,我们并不希望每次在输出的时候,自己去拼接JSON,或者用JSON工具类去格式化转成Json的String输出,最好是直接返回一个对象,自动输出为String,我们还可能需要将Date类型的Object转成格式化过的日期例如:
2021-02-26 09:02:01
2021-02-26 09:02:01
或者将
org.json.JSONObject
org.json.JSONObject
org.json.JSONString
org.json.JSONString
等其他自定义的Object也转成JsonString
例如,我们定义这样一个对象:
public class JsonResult {
private boolean result = false;
private String ingored; // 如果有不需要输出的字段,用JsonIgnore
private HashMap<String, Object> extra = new HashMap<String, Object>();
public JsonResult(boolean result, String message) {
public JsonResult(boolean result) {
public HashMap<String, Object> getExtra() {
public void setExtra(HashMap<String, Object> extra) {
public boolean isResult() {
public void setResult(boolean result) {
public String getMessage() {
public void setMessage(String message) {
public void addExtra(String key, Object value) {
this.extra.put(key, value);
* @description 可以在这里用注解来让他特意生成时间格式,或者spring-servlet.xml中去配置ObjectMapper
@JsonSerialize(using = CustDateSerializer.class)
public static JsonResult success(String message) {
return new JsonResult(true, message);
public static JsonResult success() {
return new JsonResult(true, "OK");
public static JsonResult fail(String message) {
return new JsonResult(false, message);
public class JsonResult {
private boolean result = false;
private String message;
@JsonIgnore
private String ingored; // 如果有不需要输出的字段,用JsonIgnore
private HashMap<String, Object> extra = new HashMap<String, Object>();
public JsonResult(boolean result, String message) {
this.result = result;
this.message = message;
}
public JsonResult(boolean result) {
this.result = result;
}
public JsonResult() {
}
public HashMap<String, Object> getExtra() {
return extra;
}
public void setExtra(HashMap<String, Object> extra) {
this.extra = extra;
}
public boolean isResult() {
return result;
}
public void setResult(boolean result) {
this.result = result;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void addExtra(String key, Object value) {
this.extra.put(key, value);
}
/**
* @return
* @description 可以在这里用注解来让他特意生成时间格式,或者spring-servlet.xml中去配置ObjectMapper
*/
@JsonSerialize(using = CustDateSerializer.class)
public Date getTime() {
return new Date();
}
public static JsonResult success(String message) {
return new JsonResult(true, message);
}
public static JsonResult success() {
return new JsonResult(true, "OK");
}
public static JsonResult fail(String message) {
return new JsonResult(false, message);
}
}
public class JsonResult {
private boolean result = false;
private String message;
@JsonIgnore
private String ingored; // 如果有不需要输出的字段,用JsonIgnore
private HashMap<String, Object> extra = new HashMap<String, Object>();
public JsonResult(boolean result, String message) {
this.result = result;
this.message = message;
}
public JsonResult(boolean result) {
this.result = result;
}
public JsonResult() {
}
public HashMap<String, Object> getExtra() {
return extra;
}
public void setExtra(HashMap<String, Object> extra) {
this.extra = extra;
}
public boolean isResult() {
return result;
}
public void setResult(boolean result) {
this.result = result;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void addExtra(String key, Object value) {
this.extra.put(key, value);
}
/**
* @return
* @description 可以在这里用注解来让他特意生成时间格式,或者spring-servlet.xml中去配置ObjectMapper
*/
@JsonSerialize(using = CustDateSerializer.class)
public Date getTime() {
return new Date();
}
public static JsonResult success(String message) {
return new JsonResult(true, message);
}
public static JsonResult success() {
return new JsonResult(true, "OK");
}
public static JsonResult fail(String message) {
return new JsonResult(false, message);
}
}
在Controller中,我们希望直接return JsonResult:
public @ResponseBody JsonResult ping(HttpServletRequest request) {
org.json.JSONObject pingResult = new org.json.JSONObject();
pingResult.put("xxx", "xxx");
JsonResult result = new JsonResult(true, "Ping Response OK");
result.addExtra("stats", pingResult);
@RequestMapping("/ping")
public @ResponseBody JsonResult ping(HttpServletRequest request) {
org.json.JSONObject pingResult = new org.json.JSONObject();
pingResult.put("xxx", "xxx");
JsonResult result = new JsonResult(true, "Ping Response OK");
result.addExtra("stats", pingResult);
return result;
}
@RequestMapping("/ping")
public @ResponseBody JsonResult ping(HttpServletRequest request) {
org.json.JSONObject pingResult = new org.json.JSONObject();
pingResult.put("xxx", "xxx");
JsonResult result = new JsonResult(true, "Ping Response OK");
result.addExtra("stats", pingResult);
return result;
}
客户端请求到的直接是JsonResult序列化成json的string
{"result":true,"message":"Ping Response OK","extra":{"stats":{"xxx":"xxx"}},"time":"2021-02-26 09:02:01"}
{"result":true,"message":"Ping Response OK","extra":{"stats":{"xxx":"xxx"}},"time":"2021-02-26 09:02:01"}
{"result":true,"message":"Ping Response OK","extra":{"stats":{"xxx":"xxx"}},"time":"2021-02-26 09:02:01"}
分别对Spring和SpringBoot进行配置(两者大同小异)
Spring的配置
这就需要用到
jackson
jackson
了
POM引入jackson相关类库:
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.12.1</version>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-joda</artifactId>
<version>2.12.1</version>
<!-- org.json看你是否需要,按需要引入-->
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20200518</version>
<!-- json -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.12.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-joda</artifactId>
<version>2.12.1</version>
</dependency>
<!-- org.json看你是否需要,按需要引入-->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20200518</version>
</dependency>
<!-- json -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.12.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-joda</artifactId>
<version>2.12.1</version>
</dependency>
<!-- org.json看你是否需要,按需要引入-->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20200518</version>
</dependency>
修改spring-servlet.xml,增加自定义的message-converter,以及实现自定义的 CustomObjectMapper
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<bean class="org.springframework.http.converter.StringHttpMessageConverter" />
<bean class="org.springframework.http.converter.ResourceHttpMessageConverter" />
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="customObjectMapper" />
</mvc:message-converters>
<bean id="customObjectMapper" class="com.terrynow.test.util.CustomObjectMapper"/>
<!-- 把标记了@Controller注解的类转换为bean -->
<context:component-scan base-package="com.terrynow.test.controller" />
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter" />
<bean class="org.springframework.http.converter.ResourceHttpMessageConverter" />
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="customObjectMapper" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="customObjectMapper" class="com.terrynow.test.util.CustomObjectMapper"/>
<!-- 把标记了@Controller注解的类转换为bean -->
<context:component-scan base-package="com.terrynow.test.controller" />
<!-- 其他配置省略 -->
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter" />
<bean class="org.springframework.http.converter.ResourceHttpMessageConverter" />
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="customObjectMapper" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="customObjectMapper" class="com.terrynow.test.util.CustomObjectMapper"/>
<!-- 把标记了@Controller注解的类转换为bean -->
<context:component-scan base-package="com.terrynow.test.controller" />
<!-- 其他配置省略 -->
</beans>
看下CustomObjectMapper.java 实现自定义的Object转成JsonString的规则,这里我让Date、JSONObject、JSONArray 转成JsonString
public class CustomObjectMapper extends ObjectMapper {
private static final long serialVersionUID = -8859083943056178252L;
public CustomObjectMapper() {
this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
this.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
SimpleModule module = new SimpleModule("JSONModule", new Version(2, 0, 0, null, null, null));
module.addSerializer(Date.class, new CustDateSerializer());
module.addSerializer(JSONObject.class, new CustJsonSerializer());
module.addSerializer(JSONArray.class, new CustJsonArraySerializer());
// 按照上面的格式,增加其他Object转JsonString ...
public class CustomObjectMapper extends ObjectMapper {
private static final long serialVersionUID = -8859083943056178252L;
public CustomObjectMapper() {
this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
this.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
SimpleModule module = new SimpleModule("JSONModule", new Version(2, 0, 0, null, null, null));
module.addSerializer(Date.class, new CustDateSerializer());
module.addSerializer(JSONObject.class, new CustJsonSerializer());
module.addSerializer(JSONArray.class, new CustJsonArraySerializer());
// 按照上面的格式,增加其他Object转JsonString ...
registerModule(module);
}
}
public class CustomObjectMapper extends ObjectMapper {
private static final long serialVersionUID = -8859083943056178252L;
public CustomObjectMapper() {
this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
this.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
SimpleModule module = new SimpleModule("JSONModule", new Version(2, 0, 0, null, null, null));
module.addSerializer(Date.class, new CustDateSerializer());
module.addSerializer(JSONObject.class, new CustJsonSerializer());
module.addSerializer(JSONArray.class, new CustJsonArraySerializer());
// 按照上面的格式,增加其他Object转JsonString ...
registerModule(module);
}
}
看下
CustDateSerializer.java
CustDateSerializer.java
CustJsonSerializer.java
CustJsonSerializer.java
CustJsonArraySerializer
CustJsonArraySerializer
我把3个java写在一起了,如有需要复制,请写到3个不同的java文件里,其他自定义的,按照规律写。
public class CustDateSerializer extends JsonSerializer<Date> {
public void serialize(Date value, JsonGenerator jsonGenerator,
SerializerProvider provider) throws IOException {
jsonGenerator.writeString(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(value));
public class CustJsonSerializer extends JsonSerializer<JSONObject> {
public void serialize(JSONObject json, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeObject(new ObjectMapper().readTree(json.toString()));
public class CustJsonArraySerializer extends JsonSerializer<JSONArray> {
public void serialize(JSONArray json, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeObject(new ObjectMapper().readTree(json.toString()));
public class CustDateSerializer extends JsonSerializer<Date> {
@Override
public void serialize(Date value, JsonGenerator jsonGenerator,
SerializerProvider provider) throws IOException {
// 按照这样的格式,输出String
jsonGenerator.writeString(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(value));
}
}
public class CustJsonSerializer extends JsonSerializer<JSONObject> {
@Override
public void serialize(JSONObject json, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeObject(new ObjectMapper().readTree(json.toString()));
}
}
public class CustJsonArraySerializer extends JsonSerializer<JSONArray> {
@Override
public void serialize(JSONArray json, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeObject(new ObjectMapper().readTree(json.toString()));
}
}
public class CustDateSerializer extends JsonSerializer<Date> {
@Override
public void serialize(Date value, JsonGenerator jsonGenerator,
SerializerProvider provider) throws IOException {
// 按照这样的格式,输出String
jsonGenerator.writeString(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(value));
}
}
public class CustJsonSerializer extends JsonSerializer<JSONObject> {
@Override
public void serialize(JSONObject json, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeObject(new ObjectMapper().readTree(json.toString()));
}
}
public class CustJsonArraySerializer extends JsonSerializer<JSONArray> {
@Override
public void serialize(JSONArray json, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeObject(new ObjectMapper().readTree(json.toString()));
}
}
SpringBoot的配置
SpringBoot 可以不用在pom.xml 引入jackson (默认已经引入,org.json看你需要,按需引入),自定义的HttpMessageConverter需要配置
新建MyConfiguration extends WebMvcConfigurerAdapter (如果已经有继承WebMvcConfigurerAdapter的文件,那就不需要新建,直接在已有的文件下配置)
public class MyConfiguration extends WebMvcConfigurerAdapter {
@Bean(name = "jsonMapper")
public ObjectMapper jsonMapper() {
return new CustomObjectMapper();
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new MappingJackson2HttpMessageConverter(jsonMapper()));
super.configureMessageConverters(converters);
@Configuration
public class MyConfiguration extends WebMvcConfigurerAdapter {
@Bean(name = "jsonMapper")
@Primary
public ObjectMapper jsonMapper() {
return new CustomObjectMapper();
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new MappingJackson2HttpMessageConverter(jsonMapper()));
super.configureMessageConverters(converters);
}
}
@Configuration
public class MyConfiguration extends WebMvcConfigurerAdapter {
@Bean(name = "jsonMapper")
@Primary
public ObjectMapper jsonMapper() {
return new CustomObjectMapper();
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new MappingJackson2HttpMessageConverter(jsonMapper()));
super.configureMessageConverters(converters);
}
}
CustomObjectMapper.java 的内容,就和上面Spring里一样了,这里就不写了,有需要的,直接抄上面的。
文章评论
cialis sale uk Vwhoiy - Cialis Ftuxvp Pisobi Ozboez levitra 10 mg orange Aubvfb - cialis 40 mg