ssm中关于ajax发送PUT请求导致数据无法封装,出现sql语句错误

来源:互联网 发布:9090端口 编辑:程序博客网 时间:2024/05/18 00:38

      • 问题
      • 原因
      • 事件-AJAX发送PUT请求失败
      • 解决方案
      • 关于源码分析

今天使用ajax请求rest风格的put请求报错,最后查看源码才解决问题。

     * 如果直接发送ajax=PUT形式的请求     * 封装的数据     * Blog      * [blogId=1, blogTitle=null, blogContentr=null]

问题:

     * 请求体中有数据;     * 但是Blog对象封装不上,导致sql语句成为 update tbl_emp  where blog_id = 20;     * 

原因:

     * Tomcat:     *      1、将请求体中的数据,封装一个map。     *      2、request.getParameter("blogTitle")就会从这个map中取值。     *      3、SpringMVC封装POJO对象的时候,会把POJO中每个属性的值,request.getParamter("blogTitle");

事件-AJAX发送PUT请求失败:

     * PUT请求,请求体中的数据,request.getParameter("empName")拿不到     * Tomcat一看是PUT不会封装请求体中的数据为map,只有POST形式的请求才封装请求体为map

解决方案

1.直接发送ajax的put请求     * 我们要能支持直接发送PUT之类的请求还要封装请求体中的数据     * 1、配置上HttpPutFormContentFilter;     <filter>        <filter-name>HttpPutFormContentFilter</filter-name>        <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>    </filter>    <filter-mapping>        <filter-name>HttpPutFormContentFilter</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>     * 2、他的作用;将请求体中的数据解析包装成一个map。     * 3request被重新包装,request.getParameter()被重写,就会从自己封装的map中取数据---2.直接在data后面加上——method=put$.ajax({  data:"&_method=PUT"})

HiddenHttpMethodFilter 可以将页面的表单提交post请求转换为指定的delete和 put请求
但是直接发送ajax的put请求


关于源码分析

在org.apache.catalina.connector.Request类中的
parseParameters()方法中拿到连接器,调用连接器的ispareseMethod()方法,判断是否为链接器中的method是否包含POST,如果是POST方式才会执行后续的解析内容。所以说直接ajax上写PUT解析不到。

加入 HttpPutFormContentFilter

重新包装请求中的数据,重写getParameter(),从自己封装map中数据

 HttpPutFormContentFilter的protected void doFilterInternal(final HttpServletRequest request, HttpServletResponse response,            FilterChain filterChain) throws ServletException, IOException {//如果是PUT或者PATCH请求,        if (("PUT".equals(request.getMethod()) || "PATCH".equals(request.getMethod())) && isFormContentType(request)) {        //拿到数据,包装成HttpInputMessage            HttpInputMessage inputMessage = new ServletServerHttpRequest(request) {                @Override                public InputStream getBody() throws IOException {                    return request.getInputStream();                }            };            //调用read()读取成MultiValueMap(Map)//将请求提中的对象转换成一个map            MultiValueMap<String, String> formParameters = formConverter.read(null, inputMessage);            //            HttpServletRequest wrapper = new HttpPutFormContentRequestWrapper(request, formParameters);            filterChain.doFilter(wrapper, response);        }        else {            filterChain.doFilter(request, response);        }    }
private static class HttpPutFormContentRequestWrapper extends HttpServletRequestWrapper {        private MultiValueMap<String, String> formParameters;        public HttpPutFormContentRequestWrapper(HttpServletRequest request, MultiValueMap<String, String> parameters) {            super(request);            this.formParameters = (parameters != null ? parameters : new LinkedMultiValueMap<String, String>());        }//此处重写了getParameter()方法,获取参数时还从自己的map当中获取,        @Override        public String getParameter(String name) {            String queryStringValue = super.getParameter(name);            String formValue = this.formParameters.getFirst(name);            return (queryStringValue != null ? queryStringValue : formValue);        }
阅读全文
0 0