我想使用Jackson从JSON填充POJO。我的样品请求是-
POST /lab2/person?firstname=John&lastname=Doe&email=john.doe@anony.com&street=190 South&city=Houston&state=TX&zip=12345
HTTP/1.1
Host: localhost:8080
Content-Type: application/json
Cache-Control: no-cache
个人-POJO
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.codehaus.jackson.annotate.JsonUnwrapped;
@Entity
@Table(name="person")
public class Person {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
@Column(nullable=false)
private String firstname;
@Column(nullable=false)
private String lastname;
@Column(nullable=false)
private String email;
private String description;
@Embedded
@JsonUnwrapped
private Address address;
@ManyToOne
@JoinColumn(referencedColumnName="id")
private Organization organization;
/**
* @return the id
*/
public long getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(long id) {
this.id = id;
}
/**
* @return the firstname
*/
public String getFirstname() {
return firstname;
}
/**
* @param firstname the firstname to set
*/
public void setFirstname(String firstname) {
this.firstname = firstname;
}
/**
* @return the lastname
*/
public String getLastname() {
return lastname;
}
/**
* @param lastname the lastname to set
*/
public void setLastname(String lastname) {
this.lastname = lastname;
}
/**
* @return the email
*/
public String getEmail() {
return email;
}
/**
* @param email the email to set
*/
public void setEmail(String email) {
this.email = email;
}
/**
* @return the description
*/
public String getDescription() {
return description;
}
/**
* @param description the description to set
*/
public void setDescription(String description) {
this.description = description;
}
/**
* @return the address
*/
public Address getAddress() {
return address;
}
/**
* @param address the address to set
*/
public void setAddress(Address address) {
this.address = address;
}
/**
* @return the organization
*/
public Organization getOrganization() {
return organization;
}
/**
* @param org the organization to set
*/
public void setOrganization(Organization organization) {
this.organization = organization;
}
@Override
public String toString() {
return "{name : "+this.getFirstname()+" "+this.getLastname()+", email : "+this.getEmail()+", "+this.getAddress().toString()+", "+this.getOrganization().toString()+"}";
}
}
控制器方法是-
@RequestMapping(method=RequestMethod.POST)
@ResponseBody
public String addUser(@ModelAttribute Person person){
System.out.println("In person");
System.out.println(person.getFirstname()+" "+person.getLastname()+" "+person.getEmail());
System.out.println(person.getAddress().toString());
return "Welcome";
}
当我的代码运行时,我会得到firstname、lastname和email的值,而address作为对象会抛出null指针异常,并且不会被设置。
错误-
SEVERE: Servlet.service() for servlet [spring] in context with path [/lab2] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException
at com.cmpe275.lab2.controller.PersonController.addUser(PersonController.java:29)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:174)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:421)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:409)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1517)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1474)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
In person
John Doe john.doe@anony.com
如何设置地址对象值。地址POJO看起来像-
package com.cmpe275.lab2.model;
import javax.persistence.Embeddable;
@Embeddable
public class Address {
private String street;
private String city;
private String state;
private String zip;
/**
* @return the street
*/
public String getStreet() {
return street;
}
/**
* @param street the street to set
*/
public void setStreet(String street) {
this.street = street;
}
/**
* @return the city
*/
public String getCity() {
return city;
}
/**
* @param city the city to set
*/
public void setCity(String city) {
this.city = city;
}
/**
* @return the state
*/
public String getState() {
return state;
}
/**
* @param state the state to set
*/
public void setState(String state) {
this.state = state;
}
/**
* @return the zip
*/
public String getZip() {
return zip;
}
/**
* @param zip the zip to set
*/
public void setZip(String zip) {
this.zip = zip;
}
@Override
public String toString() {
return "address : "+this.getStreet()+","+this.getCity()+","+this.getState()+", "+this.getZip();
};
}
我读过各种各样的博客,但没有通用的解决方案。我不想创建自定义映射器。
我尝试了使用Person
和Address
的代码版本,并成功地序列化和反序列化了Person
对象。因此问题不在于@JsonUnwrapped
以及特定类别Person
和Address
类别。我可以想到两个潜在的原因:
- 试图反序列化的JSON文档已损坏或与POJO结构不兼容
- 您正在使用的Jackson版本已经过时,并且与其他依赖项不兼容。我可以在你的代码中看到
import org.codehaus.jackson.annotate.JsonUnwrapped;
,那是Jackson的旧版本。尝试更新的版本(例如2.5.3)并执行import com.fasterxml.jackson.annotation.JsonUnwrapped;