zoukankan      html  css  js  c++  java
  • SpringMVC前后端参数交互

    Controller中使用JSON方式有多种

    关键在于ajax请求是将数据以什么形式传递到后台

    HTTP请求中:

    • 如果是get请求,那么表单参数以name=value&name1=value1的形式附到url的后面(QueryString Parameters),
    • 如果是post请求,那么表单参数是在请求体中,也是以name=value&name1=value1的形式在请求体中(Form Data)

    前端常用参数提交方式:

    1. POST + JSON字符串形式
    2. POST + JSON对象形式
    3. GET + 参数字符串

    方式一: POST + JSON字符串形式,如下:

    //前端 
    
    var data = {  
        userAccount: lock_username,  
        userPasswd:md5(lock_password).toUpperCase()  
    }  
       
    $.ajax({  
        url : ctx + "/unlock.do",  
        type : "POST",  
        data : JSON.stringify(data), //转JSON字符串  
        dataType: 'json',  
        contentType:'application/json;charset=UTF-8', //contentType很重要     
        success : function(result) {  
            console.log(result);  
        }  
    });
     
    注意
    1.json数据必须用JSON.stringify()方法转换成字符串
    2.contentType不能省略
    
    
    
    //后端
    
    @RequestMapping(value = "unlock.do",method = RequestMethod.POST)
    @ResponseBody
    public Msg methodName(@RequestBody User user) {
        logger.info("user:"+user);
        return Msg.success();
    }
    
    注意
    @RequestBody不可以省略,如果不加的话spring mvc后台无法接受data参数
    
    @RequestParam 、@RequestBody 说明
    
    @RequestParam用来处理ContentType: 为 application/x-www-form-urlencoded编码的内容
    
    @RequestBody该注解常用来处理Content-Type: 不是application/x-www-form-urlencoded编码的内容,例如application/json, application/xml等
    
    @RequestBody接收的是一个Json对象的字符串,而不是一个Json对象。在ajax请求往往传的都是Json对象,用 JSON.stringify(data)的方式就能将对象变成字符串。

    参考资料: https://blog.csdn.net/HelloWorld20151118/article/details/77104047

    方式二: POST + JSON对象形式,如下:

    //请求数据,登录账号 +密码  
    ar data = {  
         userAccount: lock_username,  
         userPasswd:md5(lock_password).toUpperCase()  
    }  
      
    $.ajax({  
        url : ctx + "/unlock.do",  
        type : "POST",  
        data : data, //直接用JSON对象
        contentType : "application/x-www-form-urlencoded",
        dataType: 'json',  
        success : function(result) {  
            console.log(result);  
        }  
    });  

     

    说明:

    tomcat容器会对如下两种格式数据特殊处理:

    1. 表单提交且Content-Type为application/x-www-form-urlencoded,因为表单提交数据是键值对的方式;
    2. 文件上传做特殊处理;

    tomcat容器对于Content-Type不是application/x-www-form-urlencoded的数据只能通过获取原始数据流的方式来进行解析,因为请求数据格式不固定,不一定是键值对的方式,所以服务器无法知道具体的处理方式;那么这样提交的参数我们该怎么获取呢?当然是使用最原始的方式,读取输入流来获取了(参考:FastJsonHttpMessageConverter),原始方式当然也可以接收Content-Type是application/x-www-form-urlencoded得POST请求数据

    类名:org.apache.catalina.connector.Request
    
    protected void parseParameters() {
        this.parametersParsed = true;
        Parameters parameters = this.coyoteRequest.getParameters();
        boolean success = false;
    
        try {
            parameters.setLimit(this.getConnector().getMaxParameterCount());
            String enc = this.getCharacterEncoding();
            boolean useBodyEncodingForURI = this.connector.getUseBodyEncodingForURI();
            if(enc != null) {
                parameters.setEncoding(enc);
                if(useBodyEncodingForURI) {
                    parameters.setQueryStringEncoding(enc);
                }
            } else {
                parameters.setEncoding("ISO-8859-1");
                if(useBodyEncodingForURI) {
                    parameters.setQueryStringEncoding("ISO-8859-1");
                }
            }
    
            parameters.handleQueryParameters();
            if(this.usingInputStream || this.usingReader) {
                success = true;
                return;
            }
    
            if(!this.getConnector().isParseBodyMethod(this.getMethod())) {
                success = true;
                return;
            }
    
            String contentType = this.getContentType();
            if(contentType == null) {
                contentType = "";
            }
    
            int semicolon = contentType.indexOf(59);
            if(semicolon >= 0) {
                contentType = contentType.substring(0, semicolon).trim();
            } else {
                contentType = contentType.trim();
            }
            // 这里是处理文件上传请求  
            if("multipart/form-data".equals(contentType)) {
                this.parseParts(false);
                success = true;
                return;
            }
            // 这里如果contentType是非application/x-www-form-urlencoded请求直接返回,不再进行处理。
            // 从上面代码可以看出,Content-Type==不是application/x-www-form-urlencoded==的POST请求是不会读取请求体数据和进行相应的参数处理的,即不会解析表单数据来放到request parameter map中。所以通过request.getParameter(name)是获取不到的。
            if(!"application/x-www-form-urlencoded".equals(contentType)) {
                success = true;
                return;
            }
    
            int len = this.getContentLength();
            if(len <= 0) {
                if("chunked".equalsIgnoreCase(this.coyoteRequest.getHeader("transfer-encoding"))) {
                    Object formData1 = null;
    
                    Context context;
                    byte[] formData2;
                    try {
                        formData2 = this.readChunkedPostBody();
                    } catch (IllegalStateException var17) {
                        parameters.setParseFailedReason(FailReason.POST_TOO_LARGE);
                        context = this.getContext();
                        if(context != null && context.getLogger().isDebugEnabled()) {
                            context.getLogger().debug(sm.getString("coyoteRequest.parseParameters"), var17);
                        }
    
                        return;
                    } catch (IOException var18) {
                        parameters.setParseFailedReason(FailReason.CLIENT_DISCONNECT);
                        context = this.getContext();
                        if(context != null && context.getLogger().isDebugEnabled()) {
                            context.getLogger().debug(sm.getString("coyoteRequest.parseParameters"), var18);
                        }
    
                        return;
                    }
    
                    if(formData2 != null) {
                        parameters.processParameters(formData2, 0, formData2.length);
                    }
                }
            } else {
                int formData = this.connector.getMaxPostSize();
                Context e;
                if(formData >= 0 && len > formData) {
                    e = this.getContext();
                    if(e != null && e.getLogger().isDebugEnabled()) {
                        e.getLogger().debug(sm.getString("coyoteRequest.postTooLarge"));
                    }
    
                    this.checkSwallowInput();
                    parameters.setParseFailedReason(FailReason.POST_TOO_LARGE);
                    return;
                }
    
                e = null;
                byte[] e1;
                if(len < 8192) {
                    if(this.postData == null) {
                        this.postData = new byte[8192];
                    }
    
                    e1 = this.postData;
                } else {
                    e1 = new byte[len];
                }
    
                try {
                    if(this.readPostBody(e1, len) != len) {
                        parameters.setParseFailedReason(FailReason.REQUEST_BODY_INCOMPLETE);
                        return;
                    }
                } catch (IOException var19) {
                    Context context1 = this.getContext();
                    if(context1 != null && context1.getLogger().isDebugEnabled()) {
                        context1.getLogger().debug(sm.getString("coyoteRequest.parseParameters"), var19);
                    }
    
                    parameters.setParseFailedReason(FailReason.CLIENT_DISCONNECT);
                    return;
                }
                // 处理POST请求参数,把它放到requestparameter map中(即request.getParameterMap获取到的Map,request.getParameter(name)也是从这个Map中获取的)
                parameters.processParameters(e1, 0, len);
            }
    
            success = true;
        } finally {
            if(!success) {
                parameters.setParseFailedReason(FailReason.UNKNOWN);
            }
    
        }
    
    }
    protected int readPostBody(byte[] body, int len) throws IOException {
        int offset = 0;
    
        do {
            int inputLen = this.getStream().read(body, offset, len - offset);
            if(inputLen <= 0) {
                return offset;
            }
    
            offset += inputLen;
        } while(len - offset > 0);
    
        return len;
    }   
    
    
    类:com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter
    
    @Override
    protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage ) throws IOException, HttpMessageNotReadableException {
        return readType(getType(clazz, null), 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);
        }
    }
    
    
    原始方式接收数据,自己开发:
    
    private String getRequestPayload(HttpServletRequest req) {  
        StringBuildersb = new StringBuilder();  
        try(BufferedReaderreader = req.getReader();) {  
           char[]buff = new char[1024];  
           intlen;  
           while((len = reader.read(buff)) != -1) {  
                    sb.append(buff,0, len);  
           }  
        }catch (IOException e) {  
           e.printStackTrace();  
        }  
        returnsb.toString();  
    } 

    方式三: GET + 参数字符串请求

    $.ajax({  
        url : ctx + "/unlock.do",  
        type : "GET",  
        dataType: "text",   
        data : "userAccount="+lock_username+"&userPasswd=" + hex_md5(lock_password).toUpperCase(),//等价于URL后面拼接参数  
        success : function(result) {  
            console.log(result);  
        }  
    }); 
    
    或者
    
    ar data = {  
         userAccount: lock_username,  
         userPasswd:md5(lock_password).toUpperCase()  
    }  
    $.ajax({  
        url : ctx + "/unlock.do",  
        type : "GET",  
        dataType: "text",   
        data : data,//等价于URL后面拼接参数  
        success : function(result) {  
            console.log(result);  
        }  
    });

    jquery:GET方式(选项processData:true情况下) data请求中将附加在 URL 后 

     

  • 相关阅读:
    C++ FFLIB之FFXML: 极简化TinyXml 读取
    使用ffpython嵌入和扩展python
    Json 备忘录
    一位软件工程师的6年工作总结
    Sql Server 备忘录
    走出软件作坊
    asp.net 使用Jquery 调用WebService返回JSON 类型数据
    .NET 页面间传值的几种方法
    CKeditor安全使用
    新浪短信Web Service
  • 原文地址:https://www.cnblogs.com/xiaoliang-y/p/9016495.html
Copyright © 2011-2022 走看看