【问题标题】:Jax-RS @JsonIgnore not working after adding the service endpoint to Application.getClasses将服务端点添加到 Application.getClasses 后,Jax-RS @JsonIgnore 不起作用
【发布时间】: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 表示,仅包括idname

但是,当尝试从在同一台机器上运行的第二个项目访问 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 包含在RestApplicationgetClasses() 方法中时它起作用了。卷曲 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


【解决方案1】:

根据规范:

当档案中存在 Application 子类时,如果 Application.getClasses 和 Application.getSingletons 返回一个空集合,则必须包含打包在 Web 应用程序中的所有根资源类和提供程序,并且需要 JAX-RS 实现如上所述,通过扫描 .war 文件自动发现它们。如果 getClasses 或 getSingletons 返回非空集合,则只有返回的类或单例必须包含在已发布的 JAX-RS 应用程序中。

因此,一旦您提供了 getClasses 覆盖,自动发现就会关闭,您必须明确注册资源和提供者,包括 Jackson 功能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多