我正在使用Resteasy Client和Embedded Jaxrs Server在遗留应用程序中编写RESTful服务测试。我正面临使用杰克逊带有特殊实体的序列化/反序列化的问题,我不应该做任何改变。该实体具有:
在应用程序中,我们的前端永远不会发回这些属性(因此它们永远不会被反序列化),在我的单元测试中,由于“org.codehaus.jackson.map.exc.UnrecognizedPropertyException:Unrecognized field”,它们失败了。如果上面的两个属性都有他们的公共getter / setter,那么测试不会失败,但是我再也不应该对代码进行更改,这些方法会破坏这些类的结构。
我已经调整了我的Object Mapper但没有配置能够处理这种情况。最终找不到一个或另一个。有没有办法在这些情况下通过仅调整我的Object Mapper忽略这些属性来转变序列化?或者是否必须以某种方式改变代码?
谢谢!
(小样本)
// Entity
public class Entidade {
private int numero;
private String dado;
private boolean naoUsado = false;
public Entidade() { /**/ }
public Entidade(int numero, String dado) {
this.numero = numero;
this.dado = dado;
}
public int getNumero() {
return numero;
}
public void setNumero(int numero) {
this.numero = numero;
}
public String getDado() {
return dado;
}
public void setDado(String dado) {
this.dado = dado;
}
public String getTeste() {
return "Regra de negócio de leitura";
}
}
// Embedded Server Helper
public class ServidorEmbarcadoRestEasy {
private static final int POOL_SIZE = 9999;
private static final int PORTA = 5555;
private static final String HOST = "localhost";
private TJWSEmbeddedJaxrsServer servidor;
private ResteasyClient resteasyClient;
private ServidorEmbarcadoRestEasy(Object webservice, Class<?>... providers) {
this.servidor = new TJWSEmbeddedJaxrsServer();
this.resteasyClient = new ResteasyClientBuilder().
connectionPoolSize(POOL_SIZE).
connectionCheckoutTimeout(100, TimeUnit.MILLISECONDS).
build();
servidor.setPort(PORTA);
servidor.setBindAddress(HOST);
servidor.getDeployment().getResources().add(webservice);
servidor.setSecurityDomain(null);
servidor.start();
ResteasyProviderFactory factory = servidor.getDeployment().getDispatcher().getProviderFactory();
for (Class<?> c : providers) {
factory.registerProvider(c);
}
}
public static ServidorEmbarcadoRestEasy iniciar(Object webservice, Class<?>... providers) {
ServidorEmbarcadoRestEasy servidorEmbarcado = new ServidorEmbarcadoRestEasy(webservice, providers);
return servidorEmbarcado;
}
public void fechar() {
servidor.stop();
}
private String getUrlCompleta(String uri) {
final String base = "http://%s:%s/%s";
return String.format(base, HOST, PORTA, uri);
}
private Builder request(String uri, List<String> queryParams) {
String urlCompleta = getUrlCompleta(uri);
ResteasyWebTarget target = resteasyClient.target(urlCompleta);
for (String s : queryParams) {
String[] chaveValor = s.split("=");
String chave = chaveValor[0];
String valor = chaveValor[1];
target = target.queryParam(chave, valor);
}
return target.request();
}
private Builder request(String uri) {
if (uri.contains("?")) {
String[] urlFracionada = uri.split("\\?");
String baseUri = urlFracionada[0];
String paramString = urlFracionada[1];
String[] paramArray = paramString.split("&");
List<String> parametros = new ArrayList<>(Arrays.asList(paramArray));
if (!parametros.isEmpty()) {
return request(baseUri, parametros);
}
}
String urlCompleta = getUrlCompleta(uri);
return resteasyClient.target(urlCompleta).request();
}
public Response get(String url) {
return request(url).buildGet().invoke();
}
public Response delete(String url) {
return request(url).buildDelete().invoke();
}
public Response put(String url, Object payload) {
return request(url).buildPut(Entity.json(payload)).invoke();
}
public Response post(String url, Object payload) {
return request(url).buildPost(Entity.json(payload)).invoke();
}
}
// Jackson Provider
public class JacksonTestsProvider extends JacksonJsonProvider {
public static ObjectMapper getMapper() {
return new ObjectMapper()
.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
@Override
public void writeTo(Object arg0, Class<?> arg1, Type arg2, Annotation[] arg3, MediaType arg4,
MultivaluedMap<String, Object> arg5, OutputStream arg6) throws IOException {
super.setMapper(getMapper());
super.writeTo(arg0, arg1, arg2, arg3, arg4, arg5, arg6);
}
@Override
public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException {
super.setMapper(getMapper());
return super.readFrom(type, genericType, annotations, mediaType, httpHeaders, entityStream);
}
}
// Unit Tests
public class ServidorEmbarcadoRestEasyTest {
@Path("meuservico")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public static class ServicoTeste {
private Map<Integer, Entidade> entidades = new HashMap<>();
public ServicoTeste() {
for (int i = 1; i <= 100; i++) {
entidades.put(i, new Entidade(i, "Teste " + i));
}
}
@GET
@Path("minha-entidade")
public Response getEntidade() {
return Response.ok(new Entidade(9999, "Nova entidade")).build();
}
@GET
@Path("minha-entidade/{id}")
public Response getEntidade(@PathParam("id") Integer id) {
Entidade retorno = entidades.get(id);
if (retorno == null) {
return Response.status(Status.BAD_REQUEST).build();
} else {
return Response.ok(retorno).build();
}
}
}
private static ServidorEmbarcadoRestEasy servidor;
private static ServicoTeste servico;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
servico = new ServicoTeste();
servidor = ServidorEmbarcadoRestEasy.iniciar(servico,
JacksonTestsProvider.class);
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
servidor.fechar();
}
@Test
public void deveFazerGetComSucesso() {
Response response = servidor.get("meuservico/minha-entidade");
assertEquals(Status.OK.getStatusCode(), response.getStatus());
Entidade entidade = response.readEntity(Entidade.class);
assertEquals(9999, entidade.getNumero());
assertEquals("Nova entidade", entidade.getDado());
response = servidor.get("meuservico/minha-entidade/98");
assertEquals(Status.OK.getStatusCode(), response.getStatus());
entidade = response.readEntity(Entidade.class);
assertEquals(98, entidade.getNumero());
assertEquals("Teste 98", entidade.getDado());
}
}