• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Java > SpringMVC解析JSON请求数据问题解析

SpringMVC解析JSON请求数据问题解析

作者:木叶之荣 字体:[增加 减小] 来源:互联网 时间:2017-05-28

木叶之荣 通过本文主要向大家介绍了springmvc json数据,springmvc json,springmvc返回json,springmvc接收json,springmvc ajax json等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

这几年都在搞前后端分离、RESTful风格,我们项目中也在这样用。前几天有人遇到了解析JSON格式的请求数据的问题,然后说了一下解析的方式,今天就写篇文章简单的分析一下后台对于JSON格式请求数据是怎么解析的。

先把例子的代码贴出来:

前端

<input type="button" value="测试JSON数据" onclick="testJSON()" /> 
<script type="text/javascript"> 
  function testJSON() { 
    $.ajax({ 
      type: "POST", 
      url: "/testJson", 
      contentType: "application/json", 
      dataType: "json", 
      data: JSON.stringify({"name":"张三"}), 
      success: function (jsonResult) { 
        alert(jsonResult); 
      } 
    }); 
  } 
</script> 
</div>

后台处理代码如下:

@RequestMapping(value ="testJson") 
public String testJson(@RequestBody Map name, HttpServletRequest request){ 
  System.out.println(name); 
  return "jsonp"; 
} 
</div>

这里需要注意的是:要在参数对象上加上@RequestBody注解,这个一定不能少,后台在接收JSON数据的时候一定要用自定义的对象或者Map对象去接收,不要用JDK中的简单对象(String/Integer/Long)来接收。

接下来我再把抓出来的http请求贴一下:

Content-Type:application/json 
</div>

这里需要注意的是:Request Payload中的格式一定要和上图一致,其他格式SpringMVC会解析不出来。

OK,如上的代码就可以搞定一个JSON请求数据的解析了。下面我们来分析一下SpringMVC是怎么处理JSON请求的。

SpringMVC处理请求的简单时序图如下:

正常情况下,一个请求在SpringMVC中一般会调用doDispatch这个方法,我们进入到这个方法中直接跳到

mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); 
</div>

这一行,这一行上面的内容我们以后再找机会分析。

ha.handle这个方法会调用org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter中的handle方法,这个方法里面很简单,就是调用了handleInternal这个方法,代码如下:

public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) 
    throws Exception { 
 
  return handleInternal(request, response, (HandlerMethod) handler); 
} 
</div>

而handleInternal这个方法调用的是org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter中的handleInternal方法,我们进入到这个方法中看看这个方法中都干了一些什么事:

@Override 
protected ModelAndView handleInternal(HttpServletRequest request, 
    HttpServletResponse response, HandlerMethod handlerMethod) throws Exception { 
 
  ModelAndView mav; 
  checkRequest(request);//检查是不是所支持的请求类型、是不是要求session 
 
  // Execute invokeHandlerMethod in synchronized block if required. 
  if (this.synchronizeOnSession) {//session中是不是要求同步执行 
    HttpSession session = request.getSession(false); 
    if (session != null) { 
      Object mutex = WebUtils.getSessionMutex(session); 
      synchronized (mutex) {//同步执行方法调用 
        mav = invokeHandlerMethod(request, response, handlerMethod); 
      } 
    } 
    else { 
      // No HttpSession available -> no mutex necessary 
      mav = invokeHandlerMethod(request, response, handlerMethod); 
    } 
  } 
  else { 
    // No synchronization on session demanded at all... 
    mav = invokeHandlerMethod(request, response, handlerMethod);//这三个invokeHandlerMethod调用的是同一个方法 
  }//缓存的设置 
  if (!response.containsHeader(HEADER_CACHE_CONTROL)) { 
    if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) { 
      applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers); 
    } 
    else { 
      prepareResponse(response); 
    } 
  } 
 
  return mav; 
} 
</div>

在上面的这个方法中我们需要关注的是invokeHandlerMethod这个方法。invokeHandlerMethod这个方法有点复杂,这个方法中干了很多的事,像创建数据验证类、创建方法处理类、模型视图容器等。在这里我们先忽略这些,直接跳到

invocableMethod.invokeAndHandle(webRequest, mavContainer); 
</div>

这里。这个方法在org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod中。在这个方法中我们只关注第一句话:

Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs); 
</div>

invokeForRequest这个方法在org.springframework.web.method.support.InvocableHandlerMethod中,同样在这个方法中我们也只关注第一句话:

Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs); 
</div>

getMethodArgumentValues从这个方法名我们可以看出来这个方法是获取方法参数值的,这个类和上面的方法在同一个类中。我们进到这个方法中看一下:

  private Object[] getMethodArgumentValues(NativeWebRequest request, ModelAndViewContainer mavContainer, 
      Object... providedArgs) throws Exception { 
//获取参数对象数组 方法中的参数都在这个对象数组中存放着。 
    MethodParameter[] parameters = getMethodParameters(); 
    Object[] args = new Object[parameters.length]; 
    for (int i = 0; i < parameters.length; i++) { 
      MethodParameter parameter = parameters[i]; 
      parameter.initParameterNameDiscovery(this.parameterNameDiscoverer); 
      GenericTypeResolver.resolveParameterType(parameter, getBean().getClass());//获取参数的类型(处理参数中的泛型) 
      args[i] = resolveProvidedArgument(parameter, providedArgs);//如果提供了参数的值的话,直接返回 
      if (args[i] != null) { 
        continue; 
      } 
      if (this.argumentResolvers.supportsParameter(parameter)) { //(1) 支持的参数类型 
        try { 
          args[i] = this.argumentResolvers.resolveArgument( // (2) 给参数赋值、校验的一些操作 
              parameter, mavContainer, request, this.dataBinderFactory); 
          continue; 
        } 
        catch (Exception ex) { 
          if (logger.isDebugEnabled()) { 
            logger.debug(getArgumentResolutionErrorMessage("Error resolving argument", i), ex); 
          } 
          throw ex; 
        } 
      } 
      if (args[i] == null) { 
        String msg = getArgumentResolutionErrorMessage("No suitable resolver for argument", i); 
        throw new IllegalStateException(msg); 
      } 
    } 
    return args; 
  } 
</div>

我们先来看看上面的代码中(1)的地方。这个地方是给方法中的参数匹配一个合适的解析器。这个方法的真正调用的是
org.springframework.web.method.support.HandlerMethodArgumentResolverComposite#getArgumentResolver这个方法。

private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) { 
  HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);//如果缓存中已经存在了,则从缓存中取 
  if (result == null) { 
    for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) {//遍历所有的参数解析器 
      if (logger.isTraceEnabled()) { 
        logger.trace("Testing if argument resolver [" + methodArgumentResolver + "] supports [" + 
            parameter.getGenericParameterType() + "]"); 
      } 
      if (methodArgumentResolver.supportsParameter(parameter)) {//匹配合适的参数解析器并放入到缓存中 
        result = methodArgumentResolver; 
        this.argumentRe



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • SpringMVC解析JSON请求数据问题解析
  • SpringMVC中Json数据格式转换
  • SpringMVC解析JSON请求数据问题解析

相关文章

  • 2017-05-28详解PipedInputStream和PipedOutputStream_动力节点Java学院整理
  • 2017-05-28spring boot启动加载数据原理分析
  • 2017-05-28Java 存储模型和共享对象详解
  • 2017-05-28Spring Boot的filter(过滤器)简单使用实例详解
  • 2017-05-28Spring boot集成Mybatis的方法教程
  • 2017-05-28Java导出oracle表结构实例详解
  • 2017-05-28Java初学者常问的问题(推荐)
  • 2017-05-28Java中的对象和引用详解
  • 2017-05-28java多线程编程技术详解和实例代码
  • 2017-05-28java LinkedList源码详解及实例

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 关于javaWeb中405错误的解决方法
    • java 中使用maven shade plugin 打可执行Jar包
    • 详解Spring+Hiernate整合
    • Java使用File类遍历目录及文件实例代码
    • Java微信公众平台开发(14) 微信web开发者工具使用
    • Mybaits配置文件之动态SQL配置备忘录
    • JAVA Frame 窗体背景图片,首位相接滚动代码实例
    • 实例解析Java设计模式编程中的适配器模式使用
    • 详解spring security 配置多个AuthenticationProvider
    • Java中Builder模式的实现详解

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有