JSON 구문 분석 오류: java.time 인스턴스를 생성할 수 없습니다.LocalDate: String 값에서 역직렬화할 문자열 인수 생성자/공장 메서드가 없습니다.
저는 Spring Data REST 프로젝트에 처음 참여하며 첫 RESTful 서비스를 만들려고 합니다.그 일은 간단하지만, 나는 꼼짝할 수 없다.
RESTful API를 사용하여 임베디드 데이터베이스에 저장된 사용자 데이터에 대해 CRUD 작업을 수행하고 싶습니다.
그러나 Spring 프레임워크에서 birthData를 "1999-12-15"로 처리하여 LocalDate로 저장하는 방법을 알 수 없습니다.@JsonFormat 주석은 도움이 되지 않습니다.
현재 다음과 같은 오류가 표시됩니다.
HTTP/1.1 400
Content-Type: application/hal+json;charset=UTF-8
Transfer-Encoding: chunked
Date: Thu, 24 Aug 2017 13:36:51 GMT
Connection: close
{"cause":{"cause":null,"message":"Can not construct instance of java.time.LocalDate:
no String-argument constructor/factory method to deserialize from String value ('1999-10-10')\n
at [Source: org.apache.catalina.connector.CoyoteInputStream@4ee2a60e;
line: 1, column: 65] (through reference chain: ru.zavanton.entities.User[\"birthDate\"])"},
"message":"JSON parse error: Can not construct instance of java.time.LocalDate:
no String-argument constructor/factory method to deserialize from String value ('1999-10-10'); nested exception is com.fasterxml.jackson.databind.JsonMappingException:
Can not construct instance of java.time.LocalDate: no String-argument constructor/factory method to deserialize from String value ('1999-10-10')\n
at [Source: org.apache.catalina.connector.CoyoteInputStream@4ee2a60e; line: 1, column: 65] (through reference chain: ru.zavanton.entities.User[\"birthDate\"])"}
클라이언트가 다음과 같이 호출할 수 있도록 하는 방법:
curl -i -X POST -H "Content-Type:application/json" -d "{ \"firstName\" : \"John\", \"lastName\" : \"Johnson\", \"birthDate\" : \"1999-10-10\", \"email\" : \"john@example.com\" }" http://localhost:8080/users
는 실제로 엔티티를 데이터베이스에 저장합니다.
다음은 수업에 대한 정보입니다.
사용자 클래스:
package ru.zavanton.entities;
import com.fasterxml.jackson.annotation.JsonFormat;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.time.LocalDate;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String firstName;
private String lastName;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private LocalDate birthDate;
private String email;
private String password;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public LocalDate getBirthDate() {
return birthDate;
}
public void setBirthDate(LocalDate birthDate) {
this.birthDate = birthDate;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
UserRepository 클래스:
package ru.zavanton.repositories;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import ru.zavanton.entities.User;
@RepositoryRestResource(collectionResourceRel = "users", path = "users")
public interface UserRepository extends PagingAndSortingRepository<User, Long> {
User findByEmail(@Param("email") String email);
}
응용 프로그램 클래스:
package ru.zavanton;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
이 시리얼화 및 시리얼화 해제에는 잭슨의 의존관계가 필요합니다.
다음 종속성 추가:
그라들:
compile("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.4")
메이븐:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
그 후 Jackson Object Mapper에게 Java Time Module을 사용하도록 지시해야 합니다.이를 수행하려면 메인클래스에서 Autoowire ObjectMapper를 사용하여 JavaTimeModule을 등록합니다.
import javax.annotation.PostConstruct;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
@SpringBootApplication
public class MockEmployeeApplication {
@Autowired
private ObjectMapper objectMapper;
public static void main(String[] args) {
SpringApplication.run(MockEmployeeApplication.class, args);
}
@PostConstruct
public void setUp() {
objectMapper.registerModule(new JavaTimeModule());
}
}
그런 다음 LocalDate와 LocalDateTime을 올바르게 시리얼화 및 역직렬화해야 합니다.
스프링 부츠 2.2.2 / 그래들:
그라들(build.gradle):
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310")
엔티티(User.class):
LocalDate dateOfBirth;
코드:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
User user = mapper.readValue(json, User.class);
비슷한 문제가 있어서 두 가지 변경으로 해결했습니다.
- 다음 엔트리가 에
application.yaml파일
spring:
jackson:
serialization.write_dates_as_timestamps: false
- POJO에 다음 두 개의 주석을 추가합니다.
LocalDate들판
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
예
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
public class Customer {
@JsonDeserialize(using = LocalDateDeserializer.class)
@JsonSerialize(using = LocalDateSerializer.class)
protected LocalDate birthdate;
}
요청 형식 예:
{"birthdate": "2019-11-28"}
어레이로서의 요청 형식 예시
{"birthdate":[2019,11,18]}
알고 보니 pom 파일에 jacson 의존성을 포함시키는 것을 잊지 말아야 합니다.이것으로 문제가 해결되었습니다.
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-parameter-names</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
음, 모든 프로젝트에서 제가 하는 일은 위의 옵션들을 혼합한 것입니다.
먼저 jsr310 의존관계를 추가합니다.
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
중요 세부사항: 이 의존관계를 부서 목록의 맨 위에 배치합니다.pom.xml에 의존해도 Localdate 오류가 지속되는 프로젝트가 보입니다.하지만 부서 순서를 바꾸자 오류가 사라졌습니다.
온 유저희쪽에서/src/main/resources/application.yml파일, 셋업write-dates-as-timestamps속성:
spring:
jackson:
serialization:
write-dates-as-timestamps: false
또, 작성한다.ObjectMapper다음과 같은 콩:
@Configuration
public class WebConfigurer {
@Bean
@Primary
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.build();
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
return objectMapper;
}
}
이 설정에 따라 Spring Boot 1.5.x에서는 항상 오류 없이 변환이 동작합니다.
보너스: 스프링 AMQP 큐 설정
AMQP와 Spring AMQP 가 있는지 하십시오.Jackson2JsonMessageConverter)SimpleRabbitListenerContainerFactory.ObjectMapper예를 들어 다음과 같습니다.
Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter(objectMapper);
그렇지 않으면 동일한 오류가 발생합니다.
나는 이것과 3시간 동안 씨름했다.Dherik(AMQP에 관한 Bonus 자료)의 답변이 나의 답변 YMMV와 가까운 거리에 있다고 생각합니다.
Spring Boot Application의 객체매퍼에 Java Time Module을 다음과 같이 등록했습니다.
@Bean
@Primary
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.build();
objectMapper.registerModule(new JavaTimeModule());
return objectMapper;
}
그러나 STOP 접속을 통해 들어오는 내 인스턴스는 여전히 역직렬화되지 않았다.그리고 두 번째 ObjectMapper를 작성하는 MappingJackson2MessageConverter를 실수로 작성했다는 것을 알게 되었습니다.이 이야기의 교훈은 다음과 같습니다.오브젝트 맵을 모두 조정하셨습니까?제 경우 MappingJackson2MessageConverter.objectMapper를 JavaTimeModule이 등록된 외부 버전으로 교체했습니다.모든 것이 정상입니다.
@Autowired
ObjectMapper objectMapper;
@Bean
public WebSocketStompClient webSocketStompClient(WebSocketClient webSocketClient,
StompSessionHandler stompSessionHandler) {
WebSocketStompClient webSocketStompClient = new WebSocketStompClient(webSocketClient);
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setObjectMapper(objectMapper);
webSocketStompClient.setMessageConverter(converter);
webSocketStompClient.connect("http://localhost:8080/myapp", stompSessionHandler);
return webSocketStompClient;
}
언급URL : https://stackoverflow.com/questions/45863678/json-parse-error-can-not-construct-instance-of-java-time-localdate-no-string-a
'programing' 카테고리의 다른 글
| 페이지를 갱신하지 않고 URI를 변경하려면 어떻게 해야 합니까? (0) | 2023.03.10 |
|---|---|
| 워드프레스 테마에서 쇼트코드 사용 (0) | 2023.03.10 |
| 어떻게 하면 AngularJS에서 $watching을 멈출 수 있나요? (0) | 2023.03.10 |
| URL의 각도 변경을 위한 IIS 설정 방법HTML5 모드의 JS 어플리케이션 (0) | 2023.03.10 |
| 스프링 부츠의 장점 (0) | 2023.03.10 |