How to decode multiple request parameters in Spring MVC - java

I am trying to decode request parameters in a Spring MVC controller. The client has encoded these parameters and I want to bind them to an object. I expect that the parameters will automatically be decoded by Spring MVC when they are bound to the object.
I am trying to decode multiple request parameters in my code using Spring MVC. The client sends a request with multiple parameters, such as page, size, and search. I am using the #GetMapping annotation to handle the request and the #Valid annotation to validate the UserListRequest object. However, when the request is received, the search attribute is not being decoded properly and it is still in its encoded form.
#GetMapping
public List<User> getUsers(#PathVariable #NotNull String tenantKey,
#Valid UserListRequest request) {
// some code
}
The class UserListRequest
public class UserListRequest {
private Set<UserRole> role;
private String search;
// other attributes
}
The clients sends a request like this
GET http://localhost:8080/api/user?page=0&size=20&search=some_text%2B
Spring puts all the parameters to the object UserListRequest, but the attribute search is not decoded. It has some_text%2B and not some_text+.
I have tried using the #ModelAttribute annotation but it did not work as expected. The search attribute is still in its encoded form.
I would like to know how I can properly decode the search attribute and bind it to the UserListRequest object in my Spring MVC controller.

Related

Spring Controller GET/POST/PUT to another interface

I am using React as frontend and Java Spring Boot as backend.
React sends JSON form data as GET/PUT/POST requests to my backend url (http://localhost:8080/test). Now, I wan't to send this JSON forward to another interfaces GET endpoint (https://another/interface/add?id={id}). This interface then queries database based on the id and answers 200 OK message with a JSON reply which I need to display (send back to frontend).
1. What is the correct way of sending a request to another interface from Spring Boot backend? In the same method I catched the frontends data?
2. I also have to set HTTP headers to the GET request, how would I go on about this?
Example of how Frontend is sending an id field as a JSON to backend:
React POST
addId = async (data) => {
return this.post(/localhost:8080/test/id, data)
}
Example of how Backend is receiving the id field:
Spring Boot POST
#PostMapping("test/id")
public String test(#RequestBody String id) {
return id;
}
As I understand you want to get data from backend with json body and httpstatuscode 200 . Am i right?
May be you can try this
#GetMapping(/interface/add)
public ResponseEntity<?> test(#RequestParam("id") String id){
//write code you want
return ResponseEntity.status(HttpStatus.OK).body("string" or dto possible);
}
ResponseEntity send body with httpstatus code and if you want to send requestparam you set #RequestParam annotation to set .
When I do project with springboot and react. I use json type to exchange data. And Most Services usually exchange data with json data type.
2.I confused about this Question if you send data React to springboot your code is right
Axios.get("localhost....", data) you can change http type with
Axios.(get, post, delete)

what is the importance of value attribute in request mappping of post method and this value is co-related in the project in spring mvc?

i have a request mapping with post method but i do not know what i should put in value attribute.
#RequestMapping(value = "/register", method = RequestMethod.POST)
public String guestUserRegistration(#RequestHeader(value = "referer", required = false) final String referer,
final RegisterForm form, final BindingResult bindingResult, final Model model,
final HttpServletRequest request, final HttpServletResponse response, final RedirectAttributes redirectModel)
throws CMSItemNotFoundException
{
logger.info("guest User post method::");
return processGuestUserRequest(referer, form, bindingResult, model, request, response, redirectModel);
}
How the the "register" word as value is linked in spring mvc?
The HTTP method parameter has no default – so if you don't specify a value, it's going to map to any HTTP request.
#RequestMapping – by Path
In your example, you are mapping a request by path i.e "/register".
Request Mapping Basics
In Spring MVC applications, the RequestDispatcher (i.e. Front Controller) servlet is responsible for routing incoming HTTP requests to handler methods of controllers. When configuring Spring MVC, you need to specify the mappings between the requests and handler methods.
Test Mapping
To execute this mapping you just need to call this endpoint from your registoer action button. All API endpoints are relative to the base URL.
For example, assuming the base URL of https://api.example.com/, the /registor endpoint refers to https://api.example.com/registor.
https://api.example.com/registor
\______________________/\____/
server URL endpoint path

Cross Site Scripting support on Rest based POST Web service

I have designed a REST based post Service using Spring 3.
The service method consumes parameter as String and responds data as String. The param and response can be json or string
#RequestMapping(value = "/service", method = RequestMethod.POST)
public #ResponseBody String Service(#RequestParam("param") String param) {
Sample POST Request:
http://IP:PORT/test-project/service
param={"name":"John"}
Sample response to above request:
{"age":"31"}
Is there a way to safeguard this request against Cross Site Scripting?
If yes then how can I achieve XSS support once I receive request on param parameter??
If you aren't returning the parameter value (or any manipulation of it) in the response, you don't have an XSS vulnerability.
Not that it means that your service is completely secure, of course.

Parameters from URL using Java and spring boot

I am using Java and spring boot and I need to get information by a URL and store it in my class in Java. My URL is like this one
localhost:8080/send?adress=example
I want to store the value of the URL parameter to a variable in Java.
I would suggest reading tutorials on spring boot and web services such as this one:
https://spring.io/guides/gs/rest-service/
The RequestParam annotation is used to bind method parameters to web request parameters. e.g.
#RequestMapping(value="/send", method=RequestMethod.GET)
public String method(#RequestParam(value="address") String address) {
...
}
You don't need to send a parameter with the URL, it should be sent through request parameters.
Once you have added a parameter with the request, in spring-boot by #RequestParam we can get parameter values. e.g
#RequestMapping(value="/order/search", method=RequestMethod.GET)
public String method(#RequestParam(value="orderNumber") String orderNumber) {
get Order by orderNumber...
}

How to force clients to send etag/version using spring data rest?

We are using spring data rest via spring boot (v1.3.3) and have the following entity exposed via the standard REST Repository Exporter:
#Document
public class Project {
#Version
private Long version;
#CreatedDate
private LocalDateTime createdDate;
#CreatedBy
private String createdBy;
#LastModifiedDate
private LocalDateTime lastModifiedDate;
#LastModifiedBy
private String lastModifiedBy;
private String name;
//getters and setters omitted
}
A POST to /projects or a PUT to /projects/1234 for instance creates a document with etag/version 0. Another PUT to /projects/1234 overwrites the document even if the client does not provide a version/etag. Furthermore A DELETE on /projects/1234 deletes the document even if the client does not provide a version/etag.
How can I configure spring data rest to update and delete the document if and only if the client provides a valid version/etag?
The API client needs to specify a valid ETag on a header in the request, like this:
If-Match: <value of previous ETag>
By adding this header to the HTTP request, you convert it into a conditional operation that will only be carried out if it satisfies the condition. There are other conditionals such as If-None-Match or If-Modified-Since.
It is the responsibility of the client to add a conditional header.
From the question I understand that you would like the server to disallow any operation that does not provide a valid ETag, but as far as I know Spring Data Rest does not support this.
You can either change your clients to include the proper header (assuming they are under your control), or implement this feature by yourself.
You can take a look at the Reference Documentation for further info.
How to force clients to send etag/version using spring data rest?
Simply put: you can't, unless you write the clients.
How can I configure spring data rest to update and delete the document if and only if the client provides a valid version/etag?
That requires overriding the PUT/DELETE /projects/1234 handlers provided by Spring Data Rest and deal with ETags on your own.
In order to override the handlers, you need to annotate your controller with RepositoryRestController and use RequestMapping at the method level to still benefit from the other handlers provided by Spring.
To handle the ETag part, you can dig in the contents of the request headers (search for the If-* headers mentionned by #ESala by adding a HttpServletRequest paramater to your handlers.
#RepositoryRestController
public class ProjectRepositoryRestController {
#Autowired
private ProjectRepository repository;
#RequestMapping(value = "/projects/{id}", method = RequestMethod.PUT)
#ResponseBody
public Item update(#PathVariable(value = "id") String id, #RequestBody Project, HttpServletRequest request)
{
/* dig into the request headers */
// for instance
String header = request.getHeader("If-match");
// or more likely do something with request.getHeaders(...) or request.getHeaderNames(...) to check if the relevant headers are present.
/* apply your logic on Etags */
if (null == header) {
throw new ARelevantException();
}
/* go on with the processing of the request if everything is OK */
Project project = repository.findOne(id);
/* perform some magic with your entity and your input data */
project = repository.save(project);
return project;
}
}
To handle the headers, other options are available, such as using the RequestHeader annotation. You may also give a look at RequestEntity to get the request body and header at once (just don't mix a RequestEntity parameter and #RequestBody + #RequestHeader parameters).

Categories

Resources