Using Custom Object wrapper for Request Body - spring

I have a Spring service with the following API:
/v1/createUser
Request Body
{
"UserId" : "some-guid-value",
"Username" : "username",
"password" : "hashed-password"
}
The UserId in the body is optional. The other values are mandatory. I would like my API controller to be defined like this:
#RequestMapping(method = RequestMethod.POST, value = "v1/createUser")
#ResponseBody
public void createUser(
#RequestBody CreatUserRequest body)
Now, my question is, how do I (or is it even possible to) create the CreateUserRequest class such that Spring will reject the request if it doesn't see Username and password as part of the body. UserId is optional and may or may not be present.
Thanks!

Try
public class CreatUserRequest {
#NotBlank
private String username, password;
private UUID userId;
// getter and setter
}

I would complete Peter's Answer.
1. Decalre your condition using :#NotBlank in your DTO.
2. Validate entry on you rest controller through #Validlike this:
public void createUser(#RequestBody #Valid CreatUserRequest body)
This should work.

Related

Error 400 when receiving data from URL parameters en Spring MVC

I am trying to receive data from an URL with two parameters like this one:
http://localhost:80000/xxx/xxx/tickets/search?codprovincia=28&municipio=110000
No matter the approach, I am always getting a 400 error, but if I access the URL without the two parameters, the controller returns the view correctly (without the parameters, naturally)
This is the code of my controller:
#Controller
#RequestMapping(value = "/xxx" )
public class BuscadorIncidenciasController extends BaseControllerWeb {
#RequestMapping("tickets")
public String tickets(Model model, #RequestParam ("codprovincia") String codprovincia, #RequestParam ("municipio") String municipio, HttpServletRequest request) throws NoAjaxException {
//...
return CONST.JSP_VIEW;
}
...}
Extra info: if I use this URL:
http://localhost:9081/xxx/xxx/tickets/search/28/790000
And this code:
#Controller
#RequestMapping(value = "/xxx" )
public class BuscadorIncidenciasController extends BaseControllerWeb {
#RequestMapping(value = "buscar/{codprovincia}/{municipio}", method = RequestMethod.GET)
public String buscar(#PathVariable Integer codprovincia, #PathVariable Integer municipio ,Model model, HttpServletRequest request) throws NoAjaxException {
//...
return CONST.JSP_VIEW;
}
...}
It gets the parameters correctly. The problem is that I have to use the first URL. I have reviewed similar questions about similar issues, and I have implemented the solutions to those issues, but I get the 400 error regardless what I try (add value="xxx=, required=false, and other suggestions.)
For RequestParam, you need to explicitly add 'name' attribute
#RequestParam(name = "codprovincia"), #RequestParam (name = "municipio")
No need to for HttpServletRequest, unless you have reason
Also, in your 'tickets' method, RequestMapping is not conforming to your URL path.
I think it should be
#RequestMapping("/xxx/tickets/search")
Cheers!

How to send model attribute to spring controller

I want to test my controller using postman but don't know how to send a model attribute using postman. I even don't know whether it is possible or not.
My Controller seems like:
#Controller
#RequestMapping(path = "/api/v1")
public class PaymentController {
#Autowired
private CredentialsRepository credentialsRepository;
#PostMapping(path = "/charge")
public String charge(#ModelAttribute("pay-load") PayLoad payLoad, Model model) {
Credentials creds = credentialsRepository.findCredentialsById(1);
if (creds == null)
return "init_credentials";
return "charge";
}
}
Model Attribute
public class PayLoad {
private Integer mId;
private Integer ordId;
private Integer cardId;
private Integer cvvNo;
private String hash;
// getter & setter
}
I found the way to send model attributes to the spring controller.
see above screenshot for your reference.
Even you can pass all the key and value in requestParam from postman.
Instead of requestBody. ModelAttribute object treat each and every key and value as requestParam. It's just a way to combine a lot of requestParam in one object. Even you can try out with curl request, so it will make you more clear.
Thanks

How to specify multiple parameters in POST method

I have Model called Loan:
public class Loan {
private int loan_id;
private String clientName;
private String clientSurname;
private Double amount;
private int days;
//getters and setters
}
And Controller
#RestController
public class MyController {
#Autowired
MyService myService;
#RequestMapping(value = "/makeAction",method = RequestMethod.POST)
public String makeLoan(){
return myService.makeAction(...);
}
}
The question is: how to bypass multiple variables via adressbar like:
localhost:8080/makeAction?loanId=1#clientName=Stive#clientSurname=Wassabi
and so on.
UPD: Another attempt failed:
#RequestMapping(value="/makeLoan",method = RequestMethod.GET)
public String makeLoan(#PathVariable("loan_id")int loan_id,
#PathVariable("name") String clientName,
#PathVariable("surname") String clientSurname,
#PathVariable("amount") double amount,
#PathVariable("days") int days ) throws Exception {
return myService.makeLoan(loan_id,clientName,clientSurname,amount,days);
P.S tried #PathVariables - failed to use
Thanks you all for helping me with this
The final code looks like that:
#RequestMapping(value = "/makeAction")
public String makeLoan(#RequestParam("loan_id")int loan_id,
#RequestParam("clientName")String clientName,
#RequestParam("clientSurname")String clientSurname,
#RequestParam("amount")double amount,
#RequestParam("days")int days ) throws Exception {
return loanService.makeAction(loan_id,clientName,clientSurname,amount,days);
}
I had to remove GET/POST method and switch #PathVariable to #RequestParam
Well, first of all, you shouldn't put parameters for POST in the URL.
URL parameters are used for GET, and they are separated with & so in your case:
localhost:8080/makeAction?loanId=1&clientName=Stive&clientSurname=Wassabi
For POST you should submit parameters as request body parameters. Parameters are bound with #RequestParam annotation like #SMA suggested.
In your method define them with RequestParam annotation like:
public String makeLoan(#RequestParam(value="clientName", required=false) String clientName) {//and others, and hope you meant & to seperate request parameters.
}
Well, assuming you're using spring MVC, this could be helpful:
How to explictely obtain post data in Spring MVC?
Be aware that if you're using a POST method, your parameters should be read in the request body...

Spring MVC parse web url Object

I have a GET request in the format below
http://www.example.com/companies?filters=%7B%22q%22%3A%22aaa%22%7D
After decode it is
filters={"q":"aaa"}
I have created an Object named Filters as below
public class Filters {
private String q;
//getter setter....
}
and in my controller
#RequestMapping(method = RequestMethod.GET)
public List<CompanyDTO> getCompanies(Filters filters) {
filters.getQ();
//do things
}
However, the filters.getQ() is null.
Am I doing something incorrect here?
You need to associate the request parameter to the method argument. Add #RequestParam to your method i.e.
#RequestMapping(method = RequestMethod.GET)
public List<CompanyDTO> getCompanies(#RequestParam(value="filters") Filters filters) {
filters.getQ();
//do things
}
Instead of #RequestParam, use #RequestBody
Instead of String filters=%7B%22q%22%3A%22aaa%22%7D, pass JSON object as parameter http://www.example.com/companies?filters={"q":"aaa"}

Java Spring REST, value from object (POST)

I have a quick question. I`m sending two params in a json object (user) from angular to my spring app using POST. When I display this object it is:
System.out.println(user.email);
{email=example#example.com, password=gfdgdfgf}
In Java my code is:
#RequestMapping(value="/userLogin", method = RequestMethod.POST)
public boolean userLogin(#RequestBody Object user, ModelMap model) {
...
}
But when I try to display the field from this object like:
user.password, it doesn`t work.
Many thanks for help!
You are mapping your data to an Object, which lacks the needed fields(email and password). You should create an entity class and use it instead. Jackson should be able to map your passed parameters.
public class User{
public String email;
public String password;
/* ... */
}

Resources