日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于使用fastjson统一序列化响应格式。

發布時間:2024/4/13 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于使用fastjson统一序列化响应格式。 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

摘要:其實很簡單的處理方式,只不夠優雅,或者說沒有找到fastjson為其提供便捷的處理方式。因此記錄下處理該問題的過程。

目標:將所有api請求,即響應為APPLICATION_JSON的內容做統一格式處理。 例如:@RestController 標注類方法放回值為List、 Map 或PO 類 增加響應字段 status。

  • 當成功響應List 時,返回 {"data":[],"status":true}
  • 當成功響應非List時,
    • String : {"msg":"str","status":true}
    • Map: {"k1":"v1","status":true}
    • PO: {"column1":"v1","status":true}
  • 當業務不能如預期處理,即異常響應:{"msg":"異常理由","status":false}
  • 1:業務預期失敗 在spring boot中配置HandlerExceptionResolver后,即可攔截處理所有異常,在此便可處理錯誤信息的json化。

    @Component public class GlobalExceptionResolver implements HandlerExceptionResolver {@Overridepublic ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,Exception ex) {response.setStatus(getStatusCodeValue());response.setContentType(ContentType.APPLICATION_JSON.toString());response.setCharacterEncoding(Charsets.UTF_8.toString());...} }

    **2.集合情況 ** 使用ControllerAdvice注冊專用的內容攔截

    @ControllerAdvice public class ResponseResultHandler implements ResponseBodyAdvice<Object> {private static Class<?>[] types = { Iterable.class, Iterator.class };@Overridepublic boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {Class<?> clz = returnType.getMethod().getReturnType();for (Class<?> c : types) {if (c.isAssignableFrom(clz)) {return true;}}return clz.isArray();}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,ServerHttpResponse response) {Pages<?> p = Pages.builder(body);if (MediaType.TEXT_HTML.equals(selectedContentType) || MediaType.TEXT_PLAIN.equals(selectedContentType)) {if (!Stream.of(returnType.getMethod().getAnnotations()).anyMatch(a -> a instanceof RequestMapping && !Objs.isEmpty(((RequestMapping) a).produces())))response.getHeaders().setContentType(MediaType.parseMediaType(MediaType.APPLICATION_JSON_UTF8_VALUE));return JSONObject.toJSONString(p);}return p;} }

    3.基本類型,如String,Number等

    private static Class<?>[] types = { Clob.class, java.lang.CharSequence.class, java.lang.Number.class,LocalDate.class, LocalDateTime.class, LocalTime.class, java.util.Date.class, java.sql.Blob.class,java.sql.Array.class, };@Overridepublic boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {Class<?> clz = returnType.getMethod().getReturnType();for (Class<?> t : types) {if (t.isAssignableFrom(clz)) {return true;}}return false;}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,ServerHttpResponse response) {JSONObject js = new JSONObject();js.put(AppEnum.status.getValue(), true);js.put(AppEnum.message.getValue(), body);if (MediaType.TEXT_HTML.equals(selectedContentType) || MediaType.TEXT_PLAIN.equals(selectedContentType)) {if (!Stream.of(returnType.getMethod().getAnnotations()).anyMatch(a -> a instanceof RequestMapping && !Objs.isEmpty(((RequestMapping) a).produces())))response.getHeaders().setContentType(MediaType.parseMediaType(MediaType.APPLICATION_JSON_UTF8_VALUE));return js.toString();}return js;}

    4.map

    @SuppressWarnings({ "serial", "unchecked", "rawtypes" })private static final Map<Class<?>, Function<Object, Object>> types = new LinkedHashMap<Class<?>, Function<Object, Object>>() {{put(Map.class, obj -> {((Map) obj).putIfAbsent(AppEnum.status.getValue(), true);return obj;});put(org.json.JSONObject.class, obj -> {JSONObject js = (JSONObject) obj;if (!js.containsKey(AppEnum.status.getValue()))js.put(AppEnum.status.getValue(), true);return js;});}};@Overridepublic boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {Class<?> clz = returnType.getMethod().getReturnType();if (types.containsKey(clz))return true;for (Class<?> c : types.keySet()) {if (c.isAssignableFrom(clz)) {return true;}}return false;}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,ServerHttpResponse response) {body = types.get(returnType.getMethod().getReturnType()).apply(body);if (MediaType.TEXT_HTML.equals(selectedContentType) || MediaType.TEXT_PLAIN.equals(selectedContentType)) {if (!Stream.of(returnType.getMethod().getAnnotations()).anyMatch(a -> a instanceof RequestMapping && !Objs.isEmpty(((RequestMapping) a).produces())))response.getHeaders().setContentType(MediaType.parseMediaType(MediaType.APPLICATION_JSON_UTF8_VALUE));return JSONObject.toJSONString(body);}return body;}

    5.javabean

    @Overridepublic boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {return ParserConfig.global.getDeserializer(returnType.getMethod().getReturnType()) instanceof JavaBeanDeserializer;}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,ServerHttpResponse response) {BeanGenerator bg = new BeanGenerator();bg.setSuperclass(body.getClass());bg.addProperty("status", Boolean.class);Object obj = bg.create();BeanUtil.beanCopier(obj, body);try {BeanUtils.setProperty(obj, "status", true);} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}if (MediaType.TEXT_HTML.equals(selectedContentType) || MediaType.TEXT_PLAIN.equals(selectedContentType)) {if (!Stream.of(returnType.getMethod().getAnnotations()).anyMatch(a -> a instanceof RequestMapping && !Objs.isEmpty(((RequestMapping) a).produces())))response.getHeaders().setContentType(MediaType.parseMediaType(MediaType.APPLICATION_JSON_UTF8_VALUE));return JSONObject.toJSONString(obj);}return obj;}

    對于javabean。之前采用的是fastjson的BeforeFilter,但有個問題,在JavaBeanSerializer會重復的對javaBean對象進行序列化,這會導致除了在最外層的javaBean 中添加status外,還會導致所有的javaBean都被添加。因此后續改成了通過net.sf.cglib.beans.BeanGenerator 對javaBean 進行代理。

    注意:不要單獨使用Enhancer代理,在com.alibaba.fastjson.serializer.SerializeConfig中:會對代理類進行解析。

    private ObjectSerializer getObjectWriter(Class<?> clazz, boolean create) {if (TypeUtils.isProxy(clazz)) {Class<?> superClazz = clazz.getSuperclass();ObjectSerializer superWriter = getObjectWriter(superClazz);put(clazz, superWriter);return superWriter;}if (Proxy.isProxyClass(clazz)) {Class handlerClass = null;if (interfaces.length == 2) {handlerClass = interfaces[1];} else {for (Class proxiedInterface : interfaces) {if (proxiedInterface.getName().startsWith("org.springframework.aop.")) {continue;}if (handlerClass != null) {handlerClass = null; // multi-matchedbreak;}handlerClass = proxiedInterface;}}if (handlerClass != null) {ObjectSerializer superWriter = getObjectWriter(handlerClass);put(clazz, superWriter);return superWriter;}}//------------- //TypeUtilspublic static boolean isProxy(Class<?> clazz){for(Class<?> item : clazz.getInterfaces()){String interfaceName = item.getName();if(interfaceName.equals("net.sf.cglib.proxy.Factory") //|| interfaceName.equals("org.springframework.cglib.proxy.Factory")){return true;}if(interfaceName.equals("javassist.util.proxy.ProxyObject") //|| interfaceName.equals("org.apache.ibatis.javassist.util.proxy.ProxyObject")){return true;}}return false;}

    轉載于:https://my.oschina.net/yuyizyk/blog/2236836

    總結

    以上是生活随笔為你收集整理的关于使用fastjson统一序列化响应格式。的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。