how to check wether a get param is set or not? - java

Is it possible to differenciate those two request URIs in one controller handler :
http://my-uri/
http://my-uri/?with_empty_param

HttpServletRequest object has a ParameterMap object that maps parameter name and its value.
With this map we can check if a parameter was passed in servlet request.
// Check if with_empty_param parameter exists
if (request.getParameterMap().containsKey("with_empty_param ")) {
String with_empty_param = request.getParameter("with_empty_param ");
}
If you want to use Spring way you could do:
#RequestMapping(value = {"/init"}, method = RequestMethod.GET)
public String methodName(
#RequestParam Map<String,String> allParams, ModelMap model) {
if (allParams.containsKey("with_empty_param ")) {
...
}

The #RequestMapping annotation has a params argument which you can use for that.
#RequestMapping
public void method1() {}
And with a check on the param.
#RequestMapping(params={"param"})
public void method2() {}
You can also use the ! to negate the check, so if that param isn't present.
#RequestMapping(params={"!param"})
public void method3() {}

Related

How to write a controller method's signature when url has a parameter data after the slash?

In PHP there is the possibility to recognize a parameter in the address bar by passing it in the controller's method ; for example :
http://192.168.2.49/papsp/index.php/meeting/modif/3
In this example the data 3 is taken as parameter value for the meeting controller's method modif :
public modif($key) { ... }
So how to proceed analogically in Spring ?
You need to use the #RequestMapping annotation, along with #PathVariable with your method param. And your url will be like this /meeting/modif/{key}.
Here's how should be your code:
#RequestMapping(value = "/meeting/modif/{key}", method = RequestMethod.POST)
public void modif(#PathVariable int key) {

Varargs in thymeleaf #ModelAttribute?

I want to pass multiple variable parameters (including none) for a #ModelAttribute evaluation from html thymeleaf page to a method:
//provide 0 or X params
#ModelAttribute("url")
public String url(String... params) {
return "generatedurl";
}
The following thymeleaf statements should be possible:
th:href="#{${url()}"
th:href="#{${url('page')}}"
th:href="#{${url('page', 'sort')}}"
But it does not work. Why?
#ModelAttribute is used to bind common objects to the model.
You are returning a String generatedurl every time from your method url() annotated with #ModelAttribute. So in your Thymleaf view every time yo do ${url} you get generatedurl.
One workaround for your problem could be this
#ModelAttribute("url")
public void url(Model model) {
model.addAttribute("url","YOUR_URL");
model.addAttribute("sort","age");
}
As a workaround: add the enclosing class as a model parameter, and call the method on this param from thymeleaf:
#Controller
public class PageController {
#GetMapping
public String persons(Model model) {
model.addAttribute("util", this);
return "persons";
}
public String url(String... params) {
//evaluate...
return "generatedurl";
}
}
It's then possible to access the methods as normal:
th:href="#{${url()}"
th:href="#{${url('page')}}"
th:href="#{${url('page', 'sort')}}"
Only drawback is of course having to add the class to the model explicit.
Another choice would be to initialize the model with the parameter permutations that I need. But that's less flexible:
#ModelAttribute
public void init(Model model) {
model.addAttribute("plainUrl", ...);
model.addAttribute("pageUrl", ...);
model.addAttribute("pageSizeUrl", ...);
}

How to use #PathVariable to Pojo?

I've created a POJO like this.
public class Param(){
#NotNull
private Sring paraA;
#NotNull
private Sring paraB;
//Setter and getter
}
And I want to use JSR303 to check it.
#RequestMapping(value = "/test/{paraA}/{paraB}")
#ResponseBody
public BaseJsonRsp test(#PathVariable #Valid Param param) {
//doSomething
}
But this code it doesn't work and I've got following error
HTTP Status 500 - Missing URI template variable 'value' for method parameter of type PatchValue!
Why? How to fix it? Thanks.
Have a look at the Spring Refererence Docs on #PathVariable:
A #PathVariable argument can be of any simple type such as int, long, Date, etc.
If you want to use your Param type as the controller method argument, you won't be able to do so using #PathVariable.
Alternatively, you can map your parameters to individual String variables (using #PathVariable), and then manually construct your Param after that. Note that #PathVariable assumes that the placeholder in your URL is the same as the variable name by default. If your variable name doesn't match, you'd do something like
#RequestMapping(value = "/test/{paraA}/{paraB}")
#ResponseBody
public BaseJsonRsp test(#PathVariable("paraA") String myParam,
#PathVariable("paraB") String otherParam) {
//doSomething
}
You need to explicity set the variable values from the URL into the Param object.
#RequestMapping(value = "/test/{paraA}/{paraB}")
#ResponseBody
public BaseJsonRsp test(#PathVariable("paraA") String paramA, #PathVariable("paraB") String paramB) {
Param param = new Param(paramA, paramB);
}
#PathVariable assumes that the placeholder in your URL is the same as the variable name by default. You need to do this
#RequestMapping(value = "/test/{paraA}/{paraB}")
#ResponseBody
public BaseJsonRsp test(#PathVariable("paraA") String paramA,
#PathVariable("paraB") String otherparam) {
Param param = new Param(paramA, paramB);
}

Spring MVC: Get Unnamed Request Parameter

What is the simplest way to access an unnamed request parameter in a Spring MVC controller? Is there an annotation for this similar to #RequestParam?
HTTP Delete request with unnamed parameter:
http://localhost/myEndPoint?someUnnamedParam
Controller:
public class MyController {
#RequestMapping(value = {"/myEndPoint"}, method = RequestMethod.DELETE)
public void deleteThing() {
// Do something with unnamed param
}
}
Details: Spring 3.0.7
I think you misunderstand.
In /myEndPoint?someUnnamedParam, you have a parameter named someUnnamedParam with a String value of "", ie. an empty String. It's parsed as an equivalent to /myEndPoint?someUnnamedParam=.
You can get a set of parameter names and use those as values.
#RequestMapping(value = {"/myEndPoint"}, method = RequestMethod.DELETE)
public void deleteThing((#RequestParam Map<String, List<String>> params) {
Set<String> paramNames = params.keySet();
...
}
You can always use
#RequestMapping(value = {"/myEndPoint"}, method = RequestMethod.DELETE)
public void deleteThing(HttpServletRequest request) {
String param = request.getQueryString();
// Do something with request
}
and perform any operations you need on request

Get requested value(URL) when using #RequestMapping annotations

When I map multiple values to #RequestMapping(like Multiple Spring #RequestMapping annotations), can I get the requested value(URL)?
Like this:
#RequestMapping(value={"/center", "/left"}, method=RequestMethod.GET)
public String getCenter(Model model) throws Exception {
String requestedValue = getRequestedValue(); // I want this.
// I want to do something like this with requested value.
String result;
if (requestedValue.equals("center")
result = "center";
else if (requestedValue.equals("left")
result = "left";
return result;
}
You can have the Request (HttpServletRequest) itself as an parameter of the handler method. So you can then inspect the request url to get the "value".
#RequestMapping(value={"/center", "/left"}, method=RequestMethod.GET)
public String getCenter(Model model, HttpServletRequest request) throws Exception {
String whatYouCallValue = request.getServletPath();
....
Javadoc: https://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServletRequest.html#getServletPath--
Btw: if I understand you right, you want to have different urls, not different values.
From Spring 3.1.0, you can use URI Template Patterns with Regular Expressions.
#RequestMapping(value={"/{path:[a-z-]+}"}, method=RequestMethod.GET)
public String getCenter(#PathVariable String path) throws Exception {
// "path" is what I want
}
From Spring 3.1.0, you can use ServletUriComponentsBuilder
#RequestMapping(value={"/center", "/left"}, method=RequestMethod.GET)
public String getCenter(Model model) throws Exception {
UriComponentsBuilder builder = ServletUriComponentsBuilder.fromCurrentRequest();
String requestedValue = builder.buildAndExpand().getPath(); // I want this.
System.out.println(requestedValue);
// I want to do something like this with requested value.
String result="fail";
if (requestedValue.equals("center"))
result = "center";
else if (requestedValue.equals("left"))
result = "left";
return result;
}
Use RequestParam annotation. You can also add a parameter of type HttpServletRequest to your method and then getParameters from that.
Addition to the best answer #Hugh_Lee:
This method will work for all not mapped requests. If you want to use this method just for two (or several) cases only, e.g. "/center" and "/left", you may do following. Rename "center" to "positionCenter", "left" to "positionLeft" (or add another common word). So the code would be like this:
#RequestMapping(value={"/{path:position+[A-Za-z-]+}"}, method=RequestMethod.GET)
public String getCenter(#PathVariable String path) throws Exception {
// "path" is what I want
}
Following regex will make your method to be executed only for the urls /center and /left. And you can get the value with #PathVariable annotation.
#GetMapping("/{path:^center$|^left$}")
public ResponseEntity<?> whatIsThePath(#PathVariable String path){
// path is either "center" or "left"
}

Categories

Resources