#RequestBody map to object and get raw request string simultaneously - spring

I have use #RequestBody for mapping request to object at rest controller, but in the same time I need to get raw JSON from request without mapping. I don't map all JSON content to
object. How to get simultaneously JSON raw and JSON mapped to object
#RequestMapping(path = "/rest/web")
public ResponseEntity<String> paymentHook( #RequestBody UserReq request, BindingResult bindingResult)
I can just get raw like this #RequestBody String payload, but then I must parse content "by hand"

**You can parse your JSON raw data to JSONObject and simply get all keys**
String mockResponse = "{\"customer\":{\"id\":34,\"email\":\"tt#gmail.com\"}\"}";
JSONObject jsonResponse = JSONObject.fromObject(mockResponse);

Related

How to display x-www-form-urlencoded format request with springdoc-openapi-ui

My environment
springboot:2.6.4
springdoc-openapi-ui:1.6.6
Probrem
I want to create an API definition to receive requests in x-www-form-urlencoded format.
Using #RequestBody will create a swagger-ui display with no Parameter notation, just the body. However, when receiving a request in x-www-form-urlencoded format, it is necessary to receive it with #RequestParam, and if this is done, the swagger-ui display is created as a query parameter.
#PostMapping(value = "/v1/hoge")
public ResponseEntity<SampleResponse> postProc(
#RequestParam("param1") int param1,
#RequestParam("param2") String param2,
#RequestParam("param3") String param3,
HttpServletRequest request) {
  ・・・
}
swagger-image
However, since there is no actual query parameter, I do not want to display the Parameter in the same way as when receiving a request with #RequestBody.
The display without parameters is correct, as in POST /user in the following link.
http://158.101.191.70:8081/swagger-ui/4.5.0/index.html#/user/createUser
Is there a solution to this problem?
I might have a solution for you:
#PostMapping(value = "/v1/hoge", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public ResponseEntity<SampleResponse> postProc(
#RequestPart("param1") int param1,
#RequestPart("param2") String param2,
#RequestPart("param3") String param3,
HttpServletRequest request) {
  ・・・
}
In a perfect world, you could stick to the #RequestParam but I believe there is currently a bug with springdoc that make it impossible.

How to get all form data entries from request in a spring controller

Is there any way to get all form data entries described below in spring controller?
I tried several ways like Multipartfile[], HttpServletRequest as controller parameters
public ResponseEntity<String> endpoint1(HttpServletRequest request)
but it seems that spring somehow validates the form data and rejects all form data entries that have file or files as value and their key is other than "file" or "files" so the "file1" and "file2" are not presented in any field of HttpServletRequest request
the other form data entries data data2 data3 are presented in
HttpServletRequest request getParameterMap
#PutMapping(value="/api/event/videos/update/{id}")
public ResponseEntity<String> uploadFile(#PathVariable(value = "id") Long id,
#RequestParam("file1") MultipartFile file1, #RequestParam("file2") MultipartFile file2,
#RequestParam("data") Object data, #RequestParam("data1") Object data1,
#RequestParam("data2") Object data2) {
ObjectMapper mapper = new ObjectMapper();
DataResource dataResource = mapper.readValue(object.toString(), DataResource.class);
Data1Resource data1Resource = mapper.readValue(object.toString(), Data1Resource.class);
Data2Resource data2Resource = mapper.readValue(object.toString(), Data2Resource.class);
return ......
}

Get request body as string/json to validate with a json schema- Spring boot REST API

I'm trying to validate JSON (passed by a client as a request body) before it is converted into a model in Controller method.
If validation passes then return nothing, let the process continue as it was (spring boot to convert JSON into a model marked as #RequestBody). Throw error in case validation fails (everit-org/json-schema).
I tried to two way:
Implement HandlerMethodArgumentResolver, but resolveArgument() doesn't give request body details as it is already read and stored in ContentCachingRequestWrapper.
NOTE: inputStream in ContentCachingRequestWrapper doesn't have any request body details.
Using spring Interceptor. But this doesn't help me to find request body type passed in the request. As JSON schema is different for each request.
Any other approaches I can try with?
I cannot add a comment ... so ...
What kind of validation do you need? If you only want to validate the fields like length of a string or range of a number and so on. I recommend you use #Validated on controller mehtod parameter, and model:
#NotNull
#Size(min = 32, max = 32)
private String id;
controller:
#PatchMapping
public Object update(#RequestBody #Validated User user, Errors errors) {
...
}
If there is something wrong, errors.hasErrors() will return true.
edit:
OK, I did some tests, in a filter :
HttpServletRequest httpServletRequest = (HttpServletRequest)request;
ServletInputStream inputStream = httpServletRequest.getInputStream();
byte[] a = new byte[1024];
inputStream.read(a);
System.out.println(IOUtils.toString(a));
I got a json string (a piece of request body) :
{"template":"5AF78355A4F0D58E03CE9F55AFA850F8","bd":"" ...

HttpServletRequest in spring getting parameters values as null for post request

#ResponseBody
#RequestMapping(value = {"apiRequest"}, method = {RequestMethod.POST})
public String contestApiSignUp(HttpServletRequest req) throws JSONException {
try {
String username = req.getParameter("username");
String firstname = req.getParameter("firstname");
String lastname = req.getParameter("lastname");
String password = req.getParameter("password");
String phone = req.getParameter("phone");
Here the values I am getting all are null. That is username =null, firstname =null...
I am hitting post request with the values
http://localhost:8080/apiRequest.htm
username = Subhajit
firstname = Subha
...
like this.
But while I am using same code but,
#RequestMapping(value = {"apiRequest"}, method = {RequestMethod.GET})
using GET instead of POST then I am getting the proper values.
When you sent your HTML Form by POST to your URL /apiRequest, did you fill your data (username, firstname etc.) in fields in your form, or did you attached them to the sent URL (eg. apiRequest.htm?username=test&...) ?
Because with the second approach, you data will be accessible only through a GET request, not a POST. The first approach will work with a POST request.
Also, you do not need to call explicitly getParameter on the HttpServletRequest in a Spring Controller.
You can do this :
#ResponseBody
#RequestMapping (value = "apiRequest", method = RequestMethod.POST)
public String contestApiSignUp(
#RequestParam ("username") String username,
#RequestParam ("firstname") String firstname,
#RequestParam ("lastname") String lastname,
#RequestParam ("password") String password,
#RequestParam ("phone") String phone) {
return "Hello World";
}
From the comments, you said you are trying with postman to post the request, So are you building website or webservices? either way you should not be sending your data in the headers.
If you are building a website put together an HTML file from which
you can submit a form to this controller
If you are building webservice, change the controller and let it
accept JSON (or XML -I would discourage this though) body. Follow
this https://stackoverflow.com/a/40226580/6785908. And then from
postman (or curl), post a json instead.

Spring MVC process post data

I am working on a Spring MVC app. This application expects the client to send a XML in the request body. How can I extract this XML from the body and then create a DOM object?
I am using Spring 3.0
Thanks
Adi
Using the #RequestBody annotation:
The #RequestBody method parameter annotation indicates that a method
parameter should be bound to the value of the HTTP request body. For
example:
#RequestMapping(value = "/something", method = RequestMethod.PUT)
public void handle(#RequestBody String body, Writer writer) throws IOException
writer.write(body);
}
You convert the request body to the method argument by using an
HttpMessageConverter. HttpMessageConverter is responsible for
converting from the HTTP request message to an object and converting
from an object to the HTTP response body. The
RequestMappingHandlerAdapter supports the #RequestBody annotation with
the following default HttpMessageConverters:
ByteArrayHttpMessageConverter converts byte arrays.
StringHttpMessageConverter converts strings.
FormHttpMessageConverter converts form data to/from a MultiValueMap<String, String>.
SourceHttpMessageConverter converts to/from a javax.xml.transform.Source.

Resources