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. Aspose.Cells设置单元格格式

    使用Aspose.Cells操作Excel时,填写的参数是这样的,显然要不得! 这需要像Excel中的“转换为数字”操作,强大的Aspose.Cells可轻松解决这个问题. //默认写法 worksh ...

  2. PowerShell使用ServicePrincipal登陆Azure

    一.打开PowerShell 二.输入下列命令 $pass = ConvertTo-SecureString "<这里换成您的AAD应用密钥>" -AsPlainTex ...

  3. linux 删除换行符

    今天需要删除文件里面的换行符,比如有一个文件a.txt: 1,2,3 4,5,6 1,2,3 4,5,6 1,2,3 4,5,6 1,2,3 4,5,6 1,2,3 4,5,6 1.使用vim删除换行 ...

  4. Remmina剪切板不正常的问题

    引用:http://forum.ubuntu.org.cn/viewtopic.php?f=73&p=3135388&sid=399b5566833c294045795a4b328fb ...

  5. 【PMP】项目和运营的区别

    运营管理关注产品的持续性生产和服务的持续运作. 项目与运营会存在产品生命周期的不同时点交叉,例如: 在产品开发.产品升级或提高产量时: 在改进运营或产品开发流程时: 在产品生命周期结束阶段: 在每个收 ...

  6. UICollectionView在初始化的时候移动到某个距离

    #pragma mark  -- 使用场景:选中非第一张图片用CollectionView进行浏览时,CollectionView滑动到对应的位置 #pragma mark  -- 重点在于UICol ...

  7. HTML5手机页面里面如何把长按复制避免

    在写HTML5手机页面的时候,有时候会写到一些标签是需要用户长按然后放开的 但是微信里面长按就会出现复制,大大影响了用户体验,那么如何可以避免呢? 我也是最近写到这样的页面,总结了一部分,大家可以作为 ...

  8. 对于移动端 App,虚拟机注册或类似作弊行为有何应对良策?

    1.APP攻击大致策略 对APP进行攻击的一般思路包括反编译APP代码.破解APP通讯协议.安装虚拟机自动化模拟: a.首先看能否反编译APP代码(例如Android APP),如果能够反编译,从代码 ...

  9. 【Android】GPS定位基本原理浅析

    位置服务已经成为越来越热的一门技术,也将成为以后所有移动设备(智能手机.掌上电脑等)的标配.而定位导航技术中,目前精度最高.应用最广泛的,自然非GPS莫属了.网络上介绍GPS原理的专业资料很多,而本文 ...

  10. java 生成Http 头部date格式的string-RFC 1123 Date Representation in java

    https://blog.csdn.net/lvzhuyiyi/article/details/51770148 ******************************************* ...