java - Objeto complejo de Restlet para serialización de XML
serialization deserialization (1)
Esta es la serialización predeterminada con Jackson. Sin embargo, puede aprovechar el serializador personalizado para mejorar esto. Esta característica le permite tener la mano sobre el contenido generado dentro de Jackson para una clase específica. Puede anular la estrategia predeterminada con la suya y configurar de manera muy precisa lo que se creará.
Debajo de una muestra de dicha entidad que genera contenido para la clase SomeBean
:
public class SomeBeanSerializer extends JsonSerializer<SomeBean> {
@Override
public void serialize(SomeBean bean, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonProcessingException {
jgen.writeStartObject();
// Fields
jgen.writeNumberField("id", bean.getId());
(...)
// Link
String href = (...)
HypermediaLink linkToSelf = new HypermediaLink();
linkToSelf.setHref(href + bean.getId());
linkToSelf.setRel("self");
jgen.writeObjectField("hypermediaLink", linkToSelf);
jgen.writeEndObject();
}
}
Esta es la forma de configurar esto dentro de Restlet:
JacksonConverter jacksonConverter = getRegisteredJacksonConverter();
if (jacksonConverter != null) {
ObjectMapper objectMapper = jacksonConverter.getObjectMapper();
SimpleModule module = new SimpleModule("MyModule", new Version(1, 0, 0, null));
module.addSerializer(SomeBean.class, new SomeBeanSerializer());
objectMapper.registerModule(module);
}
Este enlace podría ayudarlo a ver cómo configurar el convertidor Jackson de Restlet: https://templth.wordpress.com/2015/02/23/optimizing-restlet-server-applications/ . Proporciona el contenido del método getRegisteredJacksonConverter
.
Editado : con la versión 2.3 de Restlet, algo cambia en este nivel. El mapeador de objetos ahora es traído por JacksonRepresentation
lugar del mismo JacksonConverter
. El asignador de objetos ahora está instanciado para cada representación de este tipo. Esto significa que debe clasificar estos dos elementos para configurar el serializador personalizado.
Aquí está el código de la clase CustomJacksonRepresentation
:
public class CustomJacksonRepresentation<T>
extends JacksonRepresentation<T> {
@Override
public ObjectMapper getObjectMapper() {
if (this.objectMapper == null) {
this.objectMapper = createObjectMapper();
SimpleModule module = new SimpleModule("MyModule",
new Version(1, 0, 0, null));
module.addSerializer(SomeBean.class,
new SomeBeanSerializer());
objectMapper.registerModule(module);
}
return this.objectMapper;
}
}
Aquí está el código de la clase CustomJacksonConverter
:
public class CustomJacksonConverter
extends JacksonConverter {
protected <T> JacksonRepresentation<T> create(
MediaType mediaType, T source) {
return new CustomJacksonRepresentation<T>(
mediaType, source);
}
protected <T> JacksonRepresentation<T> create(
Representation source, Class<T> objectClass) {
return new CustomJacksonRepresentation<T>(
source, objectClass);
}
}
Esto implementado, necesita reemplazar el convertidor jackson existente que Restlet registra automáticamente. Aquí está el código para hacer eso:
// Looking for the registered jackson converter
JacksonConverter jacksonConverter = null;
List<ConverterHelper> converters
= Engine.getInstance().getRegisteredConverters();
for (ConverterHelper converterHelper : converters) {
if (converterHelper instanceof JacksonConverter) {
jacksonConverter = (JacksonConverter) converterHelper;
break;
}
}
// converters
Engine.getInstance().getRegisteredConverters().remove(
jacksonConverter);
CustomJacksonConverter customJacksonConverter
= new CustomJacksonConverter();
Engine.getInstance().getRegisteredConverters().add(
customJacksonConverter);
¡Puedes notar que la forma de administrar convertidores se refactorizará en la versión 3 de Restlet para que sea más fácil configurarlo! ;-)
Espero que te ayude, Thierry
Tengo el servicio web restlet que devuelve la respuesta como xml. Estoy usando a Jackson como aglutinante. a continuación está la clase que estoy volviendo.
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class ApiResponse<T> implements Serializable {
/**
*
*/
private static final long serialVersionUID = -2736991050157565598L;
private int responseCode;
private String reponseMessage;
private List<T> body = new ArrayList<T>();
public int getResponseCode() {
return responseCode;
}
public void setResponseCode(int responseCode) {
this.responseCode = responseCode;
}
public String getReponseMessage() {
return reponseMessage;
}
public void setReponseMessage(String reponseMessage) {
this.reponseMessage = reponseMessage;
}
public List<T> getBody() {
return body;
}
public void setBody(List<T> body) {
this.body = body;
}
}
Y a continuación se encuentra la respuesta del servicio. Todo está casi bien, excepto que pone como nombres de propiedad para los objetos anidados lo mismo que los padres. Muestra el cuerpo de los nombres de etiqueta anidados, pero espero que sea la plantilla T. ¿Algunas ideas?
<ApiResponse>
<responseCode>1</responseCode>
<reponseMessage />
<body>
<body>
<reportId>1</reportId>
<reportName>name1</reportName>
</body>
<body>
<reportId>2</reportId>
<reportName>name2</reportName>
</body>
</body>
</ApiResponse>