jackson - JAX-RS( Jersey ),Bean 验证,@JsonIgnore

标签 jackson jax-rs jersey-2.0 bean-validation jersey-test-framework

我正在使用以下方法开发示例项目:

  • JAX-RS( Jersey 2)
  • JSR-303 Bean 验证
  • 用于测试的 Jersey 测试
  • Grizzly Http 容器
  • jackson 2.7.3

在添加 @JsonIgnore 和 @JsonProperty 之前,一切都按预期工作,我能够在对对象属性执行 Bean 验证时毫无问题地运行测试。 通常,“密码”字段不应该可用于反序列化,因此我用 @JsonIgnore 标记其 getter,用 @JsonProperty 标记其 setter,以便在保存新帐户对象时允许对其进行序列化。

启动测试时,我收到 400 代码错误,并带有以下 http 响应结果:

avr. 26, 2016 12:25:29 PM org.glassfish.jersey.filter.LoggingFilter log
INFO: 1 * Client response received on thread main
1 < 400
1 < Connection: close
1 < Content-Length: 172
1 < Content-Type: application/json
1 < Date: Tue, 26 Apr 2016 11:25:29 GMT
1 < Vary: Accept
[{"message":"may not be null","messageTemplate":"{javax.validation.constraints.NotNull.message}","path":"AccountEndpoint.saveAccount.account.password","invalidValue":null}]

Note : When removing the @JsonIgnore annotation, no validation error is received of course

我的资源:

@Path("/account")
public class AccountEndpoint {

@POST
@Path("/save/")
@Produces(MediaType.APPLICATION_JSON)
public Response saveAccount(@Valid Account account){
        Account returned = accountService.saveAccount(account);
        return Response.status(200).entity(returned).build();

}

我的 Pojo 类(class):

public class Account implements Serializable {

private String username;
private String password;


// -- [username] ------------------------

@Size(max = 45)
@NotNull
@Column(name = "username", length = 45,unique=true)
public String getUsername() {
    return username;
}

public void setUsername(String username) {
    this.username = username;
}

@NotNull
@Size(max = 45)
@Column(name = "password", length = 45)
@JsonIgnore
public String getPassword() {
    return password;
}

@JsonProperty
public void setPassword(String password) {
    this.password = password;
    }
}

我的单元测试:

 public class AccountTest extends JerseyTest {

@Before
public void setUp() throws Exception {
    super.setUp();
}

@After
public void after() throws Exception {
    super.tearDown();
}

@Override
protected TestContainerFactory getTestContainerFactory() {
    return new GrizzlyWebTestContainerFactory();
}

@Override
protected DeploymentContext configureDeployment() {

    enable(TestProperties.LOG_TRAFFIC);
    enable(TestProperties.DUMP_ENTITY);

    return ServletDeploymentContext.forServlet(new ServletContainer(new
            JerseyConfig()))
            .contextParam("contextConfigLocation",TEST_APP_CONTEXT)
            .addListener(org.springframework.web.context.ContextLoaderListener.class)
            .servletPath("/").build();
}

@Test
public void testSave_New_User_Account {

    Account account = new Account();
    account.setUsername("Test");
    account.setPassword("Test");
    Response response =  target("/account/save").request().
            post(Entity.entity(account,MediaType.APPLICATION_JSON));

    assertEquals(200, response.getStatus());

}
}

JeseyConfig 类:

public class JerseyConfig extends ResourceConfig {

    public JerseyConfig() {
        packages("org.medel.endpoint");
    }
}

最佳答案

这是因为在客户端,该对象被Jackson序列化。而且由于读取时会忽略密码属性,因此它永远不会被序列化。因此,请求的发送没有密码。您可能只想为实体创建另一个测试类,不带注释,仅用于客户端测试。

编辑

为了清楚起见,问题出在客户端,而不是服务器。当客户端尝试序列化帐户时,它不会序列化密码属性,因为它被忽略。

您可以测试它,但将 JSON 作为字符串发送,这样 Jackson 就不会参与其中。你会发现它工作正常

.post(Entity.json("{\"username\":\"user\", \"password\":\"pass\"}"));

关于jackson - JAX-RS( Jersey ),Bean 验证,@JsonIgnore,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36868668/

相关文章:

java - Jersey /Jax-RS : how to filter resource and sub-resources

java - 当操作未使用 @ApiOperation 进行注释时,Swagger 会忽略 JAX-RS @Produces

java - 将 Json 转换为对象时出现 com.fasterxml.jackson.databind.JsonMappingException

java - JsonParseException : Invalid UTF-8 middle byte 0x2d

java - Spring mvc @RequestBody如何用@EmbeddedId解析JPA实体

security - JAX-RS,如何阻止用户A访问用户B的restful资源

java - Jersey 客户端发布表单数据

java - 休息服务: select an appropriate method

Glassfish 4.1 - 最新 Jersey 版本

java - Java中的getIdentifier()方法创建标识符字段?