杰克逊:调整ObjectMapper以忽略类

时间:2016-12-08 11:48:39

标签: java json junit jackson resteasy

我正在使用Resteasy Client和Embedded Jaxrs Server在遗留应用程序中编写RESTful服务测试。我正面临使用杰克逊带有特殊实体的序列化/反序列化的问题,我不应该做任何改变。该实体具有:

  • 只执行逻辑(没有等效字段)且应该可序列化但不可反序列化的公共“getter”;
  • 用于某些控件和持久性的私有字段,但没有公共getter / setter,不应该序列化/反序列化;

在应用程序中,我们的前端永远不会发回这些属性(因此它们永远不会被反序列化),在我的单元测试中,由于“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());
    }

}

0 个答案:

没有答案