分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 教程案例

如何实现@ResponseBody,把Json字符串转换为指定类型

发布时间:2023-09-06 02:09责任编辑:熊小新关键词:暂无标签

1.问题

spring 是如何把 http中的body,转换为指定类的,里面的难点其实在于泛型的处理。

2.Spring的处理

2.1 HandlerMethod

这个类Spring对Method的封装,例如使用@RequestMapping注解方法,会使用HandlerMethod封装(其实是其子类InvocableHandlerMethod)。然后由InvocableHandlerMethod对其进行调用

HandlerMethod的属性如下

private final Object bean;private final BeanFactory beanFactory;private final Class<?> beanType;private final Method method;private final Method bridgedMethod;private final MethodParameter[] parameters; //重点是这个private HttpStatus responseStatus;private String responseStatusReason;private HandlerMethod resolvedFromHandlerMethod;

  

2.2 如何解析参数的

参考InvocableHandlerMethod的getMethodArgumentValues的方法,其中会使用各种HandlerMethodArgumentResolver 对Spring mvc调用参数解析

例如,路径的中的参数 /path/${var} 使用的PathVariableMapMethodArgumentResolver 相关注解 @PathVariable

例如,header中的参数 使用 RequestHeaderMapMethodArgumentResolver 来解析,相关注解@RequestHeader

那么@ResponseBody使用的RequestResponseBodyMethodProcessor来解析的,

2.3 如何把body转换为参数类

 ???????@Overridepublic Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {parameter = parameter.nestedIfOptional();Object arg = readWithMessageConverters(webRequest, parameter, parameter.getNestedGenericParameterType());....return adaptArgumentIfNecessary(arg, parameter);}

 其中readWithMessageConverters方法是重点,注意MethodParameter其实就是HandlerMethod中的属性

继续往里面跳

GenericHttpMessageConverter<?> genericConverter = (GenericHttpMessageConverter<?>) converter;
...
body = genericConverter.read(targetType, contextClass, inputMessage);

 其中上面的那段代码就是读取http的body,并转换为指定类。我们就拿常见Fastjson的FastJsonHttpMessageConverter中的代码来看,很简单

 ???public Object read(Type type, // ??????????????????????Class<?> contextClass, // ??????????????????????HttpInputMessage inputMessage // ???) throws IOException, HttpMessageNotReadableException { ???????return readType(getType(type, contextClass), inputMessage); ???} ???private Object readType(Type type, HttpInputMessage inputMessage) throws IOException { ???????try { ???????????InputStream in = inputMessage.getBody(); ???????????return JSON.parseObject(in, fastJsonConfig.getCharset(), type, fastJsonConfig.getFeatures()); ???????} catch (JSONException ex) { ???????????throw new HttpMessageNotReadableException("JSON parse error: " + ex.getMessage(), ex); ???????} catch (IOException ex) { ???????????throw new HttpMessageNotReadableException("I/O error while reading input message", ex); ???????} ???}

3 如何自己实现

通过上面的分析,如何实现一个简单的数据mock回放,(假设的我们mock的数据使用json来存储的)

 // 第一步:创建一个HandlerMethod ?HandlerMethod handlerMethod = new HandlerMethod(bean, method); // 第二步:获取返回类型的MethodParameter MethodParameter methodParameter = handlerMethod.getReturnType().nestedIfOptional(); // 第三步:使用Fastjson反序列化 JSONObject.parseObject(phxResult.getVal(), methodParameter.getNestedGenericParameterType());//注,bean是调用的类的实例,method是通过反射获取的具体调用方法,怎么获取不是这里的重点,省略掉获取

  

如何实现@ResponseBody,把Json字符串转换为指定类型

原文地址:https://www.cnblogs.com/lizo/p/spring.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved