JAX-RS(泽西岛)、Bean 验证、@JsonIgnore
JAX-RS (Jersey), Bean Validation, @JsonIgnore
我正在使用一个示例项目:
- JAX-RS(球衣 2)
- JSR-303 Bean 验证
- 用于测试的球衣测试
- Grizzly Http 容器
- 杰克逊 2.7.3
在添加 @JsonIgnore 和 @JsonProperty 之前,一切都按预期工作,我能够 运行 我的测试没有问题,同时对我的对象属性执行 bean 验证。
通常 "password" 字段不应该可用于反序列化,所以我用 @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 Class :
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
packages("org.medel.endpoint");
}
}
这是因为在客户端,对象 也 被 Jackson 序列化了。而且因为密码 属性 在读取时被忽略,所以它永远不会被序列化。所以请求是在没有密码的情况下发送的。您可能只想为实体创建另一个测试 class,不带注释,仅用于客户端测试。
编辑
为了清楚起见,问题出在客户端,而不是服务器。当客户端尝试序列化帐户时,它不会序列化密码 属性,因为它被忽略了。
您可以对其进行测试,但将 JSON 作为字符串发送,这样 Jackson 就不会参与其中。你会看到它工作正常
.post(Entity.json("{\"username\":\"user\", \"password\":\"pass\"}"));
我正在使用一个示例项目:
- JAX-RS(球衣 2)
- JSR-303 Bean 验证
- 用于测试的球衣测试
- Grizzly Http 容器
- 杰克逊 2.7.3
在添加 @JsonIgnore 和 @JsonProperty 之前,一切都按预期工作,我能够 运行 我的测试没有问题,同时对我的对象属性执行 bean 验证。 通常 "password" 字段不应该可用于反序列化,所以我用 @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 Class :
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
packages("org.medel.endpoint");
}
}
这是因为在客户端,对象 也 被 Jackson 序列化了。而且因为密码 属性 在读取时被忽略,所以它永远不会被序列化。所以请求是在没有密码的情况下发送的。您可能只想为实体创建另一个测试 class,不带注释,仅用于客户端测试。
编辑
为了清楚起见,问题出在客户端,而不是服务器。当客户端尝试序列化帐户时,它不会序列化密码 属性,因为它被忽略了。
您可以对其进行测试,但将 JSON 作为字符串发送,这样 Jackson 就不会参与其中。你会看到它工作正常
.post(Entity.json("{\"username\":\"user\", \"password\":\"pass\"}"));