【发布时间】:2022-01-27 22:02:00
【问题描述】:
我正在开发我的第一个 REST API,我让它工作了一分钟。基本上,我有一个实体类User,它引用了另一个数据库表Bookmark。我在该字段中使用了@JsonIgnore 将其从User 的JSON 表示中排除:
import org.codehaus.jackson.annotate.JsonIgnore;
import javax.persistence.*;
@Entity
@Table(name = "user")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private String id;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "user", fetch = FetchType.LAZY)
@JsonIgnore
private List<Bookmark> bookmarks = new ArrayList<>();
@Column(name = "name")
private String name;
}
为了让它运行,我添加了一个Application 类(暂时为空):
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("/api")
public class RestApplication extends Application {
}
最后,我使用了我的旧 UserService 并添加了一个 REST 端点:
@Dependent
@Named
@Path("/userService")
public class UserService {
@Inject
private UserDAO userDAO;
@GET
@Path("/getUserById/{id}")
@Produces(MediaType.APPLICATION_JSON)
public User getUserById(@PathParam("id") String id) {
return userDAO.getUserById(id);
}
}
现在我能够访问.../api/userService/getUserById/XYZ 并取回User 的JSON 表示,仅包括id 和name。
但是,当尝试从在同一台机器上运行的第二个项目访问 API 时,我偶然发现了启用跨域资源共享的必要性。我通过遵循许多在线指南并实现了CorsFilter:
import java.io.IOException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;
@Provider
public class CorsFilter implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
throws IOException {
responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
responseContext.getHeaders().add("Access-Control-Allow-Credentials", "true");
responseContext.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
responseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
}
}
一开始它没有效果,但是当我将CorsFilter.class 包含在RestApplication 的getClasses() 方法中时它起作用了。卷曲 API 现在显示启用了 CORS 的正确标头,但端点没有返回任何内容,因此我还包括了 UserService.class。
那是我现在的RestApplication 课程:
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("/api")
public class RestApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
final Set<Class<?>> classes = new HashSet<>();
classes.add(UserService.class);
classes.add(CorsFilter.class);
return classes;
}
}
但是,现在我得到了臭名昭著的RESTEASY008205: JSON Binding serialization error org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.xyz.User.bookmarks, could not initialize proxy - no Session。顺便说一句,尝试访问不同的端点会导致RESTEASY008205: JSON Binding serialization error javax.json.bind.JsonbException: Error getting value on: org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor@2ba18598,即使我无法弄清楚两个端点之间的区别。
此时我有点迷茫,当我尝试添加过滤器时一切都走下坡路了。关于我哪里出错的任何建议?
顺便说一句,它在 jboss-eap-7.2 上运行,我在我的 POM 中添加了以下依赖项以访问 org.codehaus.jackson.annotate.JsonIgnore:
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
<version>3.6.1.SP2</version>
</dependency>
【问题讨论】:
-
您需要使用 Jackson 还是 Jakarta JSON Binding 可以工作?你可以改用
javax.json.bind.annotation.JsonbTransient。
标签: json jboss jax-rs resteasy