Get values from received html body - java

I want to get the body values from received html request body using Spring boot:
#PostMapping(value = "/v1/notification")
public ResponseEntity<String> handleNotifications(
#RequestParam(value = "uniqueid", required = false)) String uniqueidValue,
#RequestParam(value = "type", required = false)) String statusValue) {
// Get values from html body
return new ResponseEntity<>(HttpStatus.OK);
}
For example when I receive into the notification body:
some_key=some_value&sec_key=sec_value
I would like to parse the values. How I can implement this?

You can take the key value pair request with using Map and #RequestBody as below:
#PostMapping(value = "/v1/notification")
public ResponseEntity handleNotifications(#RequestBody Map<String,String> keyValuePairs) {
// here you can use keyValuePairs
// you can process some specific key like
String value = keyValuePairs.get("someSpecificKey");
return ResponseEntity.ok(value);
}
Here I attach example postman request :

Related

How can I propagate request headers to response headers in SpringBoot 2

I have interfaces generated by Swagger Codegen. It looks like this:
#PostMapping(value = "/ipc/conf", produces = {"application/json", "application/problem+json"}, consumes = {
"application/json"})
default ResponseEntity<CustomResponseEntity> ipcConfPost(
#ApiParam(value = "ID", required = true) #RequestHeader(value = "X-Request-ID", required = true) String xRequestID,
#ApiParam(value = "Value for identifying a single transaction across multiple services up to the backend.", required = true) #RequestHeader(value = "X-Correlation-ID", required = true) String xCorrelationID,
#ApiParam(value = "The payload to transmit", required = true) #Valid #RequestBody IPcData ipcConfData,
#ApiParam(value = "The business context is a general classification for a larger number of requests.") #RequestHeader(value = "X-Business-Context", required = false) String xBusinessContext) {
getRequest().ifPresent(request -> {
for (MediaType mediaType : MediaType.parseMediaTypes(request.getHeader("Accept"))) {
if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {
String exampleString = "{ \"id\" : \"id\", \"error\" : \"error\" }";
ApiUtil.setExampleResponse(request, "application/json", exampleString);
break;
}
}
});
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
}
In the implementation I want to have a full list of request headers (I need some of them in the response) or to be able to get a value of a header that is not listed in the API. The thing is I cannot change the signature of the endpoint since it will cause a major headache in further releases.
So is there any way to achieve this?
You have the request object in your code already so you can get the headers from it. i.e. request.getHeaderNames() then loop through them.
After that, you can add them to the response with
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("key", "value");
ResponseEntity.ok().headers(responseHeaders).body("some body");

Return XML or JSON from a REST controller based on request parameters

This is my controller:
#PostMapping(value = "/endpoint", produces = { APPLICATION_JSON_VALUE, APPLICATION_XML_VALUE})
#ResponseBody
public Result generateResult(#Valid #RequestBody Request request) throws JsonProcessingException {
Result result = new Result();
// some code here
return result;
}
and this is my Request class:
#Data
#NoArgsConstructor
public class Request {
#NotNull
private String name;
private String type = "application/json";
}
the controller produces the correct output based on the Accept header in the request sent by the client. However, I want to send no Accept header and only send the following request:
{
"name": "my name",
"type": "application/xml"
}
Then based on the type the correct format should be output. I tried to add HttpServletResponse response to the parameter list of the controller method and then set the content type like this:
response.setHeader(CONTENT_TYPE, request.geType());
but it always returns json. any idea what else I should do?
I think a standard Spring's ResponseEntity builder give you all needed variety:
return ResponseEntity
.ok(//any object for json structure)
.headers(//any header)
.build();
Instead .ok() you can you any other method (that's http status code)
or
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("MyHeader", "MyValue");
return new ResponseEntity<String>("Hello World", responseHeaders, HttpStatus.OK);
based on the comments I post this answer which worked for me. I changed my controller method like this:
#PostMapping(value = "/endpoint", produces = { APPLICATION_JSON_VALUE,
APPLICATION_XML_VALUE})
#ResponseBody
public ResponseEntity<Result> generateResult(#Valid #RequestBody Request request)
throws JsonProcessingException {
Result result = new Result();
// some code here
return ResponseEntity.accepted()
.headers(headers)
.body(result);
}

Spring Boot POST parameter size limit

I seem to be butting heads with a limiter somewhere. One of my Spring-Boot REST endpoint (POST) parameters (surveyResults) is looking for a string of JSON:
private static final String SURVEY_RESULTS_ENDPOINT = "/survey/results";
#PostMapping(
value = SURVEY_RESULTS_ENDPOINT,
produces = { "application/hal+json", "application/json" }
)
#ApiOperation(value = "Save one survey results")
public Resource<SurveyResult> createSurveyResults(
#ApiParam(value = "who/what process created this record", required = true) #Valid
#RequestParam(value = "recordCreatedBy", required = true) String createdBy,
#ApiParam(value = "was an issue identified", required = true)
#RequestParam(value = "hadFailure", required = true) Boolean hadFailure,
#ApiParam(value = "JSON representation of the results", required = true)
#RequestParam(value = "surveyResults", required = true) String surveyResult
) ...
If I post to this with about 1500 characters, it works. Somewhere just over that and it will fail with a HTTP 400 error bad request. The whole payload is less than 2K with the other parameters.
I just moved from Wildfly to a new server setup. My company is adopting continuous deployment to cloud servers so i don't have much control nor visibility to this new load balanced server. The server is "server": "openresty/1.13.6.2" - any idea what limit I am running into?
Please use #RequestBody instead of #RequestParam.
#RequestBody annotation maps the HTTP request's body to an object. #RequestParam maps the request parameter in the request, which is in the URL and not in the body.
Most browsers have a limitation to the number of characters supported in a request parameter, and you just hit that limit.
What I would suggest is to create a POJO that looks like this
public class Body {
private String createdBy;
private Boolean hadFailure;
private String surveyResult;
// getters and setters
}
Now your controller will be simpler
#PostMapping(
value = SURVEY_RESULTS_ENDPOINT,
produces = { "application/hal+json", "application/json" }
)
public Resource<SurveyResult> createSurveyResults(#RequestBody Body body) {
}
Wherever you are posting, you will have to now post a JSON (Content-Type = application/json) that looks like the following
{ "createdBy" : "foo", "hadFailure" : false, "surveyResult" : "the foo bar"}

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.

Angularjs-Spring : Getting parameter as Null in controller

Here is the code for the controller
#RequestMapping(value = "/fetchRecord/", method = RequestMethod.POST)
#ResponseBody
public String fetchRecord(Integer primaryKey)
{
return this.serviceClass.fetchRecord(primaryKey);
}
Here is my angular code
var dataObj = {
primaryKey : $scope.primaryKey
};
var res = $http.post('/Practice/learn/fetchRecord/', dataObj);
res.success(function(data, status, headers, config) {
$scope.firstname = data;
});
res.error(function(data, status, headers, config) {
alert("failure message: " + JSON.stringify({
data : data
}));
});
i am able to debug my code. Although i can check it in browser that value for primaryKey get passed. But still it is null in controller.
any possible reason for that ?
You should send a json object,
try this,
var dataObj = {
primaryKey : $scope.primaryKey
};
var res = $http.post('/Practice/learn/fetchRecord/', angular.toJson(dataObj));
You can get the value in the Controller from two ways:
First option:
Assign an object that has the attribute you want to pass.
Suppose that you have RecordEntity object, it has some attributes, one of them is the Integer primaryKey. The annotation #RequestBody will receive the value, so the controller will be:
backend
#RequestMapping(value = "/fetchRecord/", method = RequestMethod.POST)
#ResponseBody
public String fetchRecord(#RequestBody RecordEntity recordEntity) {
return "primaryKey from requestBody: " + recordEntity.getPrimaryKey();
}
frontend
In the frontend you should send an json that has the primaryKey attribute in the body, for example:
http://localhost:8080/Practice/learn/fetchRecord/
Post body:
{
"primaryKey": 123
}
You controller will receive the value in the RecordEntity object.
Second option:
Pass the value by URL, the annotation #RequestParam will receive the value, so the controller will be:
backend
#RequestMapping(value = "/fetchRecord", method = RequestMethod.POST)
#ResponseBody
public String fetchRecord(#RequestParam Integer primaryKey) {
return "primaryKey from RequestParam: " + primaryKey;
}
frontend
In the url you should send the value with ?primaryKey, for example
http://localhost:8080/Practice/learn/fetchRecord?primaryKey=123
You controller will receive the value in the Integer primaryKey.

Categories