How to get request URI without Path Variables? - java

The Method request.getRequestURI() returns URI with path variables.
The following example service takes Path Variable. How can I get URL that without Path Variables
#RequestMapping(value = "/getUser/{username}", method = RequestMethod.GET)
public ResponseEntity<UserDTO> getUser(#PathVariable String username)
if i make request like this(
localhost:8080/user/getUser/tommy
)
request.getRequestURI() returns with path variable.
user/getUser/tommy
I want to get a result like this:
user/getUser/
or
user/getUser
How can I get the path without path variables?

I don't see any Spring MVC way. You can parse from one of the available HttpServletRequest methods.
For instance
#Controller
public class SampleController {
#GetMapping("/sample/path/{last}")
public ResponseEntity<Object> sampleMethod(#PathVariable String last, HttpServletRequest request) {
System.out.println(request.getContextPath());
System.out.println(request.getRequestURI());
String path = request.getServletPath();
System.out.println(path);
System.out.println(path.substring(0, path.lastIndexOf(last)));
return ResponseEntity.ok(last);
}
}
/context
/context/sample/path/boom
/sample/path/boom
/sample/path/

Not possible. You have to write logic by your self to extract the path variable.

Related

How Spring controller handles parameter implicitly?

I am a newbie on Spring framework and maybe this is an easy question.
I have a link as follows and attempt Spring controller handles the value"201610061023" of this link.However,my code did not work.
I know this value can be attached as a parameter or pathvariable in path but I just curious can I pass this value implicitly?
Thank you very much.
201610061023
#RequestMapping(value = "/Order")
public String requestHandlingMethod(#ModelAttribute("test") String name, HttpServletRequest request) {
return "nextpage";
}
Spring will not handle the title of the link simply because the title of the link will not be sent by the browser. To send it you can either:
add the value as parameter: 201610061023
add the value as path variable: 201610061023
add a JavaScript that will copy the title onClick into the href or send the generated URL with document.location. This can be automated, but it's pretty uncommon.
Your a-tag is wrong, you need to submit the id, there is no implicit way to submit the link-text (except a lot of java script code)!
201610061023
#RequestMapping(value = "/Order/{orderId}")
public String requestHandlingMethod(#PathVariable("orderId") long orderId, #ModelAttribute("test") String name, HttpServletRequest request) {
return "nextpage";
}
or
201610061023
#RequestMapping(value = "/Order")
public String requestHandlingMethod(#RequestParam("orderId") long orderId, #ModelAttribute("test") String name, HttpServletRequest request) {
return "nextpage";
}
See #RequestParam vs #PathVariable for the difference between this two approaches

Real REST-API format for GET /users/:id [duplicate]

Can you give me a brief explanation and a sample in using #PathVariable in spring mvc? Please include on how you type the url?
I'm struggling in getting the right url to show the jsp page. Thanks.
suppose you want to write a url to fetch some order, you can say
www.mydomain.com/order/123
where 123 is orderId.
So now the url you will use in spring mvc controller would look like
/order/{orderId}
Now order id can be declared a path variable
#RequestMapping(value = " /order/{orderId}", method=RequestMethod.GET)
public String getOrder(#PathVariable String orderId){
//fetch order
}
if you use url www.mydomain.com/order/123, then orderId variable will be populated by value 123 by spring
Also note that PathVariable differs from requestParam as pathVariable is part of URL.
The same url using request param would look like www.mydomain.com/order?orderId=123
API DOC
Spring Official Reference
Have a look at the below code snippet.
#RequestMapping(value="/Add/{type}")
public ModelAndView addForm(#PathVariable String type) {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("addContent");
modelAndView.addObject("typelist", contentPropertyDAO.getType() );
modelAndView.addObject("property", contentPropertyDAO.get(type,0) );
return modelAndView;
}
Hope it helps in constructing your code.
If you have url with path variables, example www.myexampl.com/item/12/update where 12 is the id and create is the variable you want to use for specifying your execution for instance in using a single form to do an update and create, you do this in your controller.
#PostMapping(value = "/item/{id}/{method}")
public String getForm(#PathVariable("id") String itemId ,
#PathVariable("method") String methodCall , Model model){
if(methodCall.equals("create")){
//logic
}
if(methodCall.equals("update")){
//logic
}
return "path to your form";
}
#PathVariable used to fetch the value from URL
for example: To get some question
www.stackoverflow.com/questions/19803731
Here some question id is passed as a parameter in URL
Now to fetch this value in controller all you have to do is just to pass #PathVariable in the method parameter
#RequestMapping(value = " /questions/{questionId}", method=RequestMethod.GET)
public String getQuestion(#PathVariable String questionId){
//return question details
}
Annotation which indicates that a method parameter should be bound to a URI template variable. Supported for RequestMapping annotated handler methods.
#RequestMapping(value = "/download/{documentId}", method = RequestMethod.GET)
public ModelAndView download(#PathVariable int documentId) {
ModelAndView mav = new ModelAndView();
Document document = documentService.fileDownload(documentId);
mav.addObject("downloadDocument", document);
mav.setViewName("download");
return mav;
}
Let us assume you hit a url as www.example.com/test/111 .
Now you have to retrieve value 111 (which is dynamic) to your controller method .At time you ll be using #PathVariable as follows :
#RequestMapping(value = " /test/{testvalue}", method=RequestMethod.GET)
public void test(#PathVariable String testvalue){
//you can use test value here
}
SO the variable value is retrieved from the url
It is one of the annotation used to map/handle dynamic URIs. You can even specify a regular expression for URI dynamic parameter to accept only specific type of input.
For example, if the URL to retrieve a book using a unique number would be:
URL:http://localhost:8080/book/9783827319333
The number denoted at the last of the URL can be fetched using #PathVariable as shown:
#RequestMapping(value="/book/{ISBN}", method= RequestMethod.GET)
public String showBookDetails(#PathVariable("ISBN") String id,
Model model){
model.addAttribute("ISBN", id);
return "bookDetails";
}
In short it is just another was to extract data from HTTP requests in Spring.
have a look at the below code snippet.
#RequestMapping(value = "edit.htm", method = RequestMethod.GET)
public ModelAndView edit(#RequestParam("id") String id) throws Exception {
ModelMap modelMap = new ModelMap();
modelMap.addAttribute("user", userinfoDao.findById(id));
return new ModelAndView("edit", modelMap);
}
If you want the complete project to see how it works then download it from below link:-
UserInfo Project on GitLab

How to exclude url mappings from #RequestMapping in Spring?

I've a request mapping that handles any string after the context e.g. www.example.com/anystring
I'm handling it as follows:
#RequestMapping(value="/{str}", method = RequestMethod.GET)
public String getApp(#PathVariable("str") String anyString, ModelMap model) {
//Do something
}
The problem is I've 2-3 URLs in my app where the URL is as follows: www.example.com/about, www.example.com/contact etc.
I wrote Request Mappings for them as follows:
#RequestMapping("/about")
public String getAboutPage() {
return "about";
}
But obviously, since I've already declared that any string should be handled by the getApp(), the getAboutPage() never gets executed.
How can I exclude /about, /contact etc from getApp() mapping.
We can obviously add another keyword to the URL string, but that's not possible in my app use case.
Kindly help. :(
EDIT:
Should I just handle /about, /contact inside getApp() like:
#RequestMapping(value="/{str}", method = RequestMethod.GET)
public String getApp(#PathVariable("str") String anyString, ModelMap model) {
if(anyString.equals("about")){
//do about related stuff
}
if(anyString.equals("contact")){
//do contact related stuff
}
//Do something
}
Is there a better way?
Specifying the HTTP request method in the "catch-all" mapping is probably making the path matcher consider it to be more specific than the absolute path mappings.
Specify the request method on the absolute paths, and the mapping comparator should order the absolute matches before the one containing the path variable.
eg.
#RequestMapping("/about", method = RequestMethod.GET)
Alternatively, you could remove the method specification on the catch-all:
#RequestMapping("/{str}")
It is entirely dependent upon your url structure and whether or not any of those paths will accept different http request methods.

RequestMapping with multiple values with pathvariable - Spring 3.0

#RequestMapping(value = {"/userDetails", "/userDetails/edit/{id}"}, method = RequestMethod.GET)
public String userDetails(Map Model,****) {
//what goes here?
}
What will be my arguments to the userDetails method? And how do I differentiate /userDetails and /userDetails/edit/9 within the method?
Ideally we can get pathvariable by using annotation #PathVariable in method argument but here you have used array of url {"/userDetails", "/userDetails/edit/{id}"} so this will give error while supply request like localhost:8080/domain_name/userDetails , in this case no id will be supplied to #PathVariable.
So you can get the difference (which request is comming through) by using argument HttpServletRequest request in method and use this request object as below -
String uri = request.getRequestURI();
Code is like this -
#RequestMapping(value = {"/userDetails", "/userDetails/edit/{id}"}, method=RequestMethod.GET)
public String userDetails(Map Model,HttpServletRequest request) {
String uri = request.getRequestURI();
//put the condition based on uri
}

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