簡體   English   中英

使用郵遞員發布請求后,springboot 服務器返回錯誤 400

[英]springboot server returns error 400 after post request using postman

每當我嘗試通過郵遞員發送此郵件時:

{
    "date": "2021-11-05 12:32:32",
    "start": "start",
    "destination": "destination",
    "provider": "provider",
    "driver":1,
    "vehicule":1
}

我收到錯誤 400,錯誤的請求,我同時使用 @restController 和 @requestBody 注釋,同時還將內容類型設置為 json。

我在調試器上收到此錯誤:

2021-11-09 16:57:52.086  WARN 11748 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `java.util.Date` from String "2021-11-06 12:32:32.0": not a valid representation (error: Failed to parse Date value '2021-11-06 12:32:32.0': Cannot parse date "2021-11-06 12:32:32.0": while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSSX', parsing fails (leniency? null)); nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.util.Date` from String "2021-11-06 12:32:32.0": not a valid representation (error: Failed to parse Date value '2021-11-06 12:32:32.0': Cannot parse date "2021-11-06 12:32:32.0": while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSSX', parsing fails (leniency? null))
 at [Source: (PushbackInputStream); line: 3, column: 17] (through reference chain: com.siam.HRAssistTool.Entity.Schedule["date"])]

我不明白我應該如何解決這個我認為與日期格式相關的問題

當我從 json 正文中刪除時間並只留下日期時,我收到此錯誤:

2021-11-09 17:34:55.418  WARN 11748 --- [nio-8080-exec-4] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `com.siam.HRAssistTool.Entity.Vehicule` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (1); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.siam.HRAssistTool.Entity.Vehicule` (although at least one Creator exists): no int/Int-argument constructor/factory method to deserialize from Number value (1)
 at [Source: (PushbackInputStream); line: 8, column: 20] (through reference chain: com.siam.HRAssistTool.Entity.Schedule["vehicule"])]

我的日程安排實體:

@Entity
public class Schedule implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id ; 
    private Date date ; 
    private String Start; 
    private String destination;
    @OneToOne( fetch = FetchType.LAZY)
    private Staff driver; 
    @OneToOne(fetch = FetchType.LAZY)
    private Vehicule vehicule; 
    private String provider;
    //constructors, getters and setters 
}

我的控制器:

@RestController
public class ScheduleController {

    @Autowired
    ScheduleService scheduleService; 

    @PostMapping(value="/schedule/create")
    public @ResponseBody String createSchedule( @RequestBody Schedule schedule) {
        System.out.println(schedule.toString());

        return scheduleService.addSchedule(schedule);
        
    }
//other crud operation
}

首先,將Date替換為LocalDate ,它是新的 Java Time API 的一部分。 有了這個,您可以配置 Jackson 以輕松處理這種復雜類型的序列化和反序列化。 添加以下依賴項:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.11.0</version>
</dependency>

然后相應地配置傑克遜:

@Configuration
public class JacksonConfiguration {

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        objectMapper.registerModule(javaTimeModule);

    objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

        return objectMapper;
    }
}

然后,請避免在您的Controller使用 Entities 作為響應或請求類型。 相反,使用 DTO,它是您的核心模型實體的特定表示。

public class ScheduleCreationDto {
    private LocalDate date; 
    private String Start; 
    private String destination;
    private Long driverId;      // I am guessing the ID is a Long
    private Long vehiculeId;    // I am guessing the ID is a Long
    private String provider;
    
    //constructors, getters and setters 
}

這現在應該用作請求正文:

@RestController
public class ScheduleController {

    @Autowired
    ScheduleService scheduleService; 

    @PostMapping(value="/schedule/create")
    public @ResponseBody String createSchedule(@RequestBody ScheduleCreationDto scheduleCreationDto) {
        return scheduleService.addSchedule(schedule);
    }
    
    //other crud operation
}

你還需要改變ScheduleService ,這樣它會創建一個Schedule根據ScheduleCreationDto 大多數的屬性需要一個簡單的映射,但其他人( driverIdvehiculeId )要求您使用提供的ID實際上從數據庫獲得這些實體。 應該在您的ScheduleService完成類似於以下內容的操作:

@Service
public class ScheduleService {

    @Autowired
    ScheduleRepository scheduleRepository; 

    @Autowired
    DriverRepository driverRepository; 

    @Autowired
    VehiculeRepository vehiculeRepository; 

    public String addSchedule(ScheduleCreationDto scheduleCreationDto) {
        Driver driver = driverRepository.findById(scheduleCreationDto.getDriverId());
        Vehicule vehicule = vehiculeRepository.findById(scheduleCreationDto.getVehiculeId());

        Schedule schedule = new Schedule(scheduleCreationDto.getDate(), scheduleCreationDto.getStart(), 
            scheduleCreationDto.getDestination(), driver, vehicule, scheduleCreationDto.getProvider());
        scheduleRepository.save(schedule);    
    
        return // whatever String you want to return, you should actually return the created Schedule, but that is a different topic
    }

    //other crud operation
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM