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. haproxy负载均衡的安装配置

    haproxy是一款可靠,高性能的并且可以支持TCP/HTTP的负载均衡器,和前面说过的nginx负载均衡类似,这里haproxy对于负载均衡来说更专业,支持的配置选项更多,稳定性也很强,甚至只需要一 ...

  2. ios NSURLSession后台传输

    http://www.appcoda.com/background-transfer-service-ios7/ http://www.raywenderlich.com/51127/nsurlses ...

  3. FTP上传、下载(简单小例子)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.I ...

  4. [k8s]jenkins部署在k8s集群

    $ cat jenkins-pvc.yaml kind: PersistentVolumeClaim apiVersion: v1 metadata: name: jenkins-pvc spec: ...

  5. 物联网架构成长之路(6)-EMQ权限控制

    1. 前言 EMQTT属于一个比较小众的开源软件,很多资料不全,很麻烦,很多功能都是靠猜测,还有就是看官方提供的那几个插件,了解. 2. 说明 上一小节的插件 emq_plugin_wunaozai ...

  6. windows下安装pycharm并连接Linux的python环境

    1. 下载安装Pycharm专业版 具体方法略.Pycharm5激活方法参考http://www.cnblogs.com/snsdzjlz320/p/7110186.html 2. 添加配置连接远程服 ...

  7. linux每日命令(38):iostat命令

    Linux系统中的 iostat是I/O statistics(输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动进行监视.它的特点是汇报磁盘活动统计情况,同时也会汇报出CPU使用情况.同 ...

  8. Extjs4.2x与富文本框编辑器KindEditor的整合

    Extjs4本身的HtmlEditor编辑器,太鸡肋了,简单的html能够应付一下,稍加复杂的就无能为力了. 对于Extjs的HtmlEditor扩展主要有三个方向,一个是扩展其本身的htmlEdit ...

  9. 重新入坑-IntelliJ Maven

    写Restful的服务,使用IntelliJ+maven,发现有几个依赖总是没法配置好.通过检查POM.xml,发现犯了错误,<dependency>写到了<dependencies ...

  10. ubuntu将GNU nano换成vim

    ubuntu默认编辑器为gnu nano,使用方法是ctrl+字母键 但是gnu nano没有vim好用,我们把它切换到vim 在终端下输入以下命令 sudo update-alternatives ...