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

来源:互联网 发布:网络剧张嘉倪孙尚香 编辑:程序博客网 时间:2024/04/28 03:51

一、现象描述

前端 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)@ResponseBodypublic 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);    }});

输出为:

解决方案输出

原创粉丝点击