使用 postman post 请求后 spring boot 服务器 returns 错误 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时间API的一部分。有了这个,您可以配置 Jackson 来轻松处理这种复杂类型的序列化和反序列化。添加以下依赖项:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.11.0</version>
</dependency>
然后相应地配置 Jackson:
@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
中使用实体作为响应或请求类型。相反,使用作为核心模型实体的特定表示的 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
,以便它创建一个基于 ScheduleCreationDto
的 Schedule
。大多数属性需要一个简单的映射,但其他属性(driverId
和 vehiculeId
)需要您使用提供的 ID 从数据库中实际获取这些实体。应该在您的 ScheduleService
:
中完成类似于以下内容的操作
@Service
public class ScheduleService {
@Autowired
ScheduleRepository scheduleRepository;
@Autowired
DriverRepository driverRepository;
@Autowired
VehiculeRepository vehiculeRepository;
public String addSchedule(ScheduleCreationDto scheduleCreationDto) {
Optional<Driver> driver = driverRepository.findById(scheduleCreationDto.getDriverId());
Optional<Vehicule> vehicule = vehiculeRepository.findById(scheduleCreationDto.getVehiculeId());
if (driver.isPresent() && vehicule.isPresent()) {
Schedule schedule = new Schedule(scheduleCreationDto.getDate(), scheduleCreationDto.getStart(),
scheduleCreationDto.getDestination(), driver.get(), vehicule.get(), 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
}
每当我尝试通过邮递员发送时:
{
"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时间API的一部分。有了这个,您可以配置 Jackson 来轻松处理这种复杂类型的序列化和反序列化。添加以下依赖项:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.11.0</version>
</dependency>
然后相应地配置 Jackson:
@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
中使用实体作为响应或请求类型。相反,使用作为核心模型实体的特定表示的 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
,以便它创建一个基于 ScheduleCreationDto
的 Schedule
。大多数属性需要一个简单的映射,但其他属性(driverId
和 vehiculeId
)需要您使用提供的 ID 从数据库中实际获取这些实体。应该在您的 ScheduleService
:
@Service
public class ScheduleService {
@Autowired
ScheduleRepository scheduleRepository;
@Autowired
DriverRepository driverRepository;
@Autowired
VehiculeRepository vehiculeRepository;
public String addSchedule(ScheduleCreationDto scheduleCreationDto) {
Optional<Driver> driver = driverRepository.findById(scheduleCreationDto.getDriverId());
Optional<Vehicule> vehicule = vehiculeRepository.findById(scheduleCreationDto.getVehiculeId());
if (driver.isPresent() && vehicule.isPresent()) {
Schedule schedule = new Schedule(scheduleCreationDto.getDate(), scheduleCreationDto.getStart(),
scheduleCreationDto.getDestination(), driver.get(), vehicule.get(), 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
}