如何将 json 发送到 rest 服务以使 Jersey 将其解析为 POJO?

How to send json to rest service to make Jersey to parse it as a POJO?

这是我的代码,使用 jquery:

进行 ajax 调用
$.get("/login", { token: { name:"Donald", password:"Ducktown" }} , 
     function (data) {
            console.log(data);
 });

这是我的 POJO:

public class Token {

    private String name;

    private String password;

    public Token() {}

    //+getters, setters, toString
}

这是我的休息服务:

@Path("login")
public class LoginService {
    
    private static final Logger logger = LoggerFactory.getLogger(LoginService.class);

    @GET
    @Consumes(MediaType.APPLICATION_JSON)
    public void login(Token token) {
        logger.info("Token={}", token);
    }
}

这是输出:

12:16:12.211 [qtp967677821-35] [INFO] com.foo.LoginService - Token=null

请说明如何正确发送 json 以使 Jersey 将其解析为 POJO。

这是 Jersey 配置信息,在 Jersey 启动时打印在日志中:

Root Resource Classes: com.foo.LoginService

Pre-match Filters:
org.apache.shiro.web.jaxrs.SubjectPrincipalRequestFilter

Global Response Filters: com.foo.CORSFilter

Global Reader Interceptors:
org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor

Global Writer Interceptors:
org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor

Dynamic Features:
org.apache.shiro.web.jaxrs.ShiroAnnotationFilterFeature@204beb58

Message Body Readers:
org.glassfish.jersey.message.internal.RenderedImageProvider
org.glassfish.jersey.message.internal.SourceProvider$SaxSourceReader
org.glassfish.jersey.message.internal.FormProvider
org.glassfish.jersey.message.internal.SourceProvider$DomSourceReader
org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJaxbJsonProvider org.glassfish.jersey.message.internal.StringMessageProvider
org.glassfish.jersey.message.internal.FormMultivaluedMapProvider
org.glassfish.jersey.message.internal.SourceProvider$StreamSourceReader org.glassfish.jersey.message.internal.InputStreamProvider
org.glassfish.jersey.message.internal.ByteArrayProvider
org.glassfish.jersey.message.internal.ReaderProvider
org.glassfish.jersey.message.internal.DataSourceProvider
org.glassfish.jersey.message.internal.BasicTypesMessageProvider
org.glassfish.jersey.message.internal.FileProvider

Message Body Writers:
org.glassfish.jersey.message.internal.RenderedImageProvider
org.glassfish.jersey.message.internal.FormProvider
org.glassfish.jersey.server.ChunkedResponseWriter
org.glassfish.jersey.server.validation.internal.ValidationErrorMessageBodyWriter org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJaxbJsonProvider org.glassfish.jersey.message.internal.StringMessageProvider
org.glassfish.jersey.message.internal.FormMultivaluedMapProvider
org.glassfish.jersey.message.internal.InputStreamProvider
org.glassfish.jersey.message.internal.SourceProvider$SourceWriter
org.glassfish.jersey.message.internal.ByteArrayProvider
org.glassfish.jersey.message.internal.ReaderProvider
org.glassfish.jersey.message.internal.DataSourceProvider
org.glassfish.jersey.message.internal.StreamingOutputProvider
org.glassfish.jersey.message.internal.BasicTypesMessageProvider
org.glassfish.jersey.message.internal.FileProvider

这些是我对 Jersey 的依赖。作为 gson 解析器,我尝试使用 jackson:

    <module groupId="jakarta.validation" artifactId="jakarta.validation-api" version="2.0.2"/>
    <module groupId="com.sun.activation" artifactId="jakarta.activation" version="1.2.1"/>
    <module groupId="jakarta.ws.rs" artifactId="jakarta.ws.rs-api" version="2.1.6"/>
    <module groupId="jakarta.xml.bind" artifactId="jakarta.xml.bind-api" version="2.3.2"/>
    <module groupId="com.google.code.gson" artifactId="gson" version="2.8.6"/>
    <module groupId="com.fasterxml" artifactId="classmate" version="1.5.1"/>
    <module groupId="com.sun.xml.bind" artifactId="jaxb-impl" version="2.3.2"/>
    <module groupId="javax.enterprise" artifactId="cdi-api" version="1.1"/>
    <module groupId="org.glassfish.hk2.external" artifactId="jakarta.inject" version="2.6.1"/>
    <module groupId="org.glassfish.hk2" artifactId="hk2-api" version="2.6.1"/>
    <module groupId="org.glassfish.hk2" artifactId="hk2-utils" version="2.6.1"/>
    <module groupId="org.glassfish.hk2" artifactId="hk2-locator" version="2.6.1"/>
    <module groupId="org.glassfish.hk2" artifactId="spring-bridge" version="2.6.1"/>
    <module groupId="org.glassfish.jersey.containers" artifactId="jersey-container-jetty-http" version="2.30.1"/>
    <module groupId="org.glassfish.jersey.containers" artifactId="jersey-container-servlet-core" version="2.30.1"/>
    <module groupId="org.glassfish.jersey.core" artifactId="jersey-server" version="2.30.1"/>
    <module groupId="org.glassfish.jersey.core" artifactId="jersey-common" version="2.30.1"/>
    <module groupId="org.glassfish.jersey.core" artifactId="jersey-client" version="2.30.1"/>
    <module groupId="org.glassfish.jersey.ext" artifactId="jersey-bean-validation" version="2.30.1"/>
    <module groupId="org.glassfish.jersey.ext.cdi" artifactId="jersey-cdi1x" version="2.30.1"/>
    <module groupId="org.glassfish.jersey.ext.cdi" artifactId="jersey-cdi1x-servlet" version="2.30.1"/>
    <module groupId="org.glassfish.jersey.inject" artifactId="jersey-hk2" version="2.30.1"/>
    <module groupId="org.glassfish.jersey.ext" artifactId="jersey-spring5" version="2.30.1"/>
    <module groupId="com.sun.istack" artifactId="istack-commons-runtime" version="4.0.1"/>
    <module groupId="org.javassist" artifactId="javassist" version="3.27.0-GA"/>

    <module groupId="org.glassfish.jersey.ext" artifactId="jersey-entity-filtering" version="2.30.1"/>
    <module groupId="org.glassfish.jersey.media" artifactId="jersey-media-json-jackson" version="2.30.1"/>
    <module groupId="com.fasterxml.jackson.core" artifactId="jackson-annotations" version="2.10.2"/>
    <module groupId="com.fasterxml.jackson.core" artifactId="jackson-core" version="2.10.2"/>
    <module groupId="com.fasterxml.jackson.core" artifactId="jackson-databind" version="2.10.2"/>
    <module groupId="com.fasterxml.jackson.module" artifactId="jackson-module-jaxb-annotations" version="2.10.2"/>
    <module groupId="com.fasterxml.jackson.jaxrs" artifactId="jackson-jaxrs-json-provider" version="2.10.2"/>
    <module groupId="com.fasterxml.jackson.jaxrs" artifactId="jackson-jaxrs-base" version="2.10.2"/>

编辑 1 当我更改为 post(在 javascript 和登录服务中)时,我得到:

13:41:00.345 [qtp967677821-38] [WARN] org.glassfish.jersey.servlet.WebComponent - A servlet request to the URI http://127.0.0.1:8080/login contains form parameters in the request body but the request body has been consumed by the servlet or a servlet filter accessing the request parameters. Only resource methods using @FormParam will work as expected. Resource methods consuming the request body by other means will not work as expected.
13:41:00.359 [qtp967677821-38] [TRACE] org.glassfish.jersey.server.ServerRuntime$Responder - Starting mapping of the exception.
javax.ws.rs.NotSupportedException: HTTP 415 Unsupported Media Type
    at org.glassfish.jersey.server.internal.routing.MethodSelectingRouter.getMethodRouter(MethodSelectingRouter.java:412) ~[jersey-server-2.30.1.jar:?]
    at org.glassfish.jersey.server.internal.routing.MethodSelectingRouter.access[=16=]0(MethodSelectingRouter.java:73) ~[jersey-server-2.30.1.jar:?]
    at org.glassfish.jersey.server.internal.routing.MethodSelectingRouter.apply(MethodSelectingRouter.java:665) ~[jersey-server-2.30.1.jar:?]
    at org.glassfish.jersey.server.internal.routing.MethodSelectingRouter.apply(MethodSelectingRouter.java:305) ~[jersey-server-2.30.1.jar:?]
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:86) ~[jersey-server-2.30.1.jar:?]
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:89) ~[jersey-server-2.30.1.jar:?]
    at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:89) ~[jersey-server-2.30.1.jar:?]
    at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:69) ~[jersey-server-2.30.1.jar:?]
    at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:38) ~[jersey-server-2.30.1.jar:?]
    at org.glassfish.jersey.process.internal.Stages.process(Stages.java:173) ~[jersey-common-2.30.1.jar:?]
    at org.glassfish.jersey.server.ServerRuntime.run(ServerRuntime.java:245) ~[jersey-server-2.30.1.jar:?]

根据您所拥有的,它应该适用于此:

$.get("/login", {name:"Donald", password:"Ducktown"} , 
     function (data) {
            console.log(data);
 });

您的 POJO 映射具有字段 name, password,因此您的 JSON 应该只包含它们:

ublic class Token {

    private String name;

    private String password;

    public Token() {}

    //+getters, setters, toString
}

当您发送 { token: { name:"Donald", password:"Ducktown" }} 时,您表示您的 Pojo 应该如下所示:

public class TokenWrapper {

    private Token token;
}


public class Token {

    private String name;

    private String password;

}

并且您的 API 端点应更改为:

    @GET
    @Consumes(MediaType.APPLICATION_JSON)
    public void login(TokenWrapper token) {
        logger.info("Token={}", token);
    }