前言
再用Spring/SpringBoot做API输出的时候,最多用到的是Json格式的了。为了简单高效,我们并不希望每次在输出的时候,自己去拼接JSON,或者用JSON工具类去格式化转成Json的String输出,最好是直接返回一个对象,自动输出为String,我们还可能需要将Date类型的Object转成格式化过的日期例如:2021-02-26 09:02:01
或者将org.json.JSONObject
org.json.JSONString
等其他自定义的Object也转成JsonString
例如,我们定义这样一个对象:
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:
@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"}
分别对Spring和SpringBoot进行配置(两者大同小异)
Spring的配置
这就需要用到 jackson
了
POM引入jackson相关类库:
<!-- 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"> <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 ... registerModule(module); } }
看下CustDateSerializer.java
CustJsonSerializer.java
CustJsonArraySerializer
我把3个java写在一起了,如有需要复制,请写到3个不同的java文件里,其他自定义的,按照规律写。
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的文件,那就不需要新建,直接在已有的文件下配置)
@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