首页 > 解决方案 > 使用 postForObject 方法发布 JSON 后,我收到“415 Unsupported Media Type”错误

问题描述

我的控制器有一个后端服务器:

@RestController
@RequestMapping("/rsrv")
public class ReservationController {
    @Autowired
    private ReservationService service;
    @Autowired
    private ReservationMapper mapper;

    @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, value = "createReservation")
    public void createReservation(@RequestBody ReservationDto reservationDto) {
        service.saveReservation(mapper.mapToReservation(reservationDto));
    } 
    //  + other methods
}

以及通过 HTTP 请求与后端通信的前端。这是一些配置:

@Component
public class ApiClient {
    private static final Logger LOGGER = LoggerFactory.getLogger(ApiClient.class);
    @Autowired
    private RestTemplate restTemplate;
    @Value("${api.endpoint}")
    private String baseEndpoint;

    private URI createReservationURI(LocalDateTime date, Long patientId, Long doctorId) {
        return UriComponentsBuilder.fromHttpUrl(baseEndpoint + "/rsrv/createReservation")
                .queryParam("id", getReservations().size() + 1000)
                .queryParam("time", LocalDateTime.now())
                .queryParam("patientId", getReservations().size() + 1001)
                .queryParam("doctorId", getReservations().size() + 1002)
                .build().encode().toUri();
    }

    public void createReservation(ReservationDto reservationDto) {
        try {
            restTemplate.postForObject(createReservationURI(reservationDto.getTime(), 
                                                            reservationDto.getPatientId(), 
                                                            reservationDto.getDoctorId()),
                                                            null, 
                                                            CreatedReservationDto.class);
            System.out.println("Reservation added!");
        } catch (RestClientException e) {
            LOGGER.error(e.getMessage(), e);
            System.out.println("Reservation hasn't been added!");
        }
    }
}

我试图解决这个问题,同时我创建了一个单独的类(它几乎是原始类的克隆,实际上在上面的 postForObject 方法中使用):

@JsonIgnoreProperties(ignoreUnknown = true)
public class CreatedReservationDto {
    @JsonProperty("id")
    private Long id;
    @JsonProperty("time")
    private LocalDateTime time;
    @JsonProperty("patientId")
    private Long patientId;
    @JsonProperty("doctorId")
    private Long doctorId;

    public CreatedReservationDto(Long id, LocalDateTime time, Long patientId, Long doctorId) {
        this.id = id;
        this.time = time;
        this.patientId = patientId;
        this.doctorId = doctorId;
    }

    public CreatedReservationDto() {
    }
    // + getters and setters

createReservation 方法仍然不起作用,我已经搜索了答案,似乎请求本身没有错,但服务器端不仅接受 JSON 数据,但我不知道该怎么做。有什么帮助吗?

我将包括日志:https ://pastebin.com/S9jndvEa

标签: javajsonspringrest

解决方案


您的控制器需要一个正文(JSON 格式)而不是 URL 参数。

发送带有期望值的 POST 请求的解决方案如下:

    final HttpHeaders httpHeaders = new HttpHeaders();
    final CreatedReservationDto createdReservationDto = new 
    CreatedReservationDto("idValue","timeValue","patientValue","doctorValue");

    final HttpEntity<String> body = new HttpEntity<> 
    (gson.toJson(createdReservationDto), httpHeaders);
           
    final URI uri = UriComponentsBuilder.fromHttpUrl(baseEndpoint + 
     "/rsrv/createReservation").build().encode().toUri();
    
    final ResponseEntity<T> response = restTemplate.exchange(uri, 
       HttpMethod.POST, body, ConsumedObject.class);

考虑到ConsumedObject.class如果您的服务器正在检索 POST 请求的响应,那将是预期响应的类。


推荐阅读