spring mvc 怎么获取json

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring mvc 怎么获取json相关的知识,希望对你有一定的参考价值。

首先准备以下 jar包:
commons-logging-1.1.3.jar
jackson-core-asl-1.9.2.jar
jackson-mapper-asl-1.9.2.jar
spring-aop-4.0.6.RELEASE.jar
spring-beans-4.0.6.RELEASE.jar
spring-context-4.0.6.RELEASE.jar
spring-core-4.0.6.RELEASE.jar
spring-expression-4.0.6.RELEASE.jar
spring-web-4.0.6.RELEASE.jar
spring-webmvc-4.0.6.RELEASE.jar
其中commons-logging-1.1.3.jar,jackson-core-asl-1.9.2.jar,jackson-mapper-asl-1.9.2.jar均可在struts2的工具包中取得

导入以上包后,去web.xml中进行配置,配置文件如下:

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID"
version="3.1">    <display-name>web</display-name>
<!-- 配置springMVC请求分配Servlet -->    <servlet>        <servlet-name>springMVC</servlet-name>        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>        <!--
<!-- 声明配置文件存放位置和配置文件的名称,加入不配置此标签,springMVC的配置文件名称默认为<servlet-name>的值加上"-servlet.xml",例如本例便是springMVC-servlet.xml -->        <init-param>            <param-name>contextConfigLocation</param-name>            <param-value>/WEB-INF/*-servlet.xml</param-value>        </init-param>
-->        <!-- 值小于1时,表示容器启动时并不加载此servlet,此时只有当第一次使用servlet时才会加载,但当值大于等于1时,表示容器启动时会立即加载此servlet,此时值越大表示加载的优先级越小 -->        <load-on-startup>1</load-on-startup>    </servlet>    <servlet-mapping>        <servlet-name>springMVC</servlet-name>        <!-- 请求链接以do结尾,具体怎么回事请耐心继续往下看 -->        <url-pattern>*.do</url-pattern>    </servlet-mapping>
<welcome-file-list>        <welcome-file>index.html</welcome-file>        <welcome-file>index.htm</welcome-file>        <welcome-file>index.jsp</welcome-file>        <welcome-file>default.html</welcome-file>        <welcome-file>default.htm</welcome-file>        <welcome-file>default.jsp</welcome-file>    </welcome-file-list></web-app>

接下来我们再看springMVC-servlet.xml,如下:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">    <!-- 扫描指定包下的所有类,倘若发现@Component,@Controller,@Service,@Repsitory等注解,则将相应的类实例化 -->    <context:component-scan base-package="org.xt.controller"/>    <!-- 配置视图资源 -->    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">        <!-- 此乃视图资源的前缀 -->        <property name="prefix" value="/WEB-INF/page"/>        <!-- 此乃视图资源的后缀 -->        <property name="suffix" value=".jsp"/>    </bean>    <!-- 此处乃进行json数据传输的关键,当配置 -->    <bean id="jsonMapping" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">        <property name="messageConverters">            <list>                <ref bean="jsonMapping"/>            </list>        </property>    </bean></beans>

接下来我们再看vo对象即值对象User.java,如下:

package org.xt.pojo;import java.io.Serializable;

@SuppressWarnings("serial")public class User implements Serializable    private long userId;    private String userName;    private String userPassword;    public long getUserId()        return this.userId;
   public void setUserId(long userId)        this.userId = userId;
   public String getUserName()        return this.userName;
   public void setUserName(String userName)        this.userName = userName;
   public String getUserPassword()        return this.userPassword;
   public void setUserPassword(String userPassword)        this.userPassword = userPassword;


好接下来便轮到了Controller的类TestJSONController.java,如下:

package org.xt.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;import org.xt.pojo.User;

@Controller
@RequestMapping("/test")public class TestJSONController    /*
*看value属性,是以do结尾的,这正是web.xml配置url-pattern的值为*.do的原因,
*这样所有的请求链接都必须以.do结尾,这样做的好处在于可以将请求链接同其他链接区分开来.
*笔者建议如此做(当然了,你也可以将.do换成.html,.htm或者其他)    */
@RequestMapping(value = "/testJSON.do",method=RequestMethod.POST)
@ResponseBody    public User testJSON(@RequestBody User user)
System.out.println(user.getUserName() + " " + user.getUserPassword());        return user;


在以上类中出现的@ResponseBody和@RequestBody是关键,前者用于将JSON数据返回客户端,后者用于接受客户端的JSON数据

接下来我们来看看客户端的代码,客户端的代码由jquery完成

<%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"><title>TestJSONForSpringMVC</title></head><body>
用户名:    <input id="userName" type="text" style="width:150px" />    <br />
<br />
密&nbsp;&nbsp;&nbsp;&nbsp;码:    <input id="userPassword" type="password" style="width:150px" />    <br />    <br />    <input id="login" type="button" value="登录" />    <!-- 注意了,此处jquery的路径记得替换成你自己jquery所在的路径 -->    <script type="text/javascript" src="jquery.js"></script>    <script type="text/javascript">
$("#login").click(function()
$.ajax(
url : "test/testJSON.do",
type : "POST",
dataType : "json",
contentType : "application/json;charset=UTF-8",
data : JSON.stringify(
userId : "1",
userName : $("#userName").val(),
userPassword : $("#userPassword").val()
),
success : function(result)
alert(JSON.stringify(result));
,
error:function(result)
alert("Sorry,you are make a error!");

);
);
</script></body></html>

以上jsp文件中出现了一个JSON.stringify()函数,此函数由jquery提供,作用在于将JSON数据转换为字符串,之所以要这么做,原因在于服务端的@RequestBody只能识别字符串,而不能识别JSON对象

参考技术A @ResponseBody 是一种,试图解析器配置协商试图解析器。
如果自己已经生成json字符串,自己实现视图与视图解析器(继承spring实现好的解析器)。

spring mvc从@ResponseBody取到json发现中文乱码

  问题背景:如题。

  问题定位:代码跟踪,从源头入手,一步一步跟进,直到设置中文编码的地方。

  问题代码:

/**
     * 获取单个测试桩接口内容
     *
     * @author wulinfeng
     * @param method
     * @return
     */
    @RequestMapping(value = "/getMethod/{method}", method = RequestMethod.GET)
    public @ResponseBody String getMethodContent(@PathVariable("method") String method)
    {
        return testPillingService.getMethodContent(method);
    }

  怎么切入?是个问题。既然是从源头跟起,那么还是拿DispatcherServlet来开刀吧。所有Controller请求都不可避免的要到这个请求集散地来,而这里最主要的就是doDispatch方法了:

/**
     * Process the actual dispatching to the handler.
     * <p>The handler will be obtained by applying the servlet‘s HandlerMappings in order.
     * The HandlerAdapter will be obtained by querying the servlet‘s installed HandlerAdapters
     * to find the first that supports the handler class.
     * <p>All HTTP methods are handled by this method. It‘s up to HandlerAdapters or handlers
     * themselves to decide which methods are acceptable.
     * @param request current HTTP request
     * @param response current HTTP response
     * @throws Exception in case of any kind of processing failure
     */
    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        boolean multipartRequestParsed = false;

        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

        try {
            ModelAndView mv = null;
            Exception dispatchException = null;

            try {
                processedRequest = checkMultipart(request);
                multipartRequestParsed = (processedRequest != request);

                // Determine handler for the current request.
                mappedHandler = getHandler(processedRequest);
                if (mappedHandler == null || mappedHandler.getHandler() == null) {
                    noHandlerFound(processedRequest, response);
                    return;
                }

                // Determine handler adapter for the current request.
                HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

                // Process last-modified header, if supported by the handler.
                String method = request.getMethod();
                boolean isGet = "GET".equals(method);
                if (isGet || "HEAD".equals(method)) {
                    long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                    if (logger.isDebugEnabled()) {
                        logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
                    }
                    if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
                        return;
                    }
                }

                if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                    return;
                }

                // Actually invoke the handler.
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

                if (asyncManager.isConcurrentHandlingStarted()) {
                    return;
                }

                applyDefaultViewName(processedRequest, mv);
                mappedHandler.applyPostHandle(processedRequest, response, mv);
            }
            catch (Exception ex) {
                dispatchException = ex;
            }
            processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
        }
        catch (Exception ex) {
            triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
        }
        catch (Throwable err) {
            triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);
        }
        finally {
            if (asyncManager.isConcurrentHandlingStarted()) {
                // Instead of postHandle and afterCompletion
                if (mappedHandler != null) {
                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                }
            }
            else {
                // Clean up any resources used by a multipart request.
                if (multipartRequestParsed) {
                    cleanupMultipart(processedRequest);
                }
            }
        }
    }

  看961行,得到了请求参数、请求url映射的处理器、处理的适配器后,进入真正的请求处理流程。先到AbstractHandlerMethodAdapter类,再到子类RequestMappingHandlerAdapter里  

protected ModelAndView handleInternal(HttpServletRequest request,
            HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

        ModelAndView mav;
        checkRequest(request);

        // Execute invokeHandlerMethod in synchronized block if required.
        if (this.synchronizeOnSession) {
            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);
        }

        if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
            if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
                applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
            }
            else {
                prepareResponse(response);
            }
        }

        return mav;
    }
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
            HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

        ServletWebRequest webRequest = new ServletWebRequest(request, response);

        WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
        ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);

        ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
        invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
        invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
        invocableMethod.setDataBinderFactory(binderFactory);
        invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);

        ModelAndViewContainer mavContainer = new ModelAndViewContainer();
        mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
        modelFactory.initModel(webRequest, mavContainer, invocableMethod);
        mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);

        AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);
        asyncWebRequest.setTimeout(this.asyncRequestTimeout);

        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
        asyncManager.setTaskExecutor(this.taskExecutor);
        asyncManager.setAsyncWebRequest(asyncWebRequest);
        asyncManager.registerCallableInterceptors(this.callableInterceptors);
        asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);

        if (asyncManager.hasConcurrentResult()) {
            Object result = asyncManager.getConcurrentResult();
            mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];
            asyncManager.clearConcurrentResult();
            if (logger.isDebugEnabled()) {
                logger.debug("Found concurrent result value [" + result + "]");
            }
            invocableMethod = invocableMethod.wrapConcurrentResult(result);
        }

        invocableMethod.invokeAndHandle(webRequest, mavContainer);
        if (asyncManager.isConcurrentHandlingStarted()) {
            return null;
        }

        return getModelAndView(mavContainer, modelFactory, webRequest);
    }

   进入RequestMappingHandlerAdapter类832行,我们终于到了把处理响应的地方了,接着看ServletInvocableHandlerMethod类110行

public void invokeAndHandle(ServletWebRequest webRequest,
            ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {

        Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
        setResponseStatus(webRequest);

        if (returnValue == null) {
            if (isRequestNotModified(webRequest) || hasResponseStatus() || mavContainer.isRequestHandled()) {
                mavContainer.setRequestHandled(true);
                return;
            }
        }
        else if (StringUtils.hasText(this.responseReason)) {
            mavContainer.setRequestHandled(true);
            return;
        }

        mavContainer.setRequestHandled(false);
        try {
            this.returnValueHandlers.handleReturnValue(
                    returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
        }
        catch (Exception ex) {
            if (logger.isTraceEnabled()) {
                logger.trace(getReturnValueHandlingErrorMessage("Error handling return value", returnValue), ex);
            }
            throw ex;
        }
    }

   InvocableHandlerMethod类125行

/**
     * Invoke the method after resolving its argument values in the context of the given request.
     * <p>Argument values are commonly resolved through {@link HandlerMethodArgumentResolver}s.
     * The {@code providedArgs} parameter however may supply argument values to be used directly,
     * i.e. without argument resolution. Examples of provided argument values include a
     * {@link WebDataBinder}, a {@link SessionStatus}, or a thrown exception instance.
     * Provided argument values are checked before argument resolvers.
     * @param request the current request
     * @param mavContainer the ModelAndViewContainer for this request
     * @param providedArgs "given" arguments matched by type, not resolved
     * @return the raw value returned by the invoked method
     * @exception Exception raised if no suitable argument resolver can be found,
     * or if the method raised an exception
     */
    public Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer,
            Object... providedArgs) throws Exception {

        Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
        if (logger.isTraceEnabled()) {
            StringBuilder sb = new StringBuilder("Invoking [");
            sb.append(getBeanType().getSimpleName()).append(".");
            sb.append(getMethod().getName()).append("] method with arguments ");
            sb.append(Arrays.asList(args));
            logger.trace(sb.toString());
        }
        Object returnValue = doInvoke(args);
        if (logger.isTraceEnabled()) {
            logger.trace("Method [" + getMethod().getName() + "] returned [" + returnValue + "]");
        }
        return returnValue;
    }
/**
     * Invoke the handler method with the given argument values.
     */
    protected Object doInvoke(Object... args) throws Exception {
        ReflectionUtils.makeAccessible(getBridgedMethod());
        try {
            return getBridgedMethod().invoke(getBean(), args);
        }
        catch (IllegalArgumentException ex) {
            assertTargetBean(getBridgedMethod(), getBean(), args);
            String message = (ex.getMessage() != null ? ex.getMessage() : "Illegal argument");
            throw new IllegalStateException(getInvocationErrorMessage(message, args), ex);
        }
        catch (InvocationTargetException ex) {
            // Unwrap for HandlerExceptionResolvers ...
            Throwable targetException = ex.getTargetException();
            if (targetException instanceof RuntimeException) {
                throw (RuntimeException) targetException;
            }
            else if (targetException instanceof Error) {
                throw (Error) targetException;
            }
            else if (targetException instanceof Exception) {
                throw (Exception) targetException;
            }
            else {
                String msg = getInvocationErrorMessage("Failed to invoke controller method", args);
                throw new IllegalStateException(msg, targetException);
            }
        }
    }

 

  

以上是关于spring mvc 怎么获取json的主要内容,如果未能解决你的问题,请参考以下文章

工具类中怎么注入service,spring mvc +mybatiss

spring mvc的controller 怎么获取ajax的数据

spring MVC 怎么获取前端传递的数组参数

js怎么获取从springmvc后台传过来的数据

js怎么获取mvc3的model或者viewdata

Spring MVC 中获取 HttpServletRequest request, HttpServletResponse response 对象的方法