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

今天使用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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值