无法找到可接受的表述

9

我是一名 Spring Boot 的新手,可能会犯一些愚蠢的错误,所以提前道歉。我正在尝试编写一个接受以下 JSON 数据的 POST API:

{
  "id" : null,
  "a": 1.3,
  "b": "somestring",
   "mapJson" : 
    { 
        "monday" : "10:00-12:00/n14:00-18:00", 
        "tuesday" : "10:00-12:00/n14:00-18:00",
        "wednesday" : "10:00-12:00/n14:00-18:00",
        "thursday" : "10:00-12:00/n14:00-18:00",
        "friday" : "10:00-12:00/n14:00-18:00",
        "saturday" : "10:00-12:00/n14:00-18:00",
        "sunday" : "10:00-12:00/n14:00-18:00"
    },
    "list" : ["cc","paytm","debit"]
}

考虑以下数据传输对象类,AbcDTO

package com.abb.dto;
import java.util.List;
import com.abb.entities.OpeningHrs;
import lombok.Data;

@SuppressWarnings("unused")
@Data
public class AbcDTO {

    private Long id;
    private Double a;
    private String b;
    private MapJson mapJson;
    private List<String> list;

}

OpeningHrs 是用于映射Json Map结构的类。

该类可帮助您更好地处理与开放时间相关的数据。
package com.abb.entities;
import lombok.Data;
@SuppressWarnings("unused")
@Data
public class MapJson {

    private String monday;
    private String tuesday;
    private String wednesday;
    private String thursday;
    private String friday;
    private String saturday;
    private String sunday;

}

AbcController 是一个具有 Post API 的控制器:

package com.abb.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.abb.dto.AbcDTO;

@RestController
@EnableAutoConfiguration
@RequestMapping("/abc")
@GetMapping(value="/{id}",produces={MediaType.APPLICATION_JSON_VALUE})
public class HotelController {

   @RequestMapping(value = "/xyz", method = RequestMethod.POST)
    public @ResponseBody AbcDTO registerHotel(@RequestBody AbcDTO aaa) {

       System.out.println(aaa.toString());
       return aaa; 
   // I'm not able to map JSON into this Object
    }

}

请看下面我收到的响应结果:
{
    "timestamp": 1509193409948,
    "status": 406,
    "error": "Not Acceptable",
    "exception": "org.springframework.web.HttpMediaTypeNotAcceptableException",
    "message": "Could not find acceptable representation",
    "path": "/abc/xyz"
}

当您发送JSON时,您是否添加标题Content-Type: application/json? - dimirsen Z
1
我已经在请求头中添加了 Content-Type: application/json。 - Mayur
4个回答

7

POST请求无法正常工作,因为Spring不知道它期望的数据类型。所以你需要告诉Spring你期望的是APPLICATION_JSON_VALUE,这样Spring才知道如何处理。consumes=会告诉Spring传入的POST请求体的内容类型。

@RequestMapping(value = "xyz", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody AbcDTO registerHotel(@RequestBody AbcDTO aaa) {

    System.out.println(aaa.toString());
    return aaa; 
    // I'm not able to map JSON into this Object
}

使用PostMapping

@PostMapping(value = "xyz", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody AbcDTO registerHotel(@RequestBody AbcDTO aaa) {

   System.out.println(aaa.toString());
   return aaa; 
   // I'm not able to map JSON into this Object
}

正如您所看到的,我还添加了一个叫做produces=的东西,这将指示Spring如何格式化该请求的响应正文。因此,前端接收到的是JSON格式的正文,而不仅仅是随机文本。


2
谢谢,我错过了“consumes”参数。但是在添加它之后,它仍然无法工作 - Mayur
我已经添加了 PostMapping,你能看看它是否有效吗?你也可以尝试删除 ClassGetMapping,因为请求是 Post,这可能会阻塞整个 Class - Prav
假设您也已从类中删除了 GetMapping。错误是否有所改变?您使用什么工具发送请求? - Prav
是的,我已经从类中删除了GetMapping,并且我正在使用ARC和PostMan发送请求,同时将Content-Type设置为Application/Json,请求JSON在Body中。 - Mayur
@Mayur,你能否尝试删除 /xyz 中的 /?这是我现在能想到的唯一可能性。除此之外,我唯一能想到的就是在 Postman 中使用 Get 方法而不是 Post 方法,但我非常怀疑这种情况。 - Prav

3
在我的情况下,在pom.xml文件中使用了这个。
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

1
在你的情况下,我猜你的服务生成XML?这也是我的情况,但我还必须配置一个消息转换器:`@Override public void configureMessageConverters(final List> converters) { converters.add(new MappingJackson2XmlHttpMessageConverter()); }` - Andreas Sandberg

2
在我的情况下,问题在于我没有在响应类中指定公共的getter方法(相当于您的AbcDTO类)。因此,没有任何内容可以获取进行序列化并返回给客户端。

2

我刚刚花了半天时间解决这个错误,最终发现Spring的ContentNegotiationConfigurer默认情况下会优先选择路径扩展名。我有这样一个特定的映射:

@PostMapping(value="/convert/{fileName:.+}",produces=MediaType.APPLICATION_JSON_VALUE)
public Map<String, String> convert(@PathVariable String fileName, @RequestBody String data) {
   // Do conversion
}

现在,当我使用文件名“outputfile.pdf”将内容发布到该控制器时,Spring 会简单地假定响应必须是PDF格式,完全忽略PostMapping的“produces”参数。可以通过ContentNegotiationConfigurer.favorPathExtension(false)来解决这个问题。从Spring web 5.3开始,这应该是默认设置,但实际上并不是。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接