191

我正在尝试向 servlet 发送 POST 请求。请求是通过 jQuery 以这种方式发送的:

var productCategory = new Object();
productCategory.idProductCategory = 1;
productCategory.description = "Descrizione2";
newCategory(productCategory);

newCategory 在哪里

function newCategory(productCategory)
{
  $.postJSON("ajax/newproductcategory", productCategory, function(
      idProductCategory)
  {
    console.debug("Inserted: " + idProductCategory);
  });
}

而 postJSON 是

$.postJSON = function(url, data, callback) {
    return jQuery.ajax({
    'type': 'POST',
    'url': url,
    'contentType': 'application/json',
    'data': JSON.stringify(data),
    'dataType': 'json',
    'success': callback
    });
};

使用 firebug,我看到 JSON 发送正确:

{"idProductCategory":1,"description":"Descrizione2"}

但我得到 415 Unsupported media type。Spring mvc 控制器具有签名

    @RequestMapping(value = "/ajax/newproductcategory", method = RequestMethod.POST)
public @ResponseBody
Integer newProductCategory(HttpServletRequest request,
        @RequestBody ProductCategory productCategory)

前几天有效,现在无效。如果需要,我会显示更多代码。谢谢

4

15 回答 15

266

我以前使用 Spring @ResponseBody 发生过这种情况,这是因为没有随请求发送的接受标头。使用 jQuery 设置 Accept 标头可能会很痛苦,但这对我有用来源

$.postJSON = function(url, data, callback) {
    return jQuery.ajax({
    headers: { 
        'Accept': 'application/json',
        'Content-Type': 'application/json' 
    },
    'type': 'POST',
    'url': url,
    'data': JSON.stringify(data),
    'dataType': 'json',
    'success': callback
    });
};

@RequestBody 使用 Content-Type 标头来确定在请求中从客户端发送的数据的格式。@ResponseBody 使用接受标头来确定在响应中将数据发送回客户端的格式。这就是为什么你需要两个标题。

于 2012-07-18T20:24:33.670 回答
31

将内容类型添加到请求中以application/json解决问题

于 2017-03-02T10:47:10.023 回答
18

我遇到了类似的问题,但发现问题是我忽略了为使用 @RequestBody 注释的 DTO 提供默认构造函数。

于 2013-04-03T06:45:34.010 回答
15

我遇到了类似的问题,这就是我解决它的方法,

问题是由于从 JSON 到 Java 的转换过程,需要有正确的运行时 jackson 库才能正确进行转换。

添加以下 jars(通过依赖项或通过下载并添加到类路径。

<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>

这应该可以解决问题。

完整代码:

function() {
  $.ajax({
    type: "POST",
    url: "saveUserDetails.do",
    data: JSON.stringify({
      name: "Gerry",
      ity: "Sydney"
    }),
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    success: function(data) {
      if (data.status == 'OK')
        alert('Person has been added');
      else
        alert('Failed adding person: ' + data.status + ', ' + data.errorMessage);
}

控制器签名如下所示:

@RequestMapping(value = "/saveUserDetails.do", method = RequestMethod.POST)
public @ResponseBody Person addPerson( @RequestBody final  Person person) {

希望这可以帮助

于 2016-02-21T06:58:50.217 回答
12

我相信我遇到了同样的问题。经过无数小时与 JSON、JavaScript 和服务器的斗争,我找到了罪魁祸首:在我的例子中,我在 DTO 中有一个 Date 对象,这个 Date 对象被转换为一个字符串,所以我们可以在视图中显示它格式:HH:mm。

当返回 JSON 信息时,这个 Date String 对象必须被转换回一个完整的 Date 对象,因此我们还需要一个方法来在 DTO 中设置它。最大的问题是即使它们具有不同类型的参数(字符串与日期),您也不能在 DTO 中有 2 个具有相同名称(重载)的方法,因为这也会给您 415 Unsupported Media type 错误。

这是我的控制器方法

  @RequestMapping(value = "/alarmdownload/update", produces = "application/json", method = RequestMethod.POST)
  public @ResponseBody
  StatusResponse update(@RequestBody AlarmDownloadDTO[] rowList) {
    System.out.println("hola");
    return new StatusResponse();
  }

这是我的 DTO 示例(由于代码简短,不包括 id get/set 和 preAlarm get 方法):

@JsonIgnoreProperties(ignoreUnknown = true)
public class AlarmDownloadDTO implements Serializable {

  private static final SimpleDateFormat formatHHmm = new SimpleDateFormat("HH:mm");

  private String id;
  private Date preAlarm;

  public void setPreAlarm(Date date) { 
    this.preAlarm == date;
  }
  public void setPreAlarm(String date) {    
    try {
      this.preAlarm = formatHHmm.parse(date);
    } catch (ParseException e) {
      this.preAlarm = null;
    } catch (NullPointerException e){
      this.preAlarm = null;
    }
  }
}

为了使一切正常,您需要删除带有 Date 类型参数的方法。这个错误非常令人沮丧。希望这可以节省一些人的调试时间。

于 2013-05-18T23:34:57.150 回答
8

当我将 spring boot 与 spring mvc 集成时,我遇到了这个问题。我通过添加这些依赖项来解决它。

<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>
于 2016-06-03T05:54:33.800 回答
5

一个小的旁注 - 在开发 Web 应用程序时偶然发现了同样的错误。通过使用 Firefox Poster 来玩弄该服务,我们发现的错误是 Json 中的字段和值都应该用双引号引起来。例如..

[ {"idProductCategory" : "1" , "description":"Descrizione1"}, 
  {"idProductCategory" : "2" , "description":"Descrizione2"} ]

在我们的例子中,我们通过 javascript 填充了 json,据我所知,在处理单引号/双引号时可能会有些混乱。

之前在这篇文章和其他文章中所说的内容,比如包括“接受”和“内容类型”标题,也适用。

希望有帮助。

于 2013-01-16T10:37:00.550 回答
3

我设法使它工作。告诉我,以防我错了。@JSONSerialize我只使用了一种方法来序列化/反序列化:我删除了关于这个 (和)的所有注释,并在课堂上@JSONDeserialize注册了序列化器和反序列化器。CustomObjectMapper我没有找到解释这种行为的文章,但我以这种方式解决了。希望它有用。

于 2012-07-26T16:19:08.207 回答
1

我有同样的问题。我必须按照以下步骤解决问题:

1. 确保您具有以下依赖项:

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>${jackson-version}</version> // 2.4.3
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson-version}</version> // 2.4.3
    </dependency>

2. 创建以下过滤器:

    public class CORSFilter extends OncePerRequestFilter {

        @Override
        protected void doFilterInternal(HttpServletRequest request,
                                        HttpServletResponse response, FilterChain filterChain)
                throws ServletException, IOException {

            String origin = request.getHeader("origin");
            origin = (origin == null || origin.equals("")) ? "null" : origin;
            response.addHeader("Access-Control-Allow-Origin", origin);
            response.addHeader("Access-Control-Allow-Methods", "POST, GET, PUT, UPDATE, DELETE, OPTIONS");
            response.addHeader("Access-Control-Allow-Credentials", "true");
            response.addHeader("Access-Control-Allow-Headers",
                    "Authorization, origin, content-type, accept, x-requested-with");

            filterChain.doFilter(request, response);
        }
    }

3. 对 web.xml 中的请求应用上述过滤器

    <filter>
        <filter-name>corsFilter</filter-name>
        <filter-class>com.your.package.CORSFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>corsFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

我希望这对某人有用。

于 2016-03-16T04:11:24.853 回答
1

弹簧靴+弹簧MVN

有问题

@PostMapping("/addDonation")
public String addDonation(@RequestBody DonatorDTO donatorDTO) {

有溶液

@RequestMapping(value = "/addDonation", method = RequestMethod.POST)
@ResponseBody
public GenericResponse addDonation(final DonatorDTO donatorDTO, final HttpServletRequest request){
于 2018-12-04T10:46:14.070 回答
0

我遇到过同样的问题。添加

<mvc:annotation-driven />
<mvc:default-servlet-handler />

到 spring-xml 解决了

于 2019-12-10T15:29:20.650 回答
0

我通过将 jackson-json 数据绑定添加到我的 pom.xml 解决了这个问题。

<dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.6.3</version>
</dependency>
于 2018-01-24T10:43:27.687 回答
0

在您的模型类中添加一个 json 属性注释,还有一个默认构造函数

@JsonProperty("user_name")
private String userName;

@JsonProperty("first_name")
private String firstName;

@JsonProperty("last_name")
private String lastName;
于 2019-09-06T07:51:21.940 回答
0

除了设置 Accept 和 Content-Type 标头并确保它们与控制器方法的使用/生成设置相匹配之外,您可能还需要查看 JSON 结构并确保编组和解组没有问题。在我的情况下,内容类型还可以,但是将 JSON 请求映射到我的请求/响应模型时存在问题。通常,控制器应该返回 400 错误而不是 415 错误,但在我的情况下,错误代码是 415。我通过添加一个测试类来调试问题,其中我使用 ObjectMapper 将我的 JSON 读入请求模型对象。ObjectMapper 因请求而窒息,并给了我有用的错误,帮助我修复了模型类定义。

于 2021-05-24T15:12:54.090 回答
-1

1.a. 在 applicationContext-mvc.xml 中添加以下内容

xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc

  1. 添加杰克逊库
于 2016-01-01T05:27:31.143 回答