#ModelAttribute always maps Boolean to false - spring

when I try to map Boolean value from url to spring controller, it always map to false.
This is my url
http://localhost:8080/myurl?isFirstTime=true
here is my controller
#RequestMapping(value = "/myurl", method = RequestMethod.GET)
public ResponseEntity<?> getMyUrl(#Valid #ModelAttribute MyObject ap,BindingResult bindingResult ) {
//here isFirstTime is always set to false
}
MyObj is POJO and has several other attributes which are mapping perfectly
public class Myobj{
private boolean isFirstTime
//there are other members as well
//getter setter
i tried putting #JsonProperty but that also didn't work
#JsonProperty
private boolean isFirstTime
any idea what am I doing wrong here ?

With #ModelAttribute, the object will be initialized:
From the model if already added via Model.
From the HTTP session via #SessionAttributes.
From a URI path variable passed through a Converter.
From the invocation of a default constructor.
From the invocation of a "primary constructor" with arguments matching to Servlet request parameters; argument names are determined via JavaBeans
In your case, it might relative to the last statement.
You can try 2 way to solve it:
- Provide the constructor with the boolean argument in Myobj.java
- Add more method to initialize the #ModelAttribute Myobj firstly
#ModelAttribute
public Myobj initObj(#RequestMapping boolean isFirstTime){
Myobj obj = new MyObj();
obj.setIsFirstTime(isFirstTime);
return obj;
}

The most easiest method could be
#RequestMapping(value = "/myurl", method = RequestMethod.GET)
public ResponseEntity<?> getMyUrl(#Valid #ModelAttribute MyObject ap,#RequestParam boolean isFirstTime, BindingResult bindingResult ) {
//here isFirstTime is always initialized from incoming request parameters
// you can set it ap.isFirstTime(isFirstTime); // or whatever your setter method is
}

I stuck at this problem, but I've found that we must use Boolean object instead of boolean primitive type to map boolean value correctly in ModelAttribute

Related

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

Issue with Spring Rest #RequestMapping when negating params

I have two spring controller methods :
#RequestMapping(value="/requestotp",method = RequestMethod.POST,params = "!applicationId") //new customer
public OTPResponseDTO requestOTP( #RequestBody CustomerDTO customerDTO){
return customerService.requestOTP(customerDTO);
}
#RequestMapping(value="/requestotp",method = RequestMethod.POST,params = {"idNumber","applicationId"}) //existing customer
public String requestOTP( #RequestParam(value="idNumber") String idNumber , #RequestParam(value="applicationId") String applicationId) {
return customerService.requestOTP(idNumber, applicationId);
}
using "!applicationId" , I am expecting that when I call the url with applicationId parameter there that the second method will be called , but actually when I pass a request like this :
{"idNumber":"345","applicationId":"64536"}
The first method gets called
This is the part of the params paremeters documentation that I rely on :
Finally, "!myParam" style expressions indicate that the specified
parameter is not supposed to be present in the request.
Can't you just simply delete first request params?
#RequestMapping(value="/requestotp",method = RequestMethod.POST) //new customer
public OTPResponseDTO requestOTP( #RequestBody CustomerDTO customerDTO){
return customerService.requestOTP(customerDTO);
}
The issue actually wasn't with negating the parameter, the issue was that I was sending {"idNumber":"345","applicationId":"64536"} in the POST body and I was expecting the variables to be mapped to the method parameters annotated with #RequestParam ... this is not correct ... #RequestParam only map URL parameters .... so the controller was trying to find the best match so it was using the first method as it contained #RequestBody

Spring data binding with and without #modelAttribute in method parameter

I've read that adding #modelAttribute in method param binds the incoming data to the object and add it to the model object as attribute.
#RequestMapping(value = "/list", method = RequestMethod.GET)
public String list(#ModelAttribute User user) {
return "list";
}
if this is accessed via /list?name=unnamed, in list.jsp "unnamed" can be seen using {user.name} because it was added as model attribute for list.jsp. This is very clear to me.
But if i do
#RequestMapping(value = "/list", method = RequestMethod.GET)
public String list(User user) {
return "list";
}
"unnamed" can still be seen using {user.name} when accessed via /list?name=unnamed. I thought the user object will not be added into model because it does not have #ModelAttribute annotation.
Are you sure of this part of code: return "list"; ???
Seems you are returnig the String, not the object. Try it and post and both cases, I have no permissions to comment yet =\

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"}

Spring Mvc ModelAttribute with referencing name is not working?

I want to to create different #Entity entities within the same Controller.
#RequestMapping(value="create", method=RequestMethod.GET)
public String GET(Model model) throws InstantiationException, IllegalAccessException
{
Class<?> clazz = ????; // a Random POJO is chosen, i want to use POJOs!!
Object object = clazz.newInstance();
model.addAttribute("object", object);
return "create";
}
#RequestMapping(value="create", method=RequestMethod.POST)
public #ResponseBody Object POST(#ModelAttribute(value="object") Object object)
{
System.out.println("POST! got type: " + object.getClass().getName());
return object;
}
In the Post Method I get NULL for #ModelAttribute(value="object") Object object
If I change it to #ModelAttribute(value="object") realType object it is working perfectly fine. But I don't know the type yet.
I thought the #ModelAttribute can achieve this anyway with the name "object" but apparently not. What am I missing?
There is no actual model object named object when you submit, spring constructs it based on the parameter type and will bind the properties accordingly.
You have 2 choices to make it work
Store the object in the session
Use a #ModelAttribute annotated method
If neither of these are there spring will simply look at the method argument and use reflection to construct an instance of that class. So in your case it will only be Object and after that binding will fail.
Store object in the session
#Controller
#SessionAttributes("object")
public class MyController { ... }
Make sure that when you are finished that you call the setComplete() method on a SessionStatus object.
Use a #ModelAttribute annotated method
Instead of creating and adding the object in a request handling method create a speficic method for it.
#ModelAttribute("object")
public Object formBackingObject() {
Class<?> clazz = ????; // a Random POJO is chosen, i want to use POJOs!!
Object object = clazz.newInstance();
return object;
}
This method will be called before each request handling method, so that a newly fresh object is constructed which will be used for binding.

Resources