使用Angular和Java EE将Date添加到DB时出错



对于一个简单的客户管理应用程序,我在添加出生日期时遇到了问题!

这是我的html:

<label for="dob" class="firstThreeInputs">Date of Birth: </label>
<input type="date" [(ngModel)]="customer.dateOfBirth" class="" id="dateOfBirthInput" name="dateOfBirth" placeholder="Date of Birth">

当我添加新客户或编辑现有客户时,我会收到以下错误:

Failed executing PUT /customers/6: org.jboss.resteasy.spi.ReaderException: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.LocalDate` (no Creators, like default construct, exist): no String-argument constructor/factory method to deserialize from String value ('2018-12-12')

看起来这是一个常见的问题,Jackson有一个解决方案,但我不知道如何在我的应用程序中实现它。

以下是我的客户类别:

import java.time.LocalDate;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
//Data and Integration
@Entity
@Table(name ="basic_info")
@NamedQuery(name="Customers.selectAll", query="SELECT n From Customers n")
public class Customers {
	@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
	private Long id;
	@Column(length=100, nullable=false)
	private String first_name;
	
	@Column(length=100, nullable=false)
	private String last_name;
	
	@Column(length=100, nullable=false)
	private String country_code;
	
	@Column(length=100, nullable=false)
	private String gender;
	
	@Column(nullable=false)
	private LocalDate dateOfBirth;
	
	@Column(nullable=false)
	private boolean isActive;
	
	
	public Customers() {}
	
	public Customers(Long id, String first_name, String last_name, LocalDate dateOfBirth) {
		this.id = id;
		this.first_name = first_name;
		this.last_name = last_name;
		this.dateOfBirth = dateOfBirth;
	}
	
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	
	public String getFirstName() {
		return first_name;
	}
	
	public void setFirstName(String first_name) {
		this.first_name = first_name;
	}
	
	public String getLastName() {
		return last_name;
	}
	
	public void setLastName(String last_name) {
		this.last_name = last_name;
	}
	
	public LocalDate getDateOfBirth() {
		return dateOfBirth;
	}
	
	public void setDateOfBirth(LocalDate dateOfBirth) {
		this.dateOfBirth = dateOfBirth;
	}
	
	public String getCountryCode() {
		return country_code;
	}
	
	public void setCountryCode(String country_code) {
		this.country_code = country_code;
	}
	
	public String getGender() {
		return gender;
	}
	
	public void setGender(String gender) {
		this.gender = gender;
	}
	
	public boolean getActiveStatus() {
		return isActive;
	}
	
	public void setActiveStatus(boolean isActive) {
		this.isActive = isActive;
	}
	
	
	@Override
	public String toString() {
		return "Cusomters [id=" + id + ", First Name =" + first_name + ", Last Name=" + last_name + " DateOfBirth="+ dateOfBirth +" Gender= " + gender + "CountryCode=" + country_code + "]";
	}
	
}

我如何添加Jackson代码,以便在PUT/POST时将JSON转换为Java,而在GET期间则相反?如何使用ObjectMapper和JavaTimeModule?

下面是我的客户资源类:

package at.technikumwien.webf;
import java.net.URI;
import java.util.List;
import java.util.logging.Logger;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.core.Response.Status;
@Path("/customers")
@Consumes(MediaType.APPLICATION_JSON)	
@Produces(MediaType.APPLICATION_JSON)
public class CustomersResource {
	private static final Logger LOGGER = Logger.getLogger(CustomersResource.class.getName());
	
	@PersistenceContext
	private EntityManager em; 
	
	@Inject
	private CustomersService customersService;
	
	@Context
	private UriInfo uriInfo;
	
	@POST
	@Transactional
	public Response create(Customers customer) {
		LOGGER.info("create >> customer=" + customer);
	
		em.persist(customer);
		URI uri = uriInfo.getAbsolutePathBuilder().path(customer.getId().toString()).build();
		return Response.created(uri).build();
		
	}
	
	@PUT
	@Path("/{id}")
	@Transactional
	public void update(@PathParam("id") long id, Customers customerUpdate) {
		LOGGER.info("update >> id=" + id + ", customer=" + customerUpdate);
		Customers customerOld = em.find(Customers.class, id);
			if ( customerOld != null) {
				customerOld.setFirstName(customerUpdate.getFirstName());
				customerOld.setLastName(customerUpdate.getLastName());
				customerOld.setDateOfBirth(customerUpdate.getDateOfBirth());
				customerOld.setGender(customerUpdate.getGender());
				customerOld.setCountryCode(customerUpdate.getCountryCode());
				customerOld.setActiveStatus(customerUpdate.getActiveStatus());
			}
			
			else {
				throw new WebApplicationException(Status.NOT_FOUND);
			}
	}
	
	
	@DELETE
	@Path("/{id}")
	@Transactional
	public void delete(@PathParam("id") long id) {
		LOGGER.info("delete >> id=" + id);
		
		Customers customer = em.find(Customers.class, id);
		if (customer != null) {
			em.remove(customer);
		}
		else {
			throw new WebApplicationException(Status.NOT_FOUND);
		}
	}
	
	@GET
	@Path("/{id}")
	public Customers retrieve(@PathParam("id") long id) {
		LOGGER.info("retrieve id=" + id);	
		return em.find(Customers.class, id);
	}
	
	
	@GET
	@Path("/")
	public List<Customers> retrieveAll() {
		LOGGER.info("retrieveAll");
		return customersService.getAllCustomers();
	}
	
}

正如您的错误所解释的,java.time类(如LocalDate(没有公共构造函数。没有new LocalDate。相反,这些类使用工厂方法,如这些命名约定所示。

LocalDate today = LocalDate.now() ;  // Tip: Better to pass a `ZoneId`.
LocalDate tomorrow = today.plusDays( 1 ) ;  // Immutable objects. So a new fresh `LocalDate` is instantiated based on values copied from original object. 
LocalDate someDay = LocalDate.parse( "2020-01-23" ) ; 

您的代码显然需要一个无arg构造函数。当然没有找到。

使用Jackson处理LocalDate的主题已经在Stack Overflow上进行了多次讨论。

我发现了一个很棒的博客,它解释了这一点:

https://kodejava.org/how-to-format-localdate-object-using-jackson/

最新更新