无法找到可接受的代表

时间:2017-10-28 13:19:31

标签: json spring rest spring-boot http-status-code-406

我是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"]
}

考虑遵循DTO课程, 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;

}
具有Post API的

AbcController

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"
}

4 个答案:

答案 0 :(得分:5)

POST请求无效,因为Spring并不知道它所期望的数据类型。所以你需要告诉spring你期待APPLICATION_JSON_VALUE所以它知道如何处理。正如您可能猜到的那样,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格式化的正文,而不仅仅是随机文本。

答案 1 :(得分:2)

我花了半天的时间解决这个错误,最后发现Spring的ContentNegotiationConfigurer默认支持 path扩展(如果存在)。我有这个特殊的映射:

@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开始,这应该是默认设置,但仍然不是默认设置。

答案 2 :(得分:1)

就我而言,这有助于pom

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

答案 3 :(得分:0)

在我的情况下,问题是我没有在响应类(您的AbcDTO类的模拟)中指定公共获取者。因此,没有什么可以序列化并返回给客户端的了。