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. 反向代理WebSocket连接自动断掉的问题

    Nginx可能设置了超时时间,导致WebSocket一会儿就断了 解决方法: 1.增加Nginx配置 proxy_read_timeout 500s; 注:三种超时时间,参见 https://www. ...

  2. docker安装hive笔记

    前两篇文章介绍了docker的基本命令如何安装hadoop 那么大家会比较了解docker的基本语法的安装过程.那么咱们今天来一起安装一下hive. 安装 1.下载gitHub,地址:https:// ...

  3. android中Textview 和图片同时显示时,文字省略号显示,图片自动靠到右边

    很纠结的一个标题,实在是不知道怎么去描述这个现象. 上图片吧,先看看需求是什么样的. 1.需求: ​ 视频与票的图标跟在标题后面显示,当标题过长时icon显示到省略号…后(textview省略号显示, ...

  4. windows下vbs脚本隐藏控制台

    每次想写python代码时,都需要打开IDE进行编写,并且需要创建许多小文件.如果使用jupyter就能够直接书写.但是jupyter需要手动通过控制台打开,这不够方便.通过把jupyter note ...

  5. 【Visual Studio】Visual Studio对CLR异常的特殊支持

    Visual Studio 对异常进行了特殊的支持,它能够在进行了特殊设置后,使代码中的try catch块失效.也就是说,一个异常在正常情况下应该能够被某个特殊的try catch块捕获,但是Vis ...

  6. aaronyang的百度地图API之LBS云与.NET开发 Javascript API 2.0【把数据存到LBS云2/2】

    中国的IT 需要无私分享和贡献的人,一起努力 本篇博客来自地址:http://www.cnblogs.com/AaronYang/p/3672898.html,请支持原创,未经允许不许转载 1.新建一 ...

  7. Effective Java 第三版——61. 基本类型优于装箱的基本类型

    Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...

  8. 使用DIV弹出框的代码示例,备忘。

    1.思路 使用DIV模拟弹出框,一共用三个div: divWindow: 原来的界面内容区域 divLogin:要弹出的内容区域 divBackground:给弹出内容区域做个遮罩的区域. 点击 “请 ...

  9. linux设置开机自启动

    一..在/etc/rc.local文件中添加自启动命令 执行命令: 编辑"/etc/rc.local",添加你想开机运行的命令 运行程序脚本:然后在文件最后一行添加要执行程序的全路 ...

  10. [转]bootstrap table 动态列数

    原文地址:https://my.oschina.net/u/2356355/blog/1595563 据说bootstrap table非常好用,从入门教程中了解到它的以下主要功能: 由于固定表头意味 ...