1

Я работаю над проектом с использованием образца:JAX-RS (Jersey), Bean Validation, @JsonIgnore

  • JAX-RS (Jersey 2)
  • JSR-303 Bean validaiton
  • Джерси Тест для тестирования
  • Grizzly Http контейнера
  • Джексон 2.7.3

Перед добавлением @JsonIgnore и @JsonProperty все работало, как ожидалось, я смог запустить свои тесты без проблем, выполняя проверку bean-компонентов на свойствах моих объектов. Обычно поле «пароль» не должно быть доступно для десериализации, поэтому я пометил его getter с @JsonIgnore и его установщиком с помощью @JsonProperty, чтобы разрешить его сериализацию при сохранении нового объекта учетной записи.

При запуске моего теста я получаю сообщение об ошибке 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}] 

Примечание: При удалении @JsonIgnore аннотации, никакой ошибки проверки не будет получена конечно

Мой ресурс:

@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 Класс:

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; 
    } 
} 

Мой Unit Test:

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"); 
    } 
} 

ответ

1

Это потому, что на стороне клиента объект также сериализован Джексоном. И поскольку свойство пароля игнорируется при чтении, оно никогда не становится сериализованным. Таким образом, запрос отправляется без пароля. Вы можете просто создать другой тестовый класс для объекта без аннотаций, просто для тестирования клиента.

Редактировать

Так что для ясности, проблема с клиента, а не сервер. Когда клиент пытается сериализовать учетную запись, она не сериализует свойство пароля, поскольку оно игнорируется.

Вы можете протестировать его, но отправив JSON в виде строки, таким образом Джексон не вмешивается. Вы увидите, что он работает отлично

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

Спасибо вам ответ я не получил его, если пароль свойство игнорируется на чтение означает, что он не будет десериализация нормально, используя @JsonProperty на методе сеттера должен позволить пароль, который будет сериализован, не так, как он должен работать? – M3d3L0

+0

В коде клиента. Когда вы отправляете запрос, Джексон сериализовал Acount для JSON. Он не сериализует «пароль» из-за '@ JsonIgnore'. Таким образом, пароль никогда не отправляется вообще на сервер. Вы можете проверить журнал, вы увидите запрос клиента, выходящий без свойства пароля в JSON. –

+0

И в случае, если вы его перепутали, gettters используются для сериализации, а сеттеры используются для _de_-сериализации. А не наоборот. Сериализация означает POJO для JSON, десериализация означает JSON для POJO –

Смежные вопросы