Java Spring Jersey JSON POJO序列化问题
我正在为我的Spring项目开发一个RESTAPI。为此,我一直在使用球衣 我的控制器如下所示:Java Spring Jersey JSON POJO序列化问题,java,json,spring,serialization,jersey,Java,Json,Spring,Serialization,Jersey,我正在为我的Spring项目开发一个RESTAPI。为此,我一直在使用球衣 我的控制器如下所示: @Path("movies") @Component public class MovieController { @Autowired MoviesService moviesService; @GET @Produces({MediaType.APPLICATION_JSON}) public Response getAll(@QueryParam("count") in
@Path("movies")
@Component
public class MovieController {
@Autowired
MoviesService moviesService;
@GET
@Produces({MediaType.APPLICATION_JSON})
public Response getAll(@QueryParam("count") int rowsPerPage, @QueryParam("page") int page){
PaginationResponse<List<Movie>> response = moviesService.getList(page,rowsPerPage);
if(response==null){
return Response.noContent().build();
}
return Response.ok(response).build();
}
}
出于某种原因,电影POJO似乎是通过调用对象的toString()方法序列化的,该方法显然不是电影对象的JSON表示形式。
下面是电影和分页响应类的摘录
电影课
@Entity
@Table(name = "movies")
public class Movie {
@Column(name = "image")
private byte[] img;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@SequenceGenerator(sequenceName = "movies_movieid_seq", name = "movies_movieid_seq", allocationSize = 1)
@Column(name = "movieid", nullable = false)
private long id;
@Column(name = "title")
private String name;
@Column
private double rating;
@Column(name = "releasedate", columnDefinition="DATE")
private Date releaseDate;
@Column
private int runtime;
@Column
private String genres;
@Column
private boolean active;
@Column
private String trailer;
@Column
private String summary;
@Column
private String director;
@Column
private String actors;
@Column
private String restriction;
@JsonIgnore
@OneToMany(mappedBy = "movie",fetch = FetchType.EAGER, orphanRemoval = true)
private List<Screening> screenings;
public Movie(){}
public Movie(long id, String name, float rating, Date releaseDate, int runtime, String genres, byte[] img, String trailer,
String summary, String director, String actors, String restriction){
this.id = id;
this.name = name;
this.rating = rating;
this.releaseDate = releaseDate;
this.runtime = runtime;
this.genres = genres;
this.img = img;
this.active = true;
this.trailer= trailer;
this.summary = summary;
this.director = director;
this.actors = actors;
this.restriction = restriction;
}
//Getters and Setters for all properties
}
@实体
@表(name=“movies”)
公映{
@列(name=“image”)
专用字节[]img;
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
@SequenceGenerator(sequenceName=“movies\u movieid\u seq”,name=“movies\u movieid\u seq”,allocationSize=1)
@列(name=“movieid”,null=false)
私人长id;
@列(name=“title”)
私有字符串名称;
@纵队
私人双重评级;
@列(name=“releasedate”,columnDefinition=“DATE”)
私人日期发布日期;
@纵队
私有int运行时;
@纵队
私人弦乐流派;
@纵队
私有布尔活动;
@纵队
私家拖车;
@纵队
私有字符串摘要;
@纵队
私有字符串控制器;
@纵队
私人弦乐演员;
@纵队
私有字符串限制;
@杰索尼奥雷
@OneToMany(mappedBy=“movie”,fetch=FetchType.EAGER,orphan=true)
私人名单筛选;
公共电影(){}
公共电影(长id、字符串名称、浮动评级、日期发布日期、int运行时、字符串类型、字节[]img、字符串预告片、,
字符串摘要、字符串控制器、字符串参与者、字符串限制){
this.id=id;
this.name=名称;
这个。评级=评级;
this.releaseDate=releaseDate;
this.runtime=运行时;
this.genres=流派;
this.img=img;
this.active=true;
这个。拖车=拖车;
this.summary=摘要;
this.director=director;
这个。演员=演员;
这个限制=限制;
}
//所有属性的getter和setter
}
分页响应类
public class PaginationResponse<T extends List> {
private boolean hasNext;
private boolean hasPrevious;
private T content;
public interface Paginageable<T>{
T getData(int querySize, int queryStart);
}
public PaginationResponse(int page, int rowsPerPage, Paginageable<T> paginageable)
{
fetchPage(page, rowsPerPage, paginageable);
}
public PaginationResponse(){}
public PaginationResponse(boolean hasNext, boolean hasPrevious, T content) {
this.hasNext = hasNext;
this.hasPrevious = hasPrevious;
this.content = content;
}
public void fetchPage(int page, int rowsPerPage, Paginageable<T> paginageable)
{
int start = page*rowsPerPage;
boolean hasPrevious=true;
boolean hasNext = false;
if(start<0){
this.hasNext=true;
this.hasPrevious=false;
this.content=null;
return;
}
int queryStart = start -1;
int querySize = rowsPerPage + 2;
if(queryStart<0){
hasPrevious=false;
queryStart = start;
querySize = rowsPerPage +1;
}
T content = paginageable.getData(querySize, queryStart);
if(content.size()==querySize){
hasNext=true;
content.remove(content.size()-1);
}
if(hasPrevious){
if(content.isEmpty())
{
hasPrevious=false;
}
else{
content.remove(0);
}
}
this.hasNext=hasNext;
this.hasPrevious=hasPrevious;
this.content=content;
}
//Getters and Setters for all properties
}
公共类分页响应{
私有布尔hasnet;
私有布尔值;
私有内容;
可分页的公共接口{
T getData(int querySize,int queryStart);
}
公共分页响应(int页,int行分页,分页可分页)
{
fetchPage(页面,行页面,可分页);
}
公共分页响应(){}
公共分页响应(布尔hasNext、布尔hasPrevious、T content){
this.hasNext=hasNext;
this.hasPrevious=hasPrevious;
this.content=内容;
}
公共void fetchPage(int page,int rowsPerPage,Paginageable Paginageable)
{
int start=page*行页面;
布尔hasPrevious=true;
布尔hasNext=false;
如果(start尝试重写Movie类中的toString()方法,那么您的响应json将正确形成。我认为您缺少Movie
类的setter和getter。对此很抱歉。为了方便起见,我从帖子中删除了它们。添加了一条注释,以说明clarifyUse Jackson是您的json提供者。
public class PaginationResponse<T extends List> {
private boolean hasNext;
private boolean hasPrevious;
private T content;
public interface Paginageable<T>{
T getData(int querySize, int queryStart);
}
public PaginationResponse(int page, int rowsPerPage, Paginageable<T> paginageable)
{
fetchPage(page, rowsPerPage, paginageable);
}
public PaginationResponse(){}
public PaginationResponse(boolean hasNext, boolean hasPrevious, T content) {
this.hasNext = hasNext;
this.hasPrevious = hasPrevious;
this.content = content;
}
public void fetchPage(int page, int rowsPerPage, Paginageable<T> paginageable)
{
int start = page*rowsPerPage;
boolean hasPrevious=true;
boolean hasNext = false;
if(start<0){
this.hasNext=true;
this.hasPrevious=false;
this.content=null;
return;
}
int queryStart = start -1;
int querySize = rowsPerPage + 2;
if(queryStart<0){
hasPrevious=false;
queryStart = start;
querySize = rowsPerPage +1;
}
T content = paginageable.getData(querySize, queryStart);
if(content.size()==querySize){
hasNext=true;
content.remove(content.size()-1);
}
if(hasPrevious){
if(content.isEmpty())
{
hasPrevious=false;
}
else{
content.remove(0);
}
}
this.hasNext=hasNext;
this.hasPrevious=hasPrevious;
this.content=content;
}
//Getters and Setters for all properties
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="paw2018b"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>TicketCentral</display-name>
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
ar.edu.itba.paw2018b.webapp.config.WebConfig,
ar.edu.itba.paw2018b.webapp.config.WebAuthConfig,
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>ar.edu.itba.paw2018b.webapp.controller</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>ROOT</url-pattern>
</servlet-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>ROOT</url-pattern>
</filter-mapping>
<error-page>
<error-code>404</error-code>
<location>/404</location>
</error-page>
<error-page>
<location>/error</location>
</error-page>
</web-app>