Spring - Query parameters without question mark - spring

I'm having an issue parsing an URL with Spring.
My endpoint is
#RequestMapping(path = "/register", method = RequestMethod.GET)
public String userActivation(#RequestParam("token") String token, #RequestParam("code") String code, final Map<String, Object> model) {
...
}
So I am expecting a token and a code in the URL.
The problem I am facing is that the service redirecting to my page omits the question mark, something like:
http://myapp/register/&token=sdgddfs&code=fdasgas
Which Spring fails to match to my endpoint.
Is there any way to handle this?

You can re-write you method using #PathVariable instead of #RequestParam
So you'll have an URL like http://myapp/register/sdgddfs/fdasgas, and an annotation for method
#RequestMapping(path = "/register/{token}/{code}")
public String userActivation(#PathVariable("token") String token, #PathVariable("code") String code) { ... }

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!

spring mvc truncating special symbols

We have an application created in spring-boot. We have a rest controller in place as below
#RequestMapping(value = "getDataFromSpaceForTypeForSpaceId/{gridName}/{spaceName}/{dataType}/{spaceId}", method = GET, produces = "application/json")
public DetailedJsonView getDataFromSpaceForTypeForSpaceId(#PathVariable String spaceId,
#PathVariable String dataType,
#PathVariable String gridName,
#PathVariable String spaceName) throws Exception {
Object detailedObject = spaceAccessorService.getDetailedDataFromSpaceForTypeNameWithSpaceId(gridName, spaceName, dataType, spaceId);
String detailedXml = ObjectMarshallarService.marshal(detailedObject);
return new DetailedJsonView(detailedXml);
}
for the urls like this it works fine
http://localhost:8080/rest/query/getDataFromSpaceForTypeForSpaceId/COLO/gcmmprivateSpace/com.ambuj.ValuationSliceRun/InterestRates
for the urls like this the last variable spaceId
http://localhost:8080/rest/query/getDataFromSpaceForTypeForSpaceId/COLO/gcmmprivateSpace/com.ambuj.ValuationSliceRun/InterestRates#MUREX:RATES:EMEA:2015-01-01
Now what we see on the above url is that spaceId comes as InterestRates instead of InterestRates#MUREX:RATES:EMEA:2015-01-01.
I am not sure how i can resolve that

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 RequestMapping PathVariable in the first place

I would like to set for each user's own profile link.
Like this:
#RequestMapping(value = "/{userlogin}", method = RequestMethod.GET)
public String page(#PathVariable("userlogin") String userlogin, ModelMap model) {
System.out.println(userlogin);
return "user";
}
But static pages get this expression too..
Like this:
#RequestMapping(value = "/hello", method = RequestMethod.GET)
public String hello() {
System.out.println("hello mapping");
return "hello";
}
That is when I request GET request "hello" that calls both controllers.
I would like to do that, user controller calls only if other methods not called.
Console, when I calls localhost:8080/123:
123
Console, when I calls localhost:8080/hello:
hello
hello mapping
or
hello mapping
hello
I want to get only
hello mapping
when calls localhost:8080/hello
Who knows how it can be implemented?
Spring MVC can use URI Template Patterns with Regular Expressions. Provided :
userlogin only contain digits
others URL immediately under root contains at least one non digit character
you can use that in your #RequestMapping :
#RequestMapping(value = "/{userlogin:\\d+}", method = RequestMethod.GET)
public String page(#PathVariable("userlogin") String userlogin, ModelMap model) {
//...
}
If the separation between userlogin and other URL is different from what I imagined, it can be easy to adapt.

how to capture multiple parameters using #RequestParam using spring mvc?

Suppose a hyperlink is clicked and an url is fired with the following parameter list myparam=myValue1&myparam=myValue2&myparam=myValue3 . Now how can I capture all the parameters using #RequestParam in spring mvc?
My requirement is I have to capture all the params and put them in a map.
Please help!
#RequestMapping(value = "users/newuser", method = RequestMethod.POST)
public String saveUser(#RequestParam Map<String,String> requestParams) throws Exception{
String userName=requestParams.get("email");
String password=requestParams.get("password");
//perform DB operations
return "profile";
}
You could use RequestParam in the above mentioned manner.
It seems you can't get
Map<String,String>
because all your params have same name "myparam"
Try this instead:
public ModelAndView method(#RequestParam("myparam") List<String> params) { }
To get all parameters at once try this:
public ModelAndView postResultPage(#RequestParam MultiValueMap<String, String> params)
This feature is described in the #RequestParam java doc (3. Paragraph):
Annotation which indicates that a method parameter should be bound to a web request parameter. Supported for annotated handler methods in Servlet and Portlet environments.
If the method parameter type is Map and a request parameter name is specified, then the request parameter value is converted to a Map assuming an appropriate conversion strategy is available.
If the method parameter is Map<String, String> or MultiValueMap<String, String> and a parameter name is not specified, then the map parameter is populated with all request parameter names and values.
As of Spring 3.0, you can also use MultiValueMap to achieve this:
A rudimentary example would be:
public String someMethod(#RequestParam MultiValueMap<String,String> params) {
final Iterator<Entry<String, List<String>>> it = params.entrySet().iterator();
while(it.hasNext()) {
final String k = it.next().getKey();
final List<String> values = it.next().getValue();
}
return "dummy_response";
}
If anyone is trying to do the same in Spring Boot, use RequestBody in place of RequestParam
Spring mvc can support List<Object>, Set<Object> and Map<Object> param, but without #RequestParam.
Take List<Object> as example, if your object is User.java, and it like this:
public class User {
private String name;
private int age;
// getter and setter
}
And you want pass a param of List<User>, you can use url like this
http://127.0.0.1:8080/list?users[0].name=Alice&users[0].age=26&users[1].name=Bob&users[1].age=16
Remember to encode the url, the url after encoded is like this:
http://127.0.0.1:8080/list?users%5B0%5D.name=Alice&users%5B0%5D.age=26&users%5B1%5D.name=Bob&users%5B1%5D.age=16
Example of List<Object>, Set<Object> and Map<Object> is displayed in my github.
You can use for multiple Params as such
public String saveUser(#RequestParam("email") String userName, #RequestParam("password") String password) throws Exception{
//your code
//perform DB operations
return "profile";
}
For params with same name, you can use MultiValueMap<String ,String>. Then all the values would be present as List
You can use multiple #RequestParam annotations as shown below.
#RequestParam(value="myparam1", required = true) <Datatype> myparam1,
#RequestParam(value = "myparam2", required = false) <Datatype> myparam2,

Resources