[SpringMVC 源码] 415 (Unsupported Media Type) 原因及解决方案

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012099869/article/details/78847887

一、现象描述

前端 ajax 方式调用 springmvc 接口时,返回 415 (Unsupported Media Type) 错误:

现象描述

前端代码:

function fSave(url) {
   var obj = {};
    obj['cateId'] = $("input[name=cateId]").val();
    obj['cateName'] = $("input[name=cateName]").val();

    $.ajax({
        url: url,
        method: 'post',
        data: JSON.stringify(obj), // 以json字符串方式传递
        success: function(data) {
            console.log(data);
        },
        error: function(data) {
            console.log("error...");
            console.log(data);
        }
    });
}

接口代码:

@RequestMapping(value = "/save-by-model-2", method = RequestMethod.POST)
@ResponseBody
public Category saveByModel2(@RequestBody Category category) {
    return category;
}

Category 类定义:

package com.wlm.test.category;

/**
 * 分类实体类对象
 *
 * @author wengliemiao
 */
public class Category {
    private int cateId = 0;
    private String cateName = "";

    // getter(), setter()...
}

二、出错原因

经过对 SpringMVC 中 HTTP 请求响应机制源码(SpringMVC 中 HTTP 请求与响应原理)的深入研究,发现 SpringMVC 解析输入参数和返回数据时,会分别调用相应的输入参数解析类: HandlerMethodArgumentResolver返回值处理类 HandlerMethodReturnValueHandler对数据进行处理。

本实例中,错误为对输入参数进行解析出错,即调用 HandlerMethodArgumentResolver.resolveArgument() 方法时出错。而 @ResponseBody 对应的输入参数解析器为 RequestResponseBodyMethodProcessor, 该方法中调用了readWithMessageConverters() 方法,调用具体的 HttpMessageConverter.read() 方法对输入参数进行解析。

本次实例中的消息转换器类 HttpMessageConverter 有:

消息转换类

而具体调用哪个 HttpMessageConverter 类则根据具体的 HttpMessageConverter 类是否能对相应的媒体类型 MediaType读或写来判断。接口定义如下:

接口定义

如果无匹配的 HttpMessageConverter 类存在,则抛出 HttpMediaTypeNotSupportedException 异常:

异常抛出位置

而在 ajax post 访问中,如未显示指定 contentType 的值,则默认为表单类型
application/x-www-form-urlencoded; charset=UTF-8
。而在 springmvc 中,并无对 application/x-www-form-urlencoded; charset=UTF-8
进行处理的 HttpMessageConverter 类,因此抛出异常。

ajax get 方式编码参考: JavaWeb编码之get方式中文乱码问题

三、解决方案

根据第二点的原理介绍,只需指定接口返回的字符集,且 springmvc 支持,即可解决中文乱码问题,
如:

$.ajax({
  url: url,
    method: 'post',
    contentType: 'application/json', 
    data: JSON.stringify(obj), // 以json字符串方式传递
    success: function(data) {
        console.log(data);
    },
    error: function(data) {
        console.log("error...");
        console.log(data);
    }
});

输出为:

解决方案输出

猜你喜欢

转载自blog.csdn.net/u012099869/article/details/78847887