I am able to serialise the string field using #JsonSerialize applied on POJO getmethod, and able to see the post serialize value changes in controller before binding to response, but once the controller method returns ResponseEntity.ok(postRes), the serialise value is not coming in the response.
The application is Spring Boot 2.1.1, JsonSerialize comes from Jackson.
Do I need to configure anything in Spring Boot for this?
Usage:
#JsonSerialize(using = JsonString.class)
public String getInvoices() {
return invoices;
}
Implementation:
public class JsonString extends JsonSerializer <String> {
#Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException,
JsonProcessingException {
String val = value.replace("/", "");
gen.writeString(val);
}
}
Related
I have a POJO like:
class Wrapper,T> {
private int count;
private T data;
// getters setters
}
While converting it to JSON using Jackson, json is something like:
{
count:1,
**data**:{}
}
I need the data key to be changed as per class name T or some other value related to class name, how can I achieve this. Please suggest.
Thankyou.
Using a custom serializer, you can do anything you want since you have complete control over the serialization process. See for example https://www.baeldung.com/jackson-custom-serialization.
Your serialize method would look something like this:
#Override
public void serialize(
Wrapper<?> value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException {
String derivedName = value.getClass().getSimpleName() + "Data"; // just an example
jgen.writeStartObject();
jgen.writeNumberField("count", value.getCount());
jgen.writeObjectField(derivedName, value.getData());
jgen.writeEndObject();
}
I have a custom JsonSerializer for a field (simplified code):
#JsonSerialize(using=Text1Serializer.class)
#JsonProperty("text1") // I need this inside the custom serializer
#Override
public String getTextOne() {
return "foo";
}
// ...
public static class Text1Serializerextends JsonSerializer<String> {
#Override
public void serialize(String value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
// how to get "text1" here?
provider.defaultSerializeValue(value, jgen);
}
}
Since I need to serialize about ten other fields with a similar logic, that just depends on the field name, it would help me very much if I could get the property name inside the custom serializer - instead of writing ten identical serializers.
I've seen that inside the serialize() method I can get the whole object with JsonGenerator.getCurrentValue() (see this answer), but I didnt' find a way to get the field name.
I'm using Jackson 2.6
You can get field name in a custom json serializer like this:
#JsonComponent
public class Text1Serializerextends extends JsonSerializer<String> {
#Override
public void serialize(String value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
// will output "text1"
System.out.println(jgen.getOutputContext().getCurrentName());
provider.defaultSerializeValue(value, jgen);
}
}
If you implement ContextualSerializer, this will be used to produce a "contextual" version of your serializer, i.e. one that is configured using the BeanProperty:
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property)
throws JsonMappingException;
This should return a new instance that is customised for the given property: it doesn't have to be the same class as the non-customised serializer (although the standard Jackson implementations all seem to work that way).
You can get the current property name by calling jgen.getOutputContext().getCurrentName()
You can achieve this through Customized SerzializerProvider
public class EmptyContentSerializerProvider extends DefaultSerializerProvider {
#Override
public JsonSerializer<Object> findNullValueSerializer(BeanProperty property) throws JsonMappingException {
property.getName(); //this can extract the filed name
}
}
In Spring MVC project, I have controllers which return data in the form of various objects. Later these objects are serialized to JSON, and JSON returned as a response to a client.
This is achieved by registering custom MappingJackson2HttpMessageConverter with configureMessageConverters() in application config. The converter uses
jackson.databind.ObjectWriter.writeValue(jackson.core.JsonGenerator, object)
for object serialization.
Now I need to implement XSS protection. Since all data goes through the step of serialization, I want to filter here String values, removing all symbols except those in whitelist (alphanumeric and some punctuation signs).
Is there a way to provide Jackson with a filter which will edit String values during serialization?
I have an instance of MappingJackson2HttpMessageConverter. There, in method writeInternal(Object object, HttpOutputMessage outputMessage), I create an instance of my custom mapper: mapper = new KJsonMapper(); This mapper is then used there to generate JSON.
KJsonMapper.java:
public class KJsonMapper extends ObjectMapper {
public KJsonMapper() {
enableAntiXSS();
}
private void enableAntiXSS() {
SimpleModule module = new SimpleModule("Anti-XSS Serializer",
new Version(1, 0, 0, "FINAL", "klab", "klab.anti-xss-serializer"));
module.addSerializer(String.class, new KJsonAntiXssSerializer());
registerModule(module);
}
}
The mapper itself uses custom JsonSerializer, which is to provide anti-xss filtering.
KJsonAntiXssSerializer.java:
public class KJsonAntiXssSerializer extends JsonSerializer<String> {
public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
throws IOException {
if (value == null) {
return;
}
String encodedValue = antiXss(value);
jsonGenerator.writeString(encodedValue);
}
private String antiXss(String value) {
// return processed value from here
}
}
I have Match class and field Date start. My goal is get start as timestamp. I use Spring, AngularJs, and jackson as json converter.
Spring Controller:
#RequestMapping(value = "/web2/getMatch", method =RequestMethod.POST)
public #ResponseBody Match getPicksHistory() {
PickDAO pd = new PickDAO();
return pd.getMatch();
}
On AgularJS controler:
var res = $http.post(urlSer.url+"web2/getMatch");
res.success(function(data, status, headers, config) {
// now returns data.start = "Aug 8, 2015 7:00:00 PM"
// My goal is get as timestamp
});
I assume that by 'timestamp' you mean a numeric timestamp as opposed to a textual representation. You can use a custom ObjectMapper:
#Component
#Primary
public class CustomObjectMapper extends ObjectMapper {
public CustomObjectMapper() {
configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true);
}
}
I use jackson-databind:2.6.1 and JsonSerializer
#Component
public class JsonDateSerializer extends JsonSerializer<Date>{
#Override
public void serialize(Date date, JsonGenerator gen,
SerializerProvider serializers) throws IOException,
JsonProcessingException {
gen.writeNumber(date.getTime());
}
}
I need to create json where the objects are all structured similarly, but can contain different object names, i.e.:
"obj1":{
"field1":1,
"field2":2
}
"obj2":{
"field1":4,
"field2":5
}
"obj3":{
"field1":7,
"field2":8
}
How can I use jackson to create dynanic field names? this would be done during run time depending on input taken
You could possibly refer to this answer: Jackson dynamic property names.
Basically you can use a custom JsonSerializer.
#JsonProperty("p")
#JsonSerialize(using = CustomSerializer.class)
private Object data;
// ...
public class CustomSerializer extends JsonSerializer<Object> {
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeStartObject();
jgen.writeObjectField(value.getClass().getName(), value);
jgen.writeEndObject();
}
}