Post and Receive Result - java

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);
}

Related

Trying to call/post a third party api in java spring

My issue is when I try this I get a media type error, then I changed the header. Now I receive a 500 error. The problem isnt the api , on postman it works perfectly , am I doing something wrong in my code when requesting a post?
My object model
public class EmailModel {
private String module;
private String notificationGroupType;
private String notificationGroupCode;
private String notificationType;
private String inLineRecipients;
private String eventCode;
private HashMap<String, Object> metaData;
public EmailModel() {
this.module = "CORE";
this.notificationGroupType = "PORTAL";
this.notificationGroupCode = "DEFAULT";
this.notificationType = "EMAIL";
this.inLineRecipients = "[chrispotjnr#gmail.com,chris#mqattach.com]";
this.eventCode = "DEFAULT";
this.metaData = metaData;
}
}
My Controller
It should send a post request with a object body, the emails get sent
#RequestMapping(value = "test", method = RequestMethod.Post)
public void post() throws Exception {
String uri = "TestUrl";
EmailModel em = new EmailModel();
EmailModel data = em;
HttpClient client = HttpClient.newBuilder().build();
HttpRequest request = HttpRequest.newBuilder()
.headers("Content-Type", "application/json")
.uri(URI.create(uri))
.POST(HttpRequest.BodyPublishers.ofString(String.valueOf(data)))
.build();
HttpResponse<?> response = client.send(request, HttpResponse.BodyHandlers.discarding());
System.out.println(em);
System.out.println(response.statusCode());
}
postmanImage
You must to convert EmailModel to json format by ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
String data = objectMapper
.writerWithDefaultPrettyPrinter()
.writeValueAsString(em);
and change POST to :
.POST(HttpRequest.BodyPublishers.ofString(data))
See more about ObjectMapper
Capture requests and cookies(on the left side of setting icon)
->Request
->port and put the port number there

I cannot send an HTTP request (500 internal server error)

I am currently receiving the following error for the http request am sending. I am trying to send a JSON Array list to trigger a method in the receiving end so as it saves the list in its database.
The 500 Internal Server Error is a very general HTTP status code that means something has gone wrong on the website's server, but the server could not be more specific on what the exact problem is.
Websites phrase 500 errors in many ways but they're all basically saying the same thing: there's a general server issue going on right now.
Most of the time there isn't anything you can do but contact the website directly and then wait on them to fix it.
In the off chance there is a problem on your end, try clearing the cache and deleting any cookies from the site with the error.
Please find the error below:
org.springframework.web.client.HttpServerErrorException: 500 Internal Server
public static String FRONT_URL;
public static String BACK_URL;
public static final String REST_SYNC = "rest/sync";
public static final String REST_API = "rest/api";
private Logger log = Logger.getLogger(FrontSynchronizer.class);
static final Logger synclog = Logger.getLogger("sync");
ResourceBundle rb = ResourceBundle.getBundle("bundles.sync-application-resources", Locale.getDefault());
//method sending the request
public void syncApplications(List<SchemeApplication> accList) {
schemeApplicationDto=new SchemeApplicationDto();
FRONT_URL = rb.getString("sync.front.url").concat(REST_SYNC);
BACK_URL = rb.getString("sync.back.url").concat(REST_API);
JSONArray array = new JSONArray();
if (accList != null && accList.size() > 0) {
for (SchemeApplication student : accList) {
schemeApplicationDto.setId(student.getId());
schemeApplicationDto.setAccountID(student.getAccountID());
schemeApplicationDto.setNoOfPersonsEmployedLocal(student.getNoOfPersonsEmployedLocal());
schemeApplicationDto.setLocalmainclients(student.getLocalmainclients());
JSONObject studentJSON = new JSONObject(schemeApplicationDto);
array.put(studentJSON);
}
}
HttpHeaders headers = new HttpHeaders();
JSONObject object = new JSONObject();
object.put("array", array);
headers.setContentType(MediaType.APPLICATION_JSON);
RestTemplate restTemplate = this.createnewTemplate();
String url = BACK_URL.concat("/application");
HttpEntity<String> requestEntity = new HttpEntity<String>(object.toString(), headers);
ResponseEntity<Boolean> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity,
Boolean.class);
if (responseEntity.getBody())
{
for(SchemeApplication scheme:accList) {
schemeApplicationService.getDao().delete(scheme);
}
}
}
public RestTemplate createnewTemplate() {
// RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory());
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setConnectTimeout(120000);
RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
return restTemplate;
}
// method that needs to process the request
//The method is trying to send an Array list so as the receiving end can receive the list and save it in its database.
#RequestMapping(value = "application", method = RequestMethod.POST)
public Boolean getAllArchivedpplications(#RequestBody String schemeJson) {
List<SchemeApplication> accList = null;
try {
accList = new ArrayList<SchemeApplication>();
if (StringUtils.isNotEmpty(schemeJson)) {
JSONObject listObject = new JSONObject(schemeJson);
JSONArray entryArray = listObject.getJSONArray("array");
for (int i = 0; i < entryArray.length(); i++) {
JSONObject res = new JSONObject(entryArray.get(i).toString());
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
schemeApplication doc = mapper.readValue(res.toString(),
new TypeReference<schemeApplication>() {
});
accList.add(doc);
}
schemeService.getDao().save(accList); // Service.save accountlist;
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
#RequestBody must work on an object.
Standard way to do this kind of work in two ways:
Form a class having class files with same name and structure with your json data you are sending and capture that data in by #RequestBody annotation
As you are sending data as String, send it as request param, and use #RequestParam instead of #RequestBody and parse the way you need to do things. For I think for this kind of arrayList of bulk data you are working with, option 1 will be better/feasible.
For details you can check here: #RequestBody and #ResponseBody annotations in Spring

Append java object to another using jackson databind annotation

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);
...
}

Spring MVC: Complex object as parameter

I started to learn spring boot and I'm faced with problems. I have following code:
#RestController
public class UserController {
#RequestMapping("/")
public String getMessageInfo(Message message) {
return "Id is " + message.getId() + ", message is " + message.getMessage() + ", parameter good is " + message.isGood();
}
}
Class Message:
public class Message {
private String message;
private int id;
private boolean good;
public Message() {}
public Message(int id) {this.id = id;}
public Message(String message) {this.message = message;}
public Message(boolean good) {this.good = good;}
public Message(String message, boolean good, int id) {
this.message = message;
this.good = good;
this.id = id;
}
public String getMessage() {
return message;
}
public int getId() {
return id;
}
public boolean isGood() {
return good;
}
}
And when I try to do something like this:
RestTemplate request = new RestTemplate();
String info = request.getForObject("http://localhost:8080/?id=4", String.class);
value of id is ignored. Same problem appears when I send request with boolean good parameter (for example localhost:8080/?good=true). It is called the default constructor instead of Message(boolean)/Message(int). But when I do something like localhost:8080/?message=1234 it isn't ignored. Can you explain me what is the problem?
And one more question: can I send instance of class Message to getMessageInfo in different way than localhost:8080/?message=1234&good=true&id=145? If I have more than 3 parameters? For example if class Message has 100 parameters?
since you are trying to deal with a complex object accept your object from a post request.
#RequestMapping("/",method=RequestMethod.POST)
public String getMessageInfo(#RequestBody Message message) {
return message;
}
in the above code i'm setting method attribute to POST then it will be called when you are making a POST request, and i am using #RequestBody Message message inside the method parameter. which will convert and form an Message object from the incoming request, if you dont put #requestBody annotation then a Bean will be injected to the method by spring instead of forming a one from the request.
you can try this code to make the request
final String uri = "http://localhost:8080/";
Message message = new Message(1, "Adam",true);
RestTemplate restTemplate = new RestTemplate();
Message result = restTemplate.postForObject( uri, message, Message.class);
when making an request create an Message object setting each and every field in it, otherwise you will end up in having Bad request error.
I solved the problem, if add smth like this:
#ModelAttribute("message")
public Message getMessage(String message, boolean good, int id){
return new Message(message, good, id);
}
#RequestMapping("/")
public String getUserInfo(#ModelAttribute("message") Message message) {
return "Id is " + message.getId() + ", message is " + message.getMessage() + ", parameter good is " + message.isGood();
}
all parameters aren't ignored.
You can use like this,
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
params.add("id", 1);
params.add("good", true);
params.add("message", 1234);
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(params, requestHeaders);
RestTemplate restTemplate = new RestTemplate();
Message message= restTemplate.postForObject("http://localhost:8080/", requestEntity, Message.class);

Could not read JSON: Can not deserialize instance of modelName out of START_OBJECT token

I trying to read this json value and convert it to java object
{"message":"1"}
which is returned from this string.
http://mywebservice:8080/SpringService/service/updatepool/selectdynamicurl/~!~''WEB1500001''~!~
but i always get this error
Could not read JSON: Can not deserialize instance of
org.springframework.samples.petclinic.model.CheckOpjID[] out of
START_OBJECT token
Here is my CHeckOPJID.java class
public class CheckOpjID {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
and here is my controller class
String url = "http://mywebservice:8080/SpringService/service/updatepool/selectdynamicurl/~!~''WEB1500001''~!~";
RestTemplate restTemplate = new RestTemplate();
CheckOpjID[] messageArray = restTemplate.getForObject(url, CheckOpjID[].class);
which is i have same code, and it worked! then i trying to create new class in another controller, then it starting give me Could not read JSON error, until this line (below)
CheckOpjID[] messageArray = restTemplate.getForObject(url, CheckOpjID[].class);
what i missed here??
This is what i missed, i have to delete the array Object, as Nikolay Rusev suggested
CheckOpjID messageArray = restTemplate.getForObject(url,
CheckOpjID.class);

Categories