Jackson - DTO int to String conversion - java

Working on a REST client that calls another server which returns the following object:
public class ObjectOriginal {
private int id;
private String name;
// constructor/getters/setters
}
I need to obfuscate the id. To do so I'm using an already existing service that transforms the id into a unique generated String so that the person calling my service doesn't know the REAL id but can still request info about it with the unique string.
So I'm basically trying to return to the caller this object:
public class ObjectNew {
private String id;
private String name;
// constructor/getters/setters
}
Do I need to have a copy of ObjectOriginalDTO + create a ObjectNew DTO + create a mapper to go from one to the other.
Or can I configure Jackson to deserialize the id field as a String and not an int?

You can do this using your own Serializer/Deserializer.
You have to implement your Serializer/Deserializer that will extends respectively BeanSerializerModifier/BeanDeserializerModifier and configuring your Module with them for instance Or use the annotation base solution as explained in this tutorial, there are plenty of references on the web for such a thing. then you'll have more controlle over the way to map your id.

If you don't want to have custom deserializer you can have:
public class ObjectNewDto {
private String id;
private String name;
// constructor/getters/setters
}
and another object:
public class ObjectOriginal {
private int id;
private String name;
// construxtor/getters/settes
}
Now after validating ObjectNewDto you can map it via your obfuscator service into ObjectOriginal , then validate this Object original and so on...

Related

How to pass an object as an attribute of another object using jersey(jax-rs) client in a post request?

I wan't to pass an object which consist of another object as it's one attribute,so how to achieve this?
Ex:
Class
public class CustomerProduct{
private int customerId;
private String customerName;
private Product product;
//Constructors and getters setters
}
Product p1 = new Product(with required args);
CustomerProduct obj = new CustomerProduct(1,"John",p1);
Now I need to pass the obj to the rest API post method as an object[Here rest API is implemented by spring boot]
Response response1 =client.target(endPointUrl).request().post(Entity.json(obj));
Here with the aid of this method only the customerId and customerName will be receive by the rest API and the Product object will be get as null.
Sample code of rest API method
#PostMapping("/customer-product")
public void sampleControllerMethod(#RequestBody CUstomerProductDTO customerProductDTO){
customerProductService.methodA(customerProductDTO);
}
How to solve this ?
In here What I did to solve this issue was using the attributes that I needed in product class as attributes in CustomerProduct class.
Example:
public class CustomerProduct{
private int customerId;
private String customerName;
//Using the attributes in Product class as attributes in CustomerProduct class
private String productName;
private String productPrice;
//Likewise I used product object attributes inside the CustomerProduct class
//Overloaded constructors and getters setters
}
So after that I passed the object of CustomerProduct as a single object to the post method of Rest API using jax-rs like below.
CustomerProduct obj = new CustomerProduct(args);
Response response1 =client.target(endPointUrl).request().post(Entity.json(obj));

Mapping all request params into an object in Spring Controller [duplicate]

This question already has answers here:
In Spring-mvc the attribute names in view have to always match the property names in model?
(3 answers)
How to customize parameter names when binding Spring MVC command objects?
(10 answers)
Closed 3 years ago.
So, url requested looks like
localhost:8080/contacts?id=22&name=John&eventId=11
and also I got an object to map request into
public class ContactDTO {
private Long id;
private String name;
private Long eventId;
}
I use a controller method like passing my request params into an object
#GetMapping("/contacts")
public ContactDTO contacts(ContactDTO contact) {
// everything is awesome! contact maps clearly
return contact;
}
The question is how to map like this but have different name
localhost:8080/contacts?id=22&name=John&event_id=11
Setting #JsonAttribute doesn't works because Jackson mapper works only in requestbody.
Maybe I should write custom HandlerMethodArgumentResolver or something like that?
P.S.
I've got a dirty hack (objectMapper is injected, so I can use #JsonAttributes),
But this case fails on array mapping, same mapping with requestbody works fine
#GetMapping("/contacts")
public ContactsDTO contacts(#RequestParam Map<String,String> params) {
ContactDTO contactDTO = objectMapper.convertValue(params,ContactDTO.class);
return contactDTO;
}
Since it is an API design requirement, it should be clearly reflected in the corresponding DTO's and endpoints.
Usually, this kind of requirement stems from a parallel change and implies that the old type queries will be disabled during the contract phase.
You could approach the requirement by adding the required mapping "query-parameter-name-to-property-name" by adding it to the ContactDTO. The simplest way would be just to add an additional setter like below
public class ContactDTO {
private Long id;
private String name;
private Long eventId;
public void setEvent_id(Long eventId) {
this.eventId = eventId;
}
}
If you prefer immutable DTO's, then providing a proper constructor should work as well
#Value
public class ContactDTO {
private Long id;
private String name;
private Long eventId;
public ContactDTO(Long id, String name, String eventId, String event_id) {
this.id = id;
this.name = name;
this.eventId = eventId != null ? eventId : event_id;
}
}
Use something like
#RequestParam(name="event_id", required = true) long eventId
in the parameter list to change the parameter name.
Use #RequestBody insteaf of #requestparam.

Serialize a class to json in diffrent ways

Is there any way to serialize a class into json but only with fields I want to use in particular case without need of creating multiple variations of class?
Let's take an example:
class User{
#JsonField
private String name;
#JsonField
private String surname;
#JsonField
private String hashedCode;
#JsonField
private String city;
#JsonField
private String anotherDummyString;
}
Now in one of my methods I would like to have a mapping to json Object which only contains name, city and anotherDummyString.
In Second method I want to have surname and city. In third method ... .
Is there any pleasant and neat way to achive this?
I was wondering if I can "hide" these fields which I don't need.
Are you looking for something like this? (Using javax.json)
JsonObject getJson1() {
return Json.createObjectBuilder().add("name", this.name).add("city", this.city).build();
}
JsonObject getJson2() {
return Json.createObjectBuilder().add("surname", this.surname).add("city", this.city).build();
}
Just .add what you need in each function call.
I hope you are looking for a kind of filter for your fields in Class
This can be achieved using Jackson #JsonFilter
package com.concretepage;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.JsonProperty;
#JsonFilter("student")
public class Student
{
#JsonProperty("name")
private String name;
#JsonProperty("surname")
private String surname;
#JsonProperty("hashedCode")
private String hashedCode;
#JsonProperty("city")
private String city;
#JsonProperty("anotherDummyString")
private String anotherDummyString;
}
Create a simple filter for you above class
SimpleFilterProvider filterProvider = new SimpleFilterProvider();
filterProvider.addFilter("student",
SimpleBeanPropertyFilter.serializeAllExcept("name", "city","anotherDummyString"));
Set it to a object mapper
ObjectMapper mapper = new ObjectMapper();
mapper.setFilterProvider(filterProvider);
To get the json message
//Pass the student object
String jsonData = mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(student);
You must able to have you 2 variance of class by creating one more sample filter like above

Serialization pojo into different json structure

I need to serialize a pojo into different json structure depending on whom I am sending request. Also I should be able to configure in some config that how field of pojo are mapped to json properties for a given request.
Can this be achived using jackson?
Is there some library or api to do this?
Edit:
For example:
public class Universal {
private int id;
private Date date;
private String name;
private Inner inner;
private Map<String,Object> others;
private List<Inner> inners;
}
public class Inner {
private String value;
}
now above are two object i need to create dynamic json, one example for some of transformation is below
{
"id":"",//value will be id of Universal
"detials":{
"name":"",//value will be name of Universal
},
"data":[], // array of value(field of Inner) from inners
"ext":{
"prop1":""// value of this field will be some (key1) value from others
}
}
You can use Google Gson and rely on its type adaptors.
http://www.javacreed.com/gson-typeadapter-example/ is a good article from web

Serialize Jackson field in two different ways

I am doing POJO serialization / deserialization using Jackson.
Here is a POJO exemple :
public class Pojo {
public String productId;
public String name;
}
I have to read the field productId in this JSON :
{"productId":"1","name":"exemple"}
But also in :
{"_id":"1","name":"exemple"}
To make it short, I would like to use the same object to read the field in a JSON file found somewhere and to save the object as this in MongoDB, using productId as the primary key, which has to be named _id.
Since I am using Jackson (fasterxml) both to read from the file and to write to the database, I can not find a way to do so, except by creating a new class with the same fields (or inheritance) and fill them one by one. Basically, I would like to find a way to put 2 #JsonProperty annotations on productId.
Works with both strings:
public class Pojo {
#JsonProperty("_id")
public String productId;
public String name;
#JsonProperty("productId")
public void setProductId(String id) {
productId = id;
}
}

Categories

Resources