首页 > 解决方案 > 春季启动状态“:415,”错误“:”不支持的媒体

问题描述

我使用 Spring Boot RESTful API,在执行 POST 请求时,我收到 415 错误。cURL请求如下,

$ curl -i -X POST -H "Content-Type:application/json" -d "{\"name_of_doctor\" : \"Monika\", \"status\": \"true\", \"price\": \"12.5\"}" http://localhost:8080/api/v1/appointments/createAppointment

回复在这里,

HTTP/1.1 415 
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Fri, 08 Feb 2019 09:05:04 GMT

{"timestamp":"2019-02-08T09:05:04.560+0000","status":415,"error":"Unsupported Media Type","message":"Content type 'application/json;charset=UTF-8' not supported","path":"/api/v1/appointments/createAppointment"}

API 处理 HTTP 请求,

@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/v1/appointments")
public class AppointmentAPI {

    @Autowired
    private AppointmentService service;

    @GetMapping("/getAll")
    public ResponseEntity<List<Appointment>> findAll() {
        return ResponseEntity.ok(service.findAll());
    }

    @PostMapping(value = "/createAppointment", consumes = "application/json;charset=UTF-8", produces = "application/json;charset=UTF-8")
    public ResponseEntity<Appointment> create(@RequestBody Appointment appointment) {

        java.sql.Date date = new java.sql.Date(Calendar.getInstance().getTime().getTime());
        java.sql.Time time = new java.sql.Time(Calendar.getInstance().getTime().getTime());

        appointment.setAppointment_date(date);
        appointment.setCraeted_at(time);

        service.save(appointment);
        return ResponseEntity.status(HttpStatus.CREATED).body(appointment);
    }


}

该模型可能很有趣,因此,在下面提供,

@Entity
@JsonDeserialize(builder = Appointment.class)
public class Appointment {


//    id
//    created_at
//    appointment_date
//    name_of_doctor
//    status (Available or Booked)
//    price

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;


    @Column
    private java.sql.Time craeted_at;


    @Column
    private java.sql.Date appointment_date;

    @Column
    private String name_of_doctor;

    @Column
    private boolean status;

    @Column
    private double price;


    public Appointment(Time craeted_at, Date appointment_date, String name_of_doctor, boolean status, double price) {
        this.craeted_at = craeted_at;
        this.appointment_date = appointment_date;
        this.name_of_doctor = name_of_doctor;
        this.status = status;
        this.price = price;
    }

    public Appointment(String name_of_doctor, boolean status, double price) {
        this.name_of_doctor = name_of_doctor;
        this.status = status;
        this.price = price;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Time getCraeted_at() {
        return craeted_at;
    }

    public void setCraeted_at(Time craeted_at) {
        this.craeted_at = craeted_at;
    }

    public Date getAppointment_date() {
        return appointment_date;
    }

    public void setAppointment_date(Date appointment_date) {
        this.appointment_date = appointment_date;
    }

    public String getName_of_doctor() {
        return name_of_doctor;
    }

    public void setName_of_doctor(String name_of_doctor) {
        this.name_of_doctor = name_of_doctor;
    }

    public boolean isStatus() {
        return status;
    }

    public void setStatus(boolean status) {
        this.status = status;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Appointment)) return false;
        Appointment that = (Appointment) o;
        return isStatus() == that.isStatus() &&
                Double.compare(that.getPrice(), getPrice()) == 0 &&
                Objects.equals(getId(), that.getId()) &&
                Objects.equals(getCraeted_at(), that.getCraeted_at()) &&
                Objects.equals(getAppointment_date(), that.getAppointment_date()) &&
                Objects.equals(getName_of_doctor(), that.getName_of_doctor());
    }

    @Override
    public int hashCode() {

        return Objects.hash(getId(), getCraeted_at(), getAppointment_date(), getName_of_doctor(), isStatus(), getPrice());
    }

    @Override
    public String toString() {
        return "Appointment{" +
                "id=" + id +
                ", craeted_at=" + craeted_at +
                ", appointment_date=" + appointment_date +
                ", name_of_doctor='" + name_of_doctor + '\'' +
                ", status=" + status +
                ", price=" + price +
                '}';
    }
}

运行窗口提供了错误堆栈,

2019-02-08 10:10:24.499  INFO 1337 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-02-08 10:10:24.499  INFO 1337 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2019-02-08 10:10:24.526  INFO 1337 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 26 ms
2019-02-08 10:10:24.640  WARN 1337 --- [nio-8080-exec-1] .c.j.MappingJackson2HttpMessageConverter : Failed to evaluate Jackson deserialization for type [[simple type, class com.appoint.manager.appointment.models.Appointment]]: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Builder class com.appoint.manager.appointment.models.Appointment does not have build method (name: 'build')
2019-02-08 10:10:24.642  WARN 1337 --- [nio-8080-exec-1] .c.j.MappingJackson2HttpMessageConverter : Failed to evaluate Jackson deserialization for type [[simple type, class com.appoint.manager.appointment.models.Appointment]]: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Builder class com.appoint.manager.appointment.models.Appointment does not have build method (name: 'build')
2019-02-08 10:10:24.645  WARN 1337 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported]

谁能告诉我这里有什么问题?

标签: javarestspring-bootjackson-databind

解决方案


您收到此错误是因为您指定了@JsonDeserialize(builder = Appointment.class). 这告诉杰克逊使用构建器 Appointment.class(它不是​​构建器)来反序列化有效负载。尝试提供一个验证构建器或使用@JsonCreator,例如:

@JsonCreator
public Appointment(@JsonProperty("craeted_at") Time craeted_at, @JsonProperty("appointment_date") Date appointment_date,
        @JsonProperty("name_of_doctor") String name_of_doctor, @JsonProperty("status") boolean status, @JsonProperty("price") double price) {
    this.craeted_at = craeted_at;
    this.appointment_date = appointment_date;
    this.name_of_doctor = name_of_doctor;
    this.status = status;
    this.price = price;
}

推荐阅读