How to manipulate a payload in a REST API? - java

This is my first webservice and I am still understanding POST's GET's etc. I have been working on a Spring REST service. What I am confused about is how do I deal with a payload sent by another application?
Basically I have one app sending a json payload to my Spring REST API and I want to be able to grab the values of each key and store them in an object
Here is basically my code so far:
#RestController
public class Controller {
Payload payload;
Item item;
// gets the payload
#RequestMapping(value = "/buildevents/get-job", method = RequestMethod.GET, headers = "Accept=application/json")
public ResponseEntity <Payload> get() {
payload = new Payload();
payload.setJobName("Testing");
payload.setProjectName("Testing2");
payload.setUserName("Me");
payload.setPassWord("pass");
return new ResponseEntity<Payload>(payload, HttpStatus.OK);
}
#RequestMapping(value = "buildevents/create-item", method = RequestMethod.POST, headers = "Accept=application/json")
public ResponseEntity <Item> createItem(#RequestBody Item item) {
item.setProject(" ");
item.setItemName(payload.getJobName());
item.setUserName(" ");
item.setPassWord(" ");
return new ResponseEntity<Item>(item, HttpStatus.OK);
}
}
I want to do GET'S and POST'S from this code. The info I need to do so will come from a json payload POST to this service though, so I need to store the info from it in my object's setters. I don't know if I'm going about this wrong, but I'm lost.

Related

How to wrap an external API inside a custom API with Spring Boot

Let's say I have a third party rest api ("https://example.com/write") that allows POST requests with the following body structure:
{
"id": "abc",
"Config": {"Comments":"text"}
}
I am completely new to Java and the Spring Framework, but I want to create a custom API with Spring that only allow users to change the text part of the body. Other parts of the JSON body should have a fixed value (for example id is always "abc"). Basically, when user input a custom text string, my api will compile the input and consume the external api and get the results from it accordingly
I understand the basics of #Getmapping / #RequestMapping after doing some research. Here is what I have so far for my custom API, and I am stuck at the post mapping section.
#RestController
#RequestMapping("/api")
public class ApiController {
#Autowired
private Environment env;
// GET
#RequestMapping(value = "/retrive", method = { RequestMethod.GET })
public ResponseEntity<?> retrive (HttpServletRequest request, HttpServletResponse response) throws IOException {
// URL
URL u = new URL("https://example.com/get");
HttpURLConnection uc = (HttpURLConnection) u.openConnection();
// Create HttpHeaders for ResponseEntity
HttpHeaders responseHeaders = new HttpHeaders();
uc.setRequestProperty ("Authentication", "Bearer "+ env.getProperty("api-key"));
try (InputStream inputStream = uc.getInputStream();
OutputStream outputStream = response.getOutputStream();
)
{IOUtils.copy(inputStream, outputStream);
}
return new ResponseEntity<>(responseHeaders, HttpStatus.OK);
}
// POST
#RequestMapping(value = "/write", method = { RequestMethod.POST },
consumes = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity process(#RequestBody Root input) throws IOException {
// Operation goes here...
return new ResponseEntity<>(input, HttpStatus.OK);
}
public class Root{
private String Comments;
// Getters and Setters
}
Create a Custom DTO class which will represent the response from Third party API. What It means is it should have all fields which should map with corresponding required field of response payload of third party API. It will be populated on de-serializing the third party API response. You can take help of feign client here. Its very easy and declarative way to make REST API call.
Create a separate response DTO with 2 fields 1 which will have the static value and second the DTO which we created above (which will be populated with the response of third party API). This DTO will be the response from POST "/write"

How can I get the user_id from the request header instead of passing it as a request parameter? And then send it back through the header

For various REST api endpoints, the user_id will reach the backend, needed for further processing and then, sent back as a response to the front end.
I have a feeling I can do this through the header instead of passing it as a path parameter each time, except I can't seem to find the relevant information yet.
At the moment I send the response as a ResponseEntity. I would like, if possible, to keep this option.
I am using Java and Spring Boot.
example based on
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/ResponseEntity.html
edited to add readign header from request
#RequestMapping("/handle")
public ResponseEntity<String> handle(HttpServletRequest httpRequest) {
String userId= httpRequest.getHeader("user_id");
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("user_id", userId);
return new ResponseEntity<String>("Hello World", responseHeaders, HttpStatus.CREATED);
}
I have decided that the best approach for my scenario, where I only need to fetch the user id and then respond back with it, is to use the #RequestHeader("userId") Long userId annotation.
Let's have a look at how I had configured the enpoint initially:
#PostMapping(path = "/add-follower/{userIdForFollowing}/{currentUserId}")
public ResponseEntity<String> addFollower(#PathVariable ("userIdForFollowing") Long userIdForFollowing, #PathVariable Long currentUserId)
{
Follow newFollow = followService.returnNewFollow(userIdForFollowing, currentUserId);
newFollow = followService.saveFollowToDb(newFollow);
return new ResponseEntity<>("Follow saved successfully", HttpStatus.OK);
}
Now, let's look at how I refactored the endpoint to fetch the id's from the header and return them in the response:
#PostMapping(path = "/add-follower")
public ResponseEntity<String> addFollower(#RequestHeader("userIdForFollowing") Long userIdForFollowing, #RequestHeader("currentUserId") Long currentUserId)
{
Follow newFollow = followService.returnNewFollow(userIdForFollowing, currentUserId);
newFollow = followService.saveFollowToDb(newFollow);
//here I will add more code which should replace the String in the ResponseEntity.
return new ResponseEntity<>("Follow saved successfully", HttpStatus.OK);
}

Sending raw JSON using Postman value is null

A pleasant day.
I am having trouble with simply displaying string in raw JSON format using Postman.
This is what I have in my Java code:
#RestController
public class HeroController {
#RequestMapping(method = {RequestMethod.POST}, value = "/displayHero")
#ResponseBody
public Map<String, String> displayInfo(String name){
//System.out.println(name);
Map<String, String> imap = new LinkedHashMap<String, String>();
map.put("hero", name);
return imap;
}
}
Every time I test this in Postman, I always get null (again if I am using raw format):
{
"hero": null
}
But using form-data, on the other hand, displays just what I entered.
{
"hero": "wolverine"
}
Any information, or should do in Postman to make this raw format works instead of form-data? By the way, the raw format value is JSON(application/json), and in the Header Tab, the value of Content-Type is application/json; charset=UTF-8.
Thank you and have a nice day ahead.
Try the following code for consuming the request body as JSON, in spring boot:-
#RequestMapping(value = "/displayHero", method = POST, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE)
#ResponseBody
public String displayInfo(HttpEntity<String> httpEntity) {
String json = httpEntity.getBody();
// json contains the plain json string
// now you can process the json object information as per your need
// and return output as per requirements.
return json;
}
This code will accept json body of POST Request and then return it as response.

Receiving a POST Request on Spring From Another Site

I'm a little new in Java Spring. What I want to do is as follows:
Some 3rd party is asking a "return URL" from me and I set it as follows:
https://localhost:9002/my-account/order-history
Then they send me a POST request and I'm supposed to handle it within my controller. The request has both url parameters and a form data. The request is
Request URL:https://localhost:9002/my-account/order-history?responseCode=0000&token=E0ECFC1214B19E5D11B9B587920FC5F164C5CB17E7DC67F083E0EC6676F79467DFBDF4B6CCF3C39BF47F0232D1AA42F1FA112F29B0157DDF98EE3997F781CCB1FEB070A44E530691BA36674BEA4CF56A4A43F2B9746D9C3591CF288D745A6694
Request Method:POST
Status Code:403 Bad or missing CSRF token
Remote Address:127.0.0.1:9002
Referrer Policy:no-referrer-when-downgrade
A part of the form data is:
I added the whole form data and other request info as attachment.
The controller I'm desperately trying to use is as follows:
#Controller
#RequestMapping(value = "/my-account")
public class MaviAccountPageController extends MaviAbstractController
{
#RequestMapping(value = "/order-history", method = RequestMethod.POST)
public ModelAndView process(#RequestBody final String req)
{
//consumes = "text/plain"
System.out.println(req);
System.out.println(req);
return new ModelAndView("deneme");
}
....
}
And I keep getting 403 - Bad or missing CSRF token error.
How should I implement my controller? I have checked below links and they did not work out unfortunately:
How to retrieve FORM/POST Parameters in Spring Controller?
How to explicitly obtain post data in Spring MVC?
I tried, but failed to regenerate issue on postman.
Can anyone, please, advise me about how to move on?
you can annotate your method with #CrossOrigin
#CrossOrigin
#RequestMapping(value = "/order-history", method = RequestMethod.POST)
public ModelAndView process(#RequestBody final String req)
{
//consumes = "text/plain"
System.out.println(req);
System.out.println(req);
return new ModelAndView("deneme");
}
https://spring.io/guides/gs/rest-service-cors/

How to transfer data from one request to another request

I have a RestController in which the request is sent by the post method.
#RequestMapping(value = "/params", method = RequestMethod.POST)
public OneObject getParams(#RequestBody NeededObject neededObject) {
// logics
}
After the server processes this request.
Comes the answer to callback endpoint.
#RequestMapping(value = "/callback", method = RequestMethod.POST)
public DifferentObject callback(#RequestBody OtherObject otherObject) {
// processing the response otherObject and if the success
// needs to redirect the request to another endpoint
// with the parameters of the first query,
// transfer to #RequestBody NeededObject neededObject
}
How can I implement this?
The first two endpoints are on the same controller, and I need to redirect it to another controller (Controller below).
#RequestMapping(value = "/need", method = RequestMethod.POST)
public OneDto create(#RequestBody NeededObject neededObject) {
// logics
}
I'm trying something (the code below), but I do not know if it's a good way.
And I do not know where to get the response to inserting it when include.
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/need");
requestDispatcher.include(request, response);
Thank you for your help.

Categories