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转换为参数类

        @Override
public 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字符串转换为指定类型的更多相关文章

  1. c# 将字符串转换为指定类型的值

    private object GetValueByProperty(string key, string value, ref Type typeValue) { Type t = typeof(T) ...

  2. @ResponseBody 返回json字符串的核心类是org.springframework.http.converter.json.MappingJacksonHttpMessageConverter,它使用了Jackson 这个开源的第三方类库。主要是以下两个jar包:jackson-core-asl-1.6.4.jar;jackson-mapper-asl-1.6.4.jar

    @ResponseBody 返回json字符串的核心类是org.springframework.http.converter.json.MappingJacksonHttpMessageConvert ...

  3. JavaScript操作JSON的方法总结,JSON字符串转换为JSON对象

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是 JavaScript 原生格式,这意 ...

  4. 【荐】使用eval()、new Function()将JSON字符串转换为JSON对象

    在JS中将JSON的字符串解析成JSON数据格式,一般有两种方式: 1.一种为使用eval()函数. 2. 使用Function对象来进行返回解析. 第一种解析方式:使用eval函数来解析,并且使用j ...

  5. js 将json字符串转换为json对象的方法解析

    推荐: var obj = eval('(' + str + ')'); var last=JSON.stringify(obj); //将JSON对象转化为string字符 例如: JSON字符串: ...

  6. javaScript 将json字符串转换为json对象的方法解析

    JSON字符串: var str1 = '{ "name": "cxh", "sex": "man" }'; JSON对 ...

  7. js 将json字符串转换为json兑现

    在数据传输过程中,json是以文本,即字符串的形式传递的,而JS操作的是JSON对象,所以,JSON对象和JSON字符串之间的相互转换是关键.例如:JSON字符串:var str1 = '{ &quo ...

  8. JSON字符串转换为JSON对象

    一.JSON字符串转换为JSON对象 A:eval函数 eval函数可以直接将本质符合或者近似符合JSON格式的字符串转换为JSON对象,使用方式如: eval('(' + str + ')'); / ...

  9. Json字符串转换为java对象的各种实现方法【json_lib框架、Gson、org.json】

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://mengzhengbin520.blog.51cto.com/7590564/12 ...

随机推荐

  1. 微软BI 之SSIS 系列 - 通过 OLE DB 连接访问 Excel 2013 以及对不同 Sheet 页的数据处理

    文章更新历史 2014年9月7日 - 加入了部分更新内容,在文章最后提到了关于不同 Office Excel 版本间的连接问题. 开篇介绍 这篇文章主要总结在 SSIS 中访问和处理 Excel 数据 ...

  2. codeblocks技巧收集

    Ctrl+Shift+C  注释代码块 Ctrl+Shift+X  取消注释

  3. 基于CentOS搭建VNC远程桌面服务

    系统要求:CentOS 7.2 64 位操作系统 安装.启动 VNC VNC 远程桌面原理 名词解释: Xorg:在 Linux 用户中非常流行,已经成为图形用户程序的必备条件,所以大部分发行版都提供 ...

  4. Cortex-A15架构解析:它为什么这么强(转)

    今年的新手机趋势无异是全面向四核靠拢,不过同样是四核,在实际的性能上其实是千差万别.例如针对入门级主流市场的四核手机普遍采用的都是Cortex-A7以及 Cortex-A9 级别的CPU内核,这类内核 ...

  5. mysql8.0.11修改root密码,其他创建用户和删除用户

    1.7. 查询用户密码: 查询用户密码命令:mysql> select host,user,authentication_string from mysql.user; host: 允许用户登录 ...

  6. 一道简单的HashMap面试题所想到的...

    前言 看到一个JDK1.7和JDK1.8中关于HashMap的一个面试题: JDK1.7和1.8中HashMap中链表的插入的方式有什么不同? 原以为自己对HashMap的源码理解的还算可以了,应该足 ...

  7. 2D空间中求线段与圆的交点

    出处: https://answers.unity.com/questions/366802/get-intersection-of-a-line-and-a-circle.html 测试脚本(返回值 ...

  8. zookeeper的可视化web界面

    转载一篇我心中大神有关zookeeper  WEB的文章 以前写过一篇zookeeper集群搭建的文章<烂泥:zookeeper集群搭建>,最近在使用activemq集群过程中碰到了一些有 ...

  9. 如何生成ExecutionGraph及物理执行图

    http://chenyuzhao.me/2017/02/06/flink%E7%89%A9%E7%90%86%E8%AE%A1%E5%88%92%E7%94%9F%E6%88%90/ https:/ ...

  10. IOS开发之Core Location

    IOS 支持三种检测当前位置的方式:手机基站.Wi-Fi.和GPS,其中GPS是经度最高的,同时也是最耗费手机电量的.一般情况下在室内是无法通过GPS获 取位置信息的,通过Wi-Fi获取位置的原理是通 ...