Append java object to another using jackson databind annotation - java

I need to send json data to a post call in java. The following is the code
my pojo class
public class Data{
#JSONProperty("clientIP")
String clientIP;
#JSONProperty("empID")
String empID;
public Data setClientIP(String clientIp){
this.clientIP = clientIp;
return this;
}
public Data setEmpID(String empId){
this.empID = empId;
return this;
}
public String toString(){ /*toString conversion*/ }
}
Filter class where am setting clientIp
public doFilter(ServletRequest request, ServletResponse response){
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String clientIP = httpServletRequest.getRemoteAddr();
Data data = new Data();
data.setClientIP(clientIP);
}
Java class where am setting other emp related data for example userId
public Emp createEmp(empId, /*other emp related data*/){
Data data = new Data();
data.setEmpID(empId);
//append clientIp to this data object
ConvertToJSON(data);
}
in another service class am converting this data to json formatted string using jackson binding. Here I want to append previously set clientIp to this data so that I can convert entire data object to json formatted string
Class where am converting java object to json
convertToJSON(Object data){
ObjectMapper mapper = new ObjectMapper();
String jsonString = null;
jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(data);
}
I need output like { clientIP: 123.123.123.123, empID: emp123 }
currently it displays { clientIP: null, empID: emp123} which is obvious

As I said in comment, one simple way is to store clienIP into session attribute in your web filter as follows:
String clientIP = httpServletRequest.getRemoteAddr();
HttpSession session = httpServletRequest.getSession();
session.setAttribute("X-CLIENT-IP", clientIP);
Then you can use request.getSession().getAttribute("X-CLIENT-IP").toString() to retrieve client IP if you have a declaration of HttpServletRequest request.
After that, you can pass it as an argument for mehtod createEmp such as
public Emp createEmp(empId, clientIp) {
Data data = new Data();
data.setClientIP(clientIp);
data.setEmpID(empId);
...
}

Related

Java - Response JSON to Object

I tried to create a generic method to read the response json but I don't like to have a generic object with many hashmaps... I don't want to specify the type. I want to get the content for Country, City, etc...
AwsProxyResponse response = get("/countries");
List<Country> countryList = (List<Country>) jsonStringToObject(response.getBody()).get("countries"); // doesn't work
protected Object jsonStringToObject(String jsonString) throws IOException {
JsonObject jsonData = new JsonObject(jsonString);
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(jsonData.toString().getBytes(), Object.class);
}
What is the proper way to get the Response data and then fetch what I need (e.g. content, totalElements, etc...)

ResponseBuilder toString() returns object classes in string, not just the raw response string

I'm presently migrating from the Java ASK-SDK v1 to Java ASK SDK v2.
I'm trying to return a webhook call using the ResponseBuilder class that I built my response up and the data is correct, however when I try to populate the HTTP body with the JSON text, the ResponseBuilder.toString() value doesn't just populate the data with just the string, I get the following:
Optional[class Response {
outputSpeech: class SsmlOutputSpeech {
class OutputSpeech {
type: SSML
playBehavior: null
}
ssml: <speak>Some of the things you can say are What would you like to do?</speak>
}
card: null
reprompt: class Reprompt {
outputSpeech: class SsmlOutputSpeech {
class OutputSpeech {
type: SSML
playBehavior: null
}
ssml: <speak>You can say ..., is that what you want?</speak>
}
}
directives: []
shouldEndSession: false
canFulfillIntent: null
}]
Is there another way to get the string for the body of the response? The BaseSkillResponse has a getResponse() call, however, I cannot figure out how to use the class to generate the String response output.
I was able to get the string with the following in my class:
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
myFunction(){
try{
return toJsonString(responseBuilder.build().get());
} catch(IOException e) {
e.printStackTrace();
}
}
public String toJsonString(Response response)throws IOException {
return OBJECT_MAPPER.writeValueAsString(response);
}
Solve this by doing the following:
public String toJsonString(Response response)throws IOException
{
JacksonSerializer jacksonSerializer = new JacksonSerializer();
constructedResponse = jacksonSerializer.serialize(response);
JSONObject jsonObject = new JSONObject();
jsonObject.put("response",constructedResponse);
}

Post and Receive Result

Android space
void post(Food food)
{
Gson gson = new Gson();
String jsonFood = gson.toJson(food);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
restTemplate.postForEntity(URL, jsonFood, String.class);
}
Back end space
#PostMapping("/food")
public void postFood(#RequestBody String foodJson)
{
Food food = new GsonBuilder().create().fromJson(foodJson, Food.class);
String id = createId(food);
// now how do I send back saying I got this and here is an id?
}
After I receive I want to reply back saying I got the information and send back an ID.
Spring boot will automatically convert the json to a model object under the covers using Jackson
#PostMapping("/food")
public YourResponse postFood(#RequestBody Food food)
{
String id = createId(food);
return new YourResponse(id,"hello World");
}
Response object
public class YourResponse{
private String id;
private String response;
//.. constructor, getter setter
}
You can create a response model
public class PostFoodResponse{
private String id;
private String response;
//.. constructor, getter setter
}
In your code create an object of PostFoodResponse set data and send the object back as a json response
#PostMapping("/food")
public String postFood(#RequestBody String foodJson)
{
Food food = new GsonBuilder().create().fromJson(foodJson, Food.class);
String id = createId(food);
// now how do I send back saying I got this and here is an id?
PostFoodResponse response = new PostFoodResponse(id, "I got this");
return new GsonBuilder().create().toJson(response);
}

From JSON to object without table name

I'm trying to Parse very simply JSON to object (with GSON)
My JSON:
[{"username":"admin","password":"admin","name":"admin","email":"admin#admin.com"},{"username":"mark20","password":"mark123","name":"mark","email":"mark#steew.com"}]
is there 2 users, so I create 2 class, Users with list of users and User :
public class Users {
ArrayList<User> users;
Users(ArrayList<User> users){
this.users = users;
}
}
.
public class User {
String userame;
String password;
String name;
String email;
}
and here is my parsing code:
public void onResponse(Call call, Response response) throws IOException {
String body = response.body().string();
Gson gson = new GsonBuilder().create();
Users users = gson.fromJson(body, Users.class);
}
of course in variable body I have got correct JSON, but in last lane I got:
JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY
What can be wrong here ? How to fix it ?
Your json is an array of User not a wrapper Users of array User.
Read your json like this:
User[] users = gson.fromJson(body, User[].class);
If you want an ArrayList<>:
List<User> userList = Arrays.asList(users);
Another way is to use TypeToken:
Type listType = new TypeToken<ArrayList<User>>(){}.getType();
List<User> userList = gson.fromJson(body, listType);
If I'm reading from what I read elsewhere correctly try:
public void onResponse(Call call, Response response) throws IOException {
String body = response.body().string();
Gson gson = new GsonBuilder().create();
User[] users = gson.fromJson(body, User[].class);
}

How to pass multiple parameters to Jersey POST method

I am trying to pass multiple parameters to Jersey POST method . Currently I am following below steps to pass a single parameter to Jersey POST method.
Client client = ClientBuilder.newClient();
WebTarget target= client.target("http://localhost:8080/Rest/rest/subuser").path("/insertSubUser");
SubUserBean subUserBean=new SubUserBean();
subUserBean.setIdUser(1);
subUserBean.setIdSubUserType(1);
subUserBean.setIdSubUser(15);
subUserBean.setFirstName("Haritha");
subUserBean.setLastName("Wijerathna");
subUserBean.setNumberOfDaysToEditRecord(14);
subUserBean.setUserName("haritha");
subUserBean.setPassword("hariwi88");
subUserBean.setDateCreated(Common.getSQLCurrentTimeStamp());
subUserBean.setLastUpdated(Common.getSQLCurrentTimeStamp());
target.request(MediaType.APPLICATION_JSON_TYPE).post(Entity.entity(subUserBean, MediaType.APPLICATION_JSON_TYPE));
SubUserJSONService.java
#Path("/subuser")
public class SubUserJSONService {
#POST
#Path("/insertSubUser")
#Consumes(MediaType.APPLICATION_JSON)
public String updateSubUser(SubUserBean bean){
SubUserInterface table = new SubUserTable();
String result= table.insertSubUser(bean);
return result;
}
}
Now, I want to pass parameters to following method via Jersey POST method.
public String insertHistory(List<SocialHistoryBean> list, String comment){
//my stuffs
}
Have any ideas to do above work ?
Thank you.
You can try using MultivaluedMap.Add form data and send it to the server. An example below, code is not tested just for demo/logic flow.
WebTarget webTarget = client.target("http://www.example.com/some/resource");
MultivaluedMap<List, String> formData = new MultivaluedHashMap<List, String>();
formData.add(List, "list1");
formData.add("key2", "value2");
Response response = webTarget.request().post(Entity.form(formData));
Consume this on server side something like
#Path("/uripath")
#POST -- if this is post or #GET
#Consumes("application/x-www-form-urlencoded;charset=UTF-8") or json..
#Produces("application/json")
public void methodNameHere(#FormParam("list") List<String> list1, #FormParam("key2") String val2) {
System.out.println("Here are I am");
System.out.println("list1" + list1.size);
System.out.println("val2" + val2);
}
Read more here in docs..
In case you're using Jersey 1.x, check this example on how to post multiple objects as #FormParam
Client: (pure Java):
public Response testPost(String param1, String param2) {
// Build the request string in this format:
// String request = "param1=1&param2=2";
String request = "param1=" + param1+ "&param2=" + param2;
WebClient client = WebClient.create(...);
return client.path(CONTROLLER_BASE_URI + "/test")
.post(request);
}
Server:
#Path("/test")
#POST
#Produces(MediaType.APPLICATION_JSON)
public void test(#FormParam("param1") String param1, #FormParam("param2") String param2) {
...
}
JSON data cannot be passed to the server in a List. This means that you should create a wrapper around your SocialHistoryBean class (i.e around the list that holds your objects)
#XmlRootElement(name = "uw")
public class SocialHistoryBeanWrapper implements Serializable {
private List<SocialHistoryBean> sList ;//this will hold your SocialHistoryBean instances
public SocialHistoryBeanWrapper(){
sList = new ArrayList<User>();
}
public List<User> getUsrList(){
return sList;
}
}
Your server side code will be like
#POST
#Path("/history")
#Produces(MediaType.TEXT_PLAIN)
#Consumes(MediaType.APPLICATION_JSON)
public String insertHistory( #QueryParam("comment") String comment, SocialHistoryBeanWrapper uw) {
do whatever you want with your history data
//userData.setUser(uw.getUsrList().get(0));
return comment; //just echo the string that we have sent from client
}
Note that comment is passed with #QueryParam (this means it's not part of the POST request (body) but is rather encoded in the URL string. For this to work, you can call your service as (the client code)
WebTarget target = client.target(UriBuilder.fromUri("http://localhost:8088/Rest/rest/subuser").build());
SocialHistoryBeanWrapper uw = new SocialHistoryBeanWrapper();
//just populate whatever fields you have;
uw.getUsrList().get(0).setName("Mark Foster");
uw.getUsrList().get(0).setProfession("writer");
uw.getUsrList().get(0).setId(55);
String s = target.path("history").queryParam("comment", "OK").request()
.accept(MediaType.TEXT_PLAIN).post(Entity.entity(uw, MediaType.APPLICATION_JSON), String.class);
System.out.println(s);//this prints OK

Categories