#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
}
Related
This question already has an answer here:
Post parameter in path or in body
(1 answer)
Closed 2 years ago.
I have an API to be designed, this one require only one parameter then to be inserted into DB.
So POST is the verb, but my doubt is on the parameter that will be passed as query param or path param ?
#RequestMapping(value = "/users-access/{userId}", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseStatus(HttpStatus.NO_CONTENT)
#ApiOperation("Promotes user access")
public boolean promoteUserAccess(#PathVariable String userId)
throws BadRequestException, UnAuthorizedException {
//actions
}
What's the best practices ? thanks !
You should send your data in the request body like below.
#RequestMapping(value = "/users", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseStatus(HttpStatus.NO_CONTENT)
#ApiOperation("Promotes user access")
public boolean promoteUserAccess(#RequestBody Request request)
throws BadRequestException, UnAuthorizedException {
//actions
}
public class Request {
private String userId;
}
If the parameter is meant to refer a resource then use path param.
If the parameter is meant to filter the resource then use query param.
In your case, the userId refers to resource so you should use it as path param.
Generally,query param is used in GET requests to sort/filter the resources. Ex:
GET/users?id=5
I want to pass and Get Json String From Controller.
I want to call controller by passing json String and also want to get json String at Controller.
Is there any way to do this.
I have 2 values in my url parameter :: api=asdf23&&jsonstr={"name":"myname","age":"20"}
How can i get these two parameters at controller
#RequestMapping(value = "/GetJSON", method = RequestMethod.GET, produces = "application/json")
public #ResponseBody String GetJSON(
HttpServletRequest request, HttpServletResponse response,
#RequestParam(value = "api") String apiKey,
#RequestParam(value = "jsonstr") String json)
throws ParseException {
System.out.println("JSON :: "+json);
return json;
}
I would recommend not using URL parameter to pass the whole JSON object, rather use POST method and put JSON in the body. However, if you have reasons to use GET with json as url parameter, take help from this link to encode Http URL properly.
For your case, your JSON object will look like this:
api%3Dasdf23%26jsonstr%3D%7B%22name%22%3A%22myname%22%2C%22age%22%3A%2220%22%7D
Create a pojo having 2 properties name and age
public class Test{
private String name;
private Integer age;
//getter and setters
}
then modify your controller to accept json in requestbody and change the request method to post
#RequestMapping(value = "/GetJSON", method = RequestMethod.POST, produces = "application/json")
public #ResponseBody String GetJSON(
HttpServletRequest request, HttpServletResponse response,
#RequestParam(value = "api") String apiKey,
#RequestBody Testjson testJson)
throws ParseException {
api=asdf23**&&**jsonstr={"name":"myname","age":"20"}
You only need one &
you can also use gson 2.2.2 jar
RequestMapping(value = "/GetJSON", method = RequestMethod.GET)
public #ResponseBody String GetJSON(
HttpServletRequest request, HttpServletResponse response,
#RequestParam(value = "api") String apiKey)
throws ParseException {
Gson gson=new Gson();
Emp emp=new Emp();
String json =gson.tojson(emp);
System.out.println("JSON :: "+json);
return json;
}`
Pass the JSON HTTP Request
using the body as a POST request.
using url encode.
below just for example :
jsonstr={"name":"myname","age":"20"}
url :80/GetJSON?jsonstr=%7B%22name%22%3A%22myname%22%2C%22age%22%3A%2220%22%7D
for more information on URL encoding refer below
Percent-encoding, also known as URL encoding, is a mechanism for
encoding information in a Uniform Resource Identifier (URI) under
certain circumstances. Although it is known as URL encoding it is, in
fact, used more generally within the main Uniform Resource Identifier
(URI) set, which includes both Uniform Resource Locator (URL) and
Uniform Resource Name (URN). As such, it is also used in the
preparation of data of the application/x-www-form-urlencoded media
type, as is often used in the submission of HTML form data in HTTP
requests.
https://en.wikipedia.org/wiki/Percent-encoding
What is the difference between #RequestParam and #PathVariable while handling special characters?
+ was accepted by #RequestParam as space.
In the case of #PathVariable, + was accepted as +.
#PathVariable is to obtain some placeholder from the URI (Spring call it an URI Template)
— see Spring Reference Chapter 16.3.2.2 URI Template Patterns
#RequestParam is to obtain a parameter from the URI as well — see Spring Reference Chapter 16.3.3.3 Binding request parameters to method parameters with #RequestParam
If the URL http://localhost:8080/MyApp/user/1234/invoices?date=12-05-2013 gets the invoices for user 1234 on December 5th, 2013, the controller method would look like:
#RequestMapping(value="/user/{userId}/invoices", method = RequestMethod.GET)
public List<Invoice> listUsersInvoices(
#PathVariable("userId") int user,
#RequestParam(value = "date", required = false) Date dateOrNull) {
...
}
Also, request parameters can be optional, and as of Spring 4.3.3 path variables can be optional as well. Beware though, this might change the URL path hierarchy and introduce request mapping conflicts. For example, would /user/invoices provide the invoices for user null or details about a user with ID "invoices"?
#RequestParam annotation used for accessing the query parameter values from the request. Look at the following request URL:
http://localhost:8080/springmvc/hello/101?param1=10¶m2=20
In the above URL request, the values for param1 and param2 can be accessed as below:
public String getDetails(
#RequestParam(value="param1", required=true) String param1,
#RequestParam(value="param2", required=false) String param2){
...
}
The following are the list of parameters supported by the #RequestParam annotation:
defaultValue – This is the default value as a fallback mechanism if request is not having the value or it is empty.
name – Name of the parameter to bind
required – Whether the parameter is mandatory or not. If it is true, failing to send that parameter will fail.
value – This is an alias for the name attribute
#PathVariable
#PathVariable identifies the pattern that is used in the URI for the incoming request. Let’s look at the below request URL:
http://localhost:8080/springmvc/hello/101?param1=10¶m2=20
The above URL request can be written in your Spring MVC as below:
#RequestMapping("/hello/{id}") public String getDetails(#PathVariable(value="id") String id,
#RequestParam(value="param1", required=true) String param1,
#RequestParam(value="param2", required=false) String param2){
.......
}
The #PathVariable annotation has only one attribute value for binding the request URI template. It is allowed to use the multiple #PathVariable annotation in the single method. But, ensure that no more than one method has the same pattern.
Also there is one more interesting annotation:
#MatrixVariable
http://localhost:8080/spring_3_2/matrixvars/stocks;BT.A=276.70,+10.40,+3.91;AZN=236.00,+103.00,+3.29;SBRY=375.50,+7.60,+2.07
And the Controller method for it
#RequestMapping(value = "/{stocks}", method = RequestMethod.GET)
public String showPortfolioValues(#MatrixVariable Map<String, List<String>> matrixVars, Model model) {
logger.info("Storing {} Values which are: {}", new Object[] { matrixVars.size(), matrixVars });
List<List<String>> outlist = map2List(matrixVars);
model.addAttribute("stocks", outlist);
return "stocks";
}
But you must enable:
<mvc:annotation-driven enableMatrixVariables="true" >
#RequestParam is use for query parameter(static values) like: http://localhost:8080/calculation/pow?base=2&ext=4
#PathVariable is use for dynamic values like : http://localhost:8080/calculation/sqrt/8
#RequestMapping(value="/pow", method=RequestMethod.GET)
public int pow(#RequestParam(value="base") int base1, #RequestParam(value="ext") int ext1){
int pow = (int) Math.pow(base1, ext1);
return pow;
}
#RequestMapping("/sqrt/{num}")
public double sqrt(#PathVariable(value="num") int num1){
double sqrtnum=Math.sqrt(num1);
return sqrtnum;
}
1) #RequestParam is used to extract query parameters
http://localhost:3000/api/group/test?id=4
#GetMapping("/group/test")
public ResponseEntity<?> test(#RequestParam Long id) {
System.out.println("This is test");
return ResponseEntity.ok().body(id);
}
while #PathVariable is used to extract data right from the URI:
http://localhost:3000/api/group/test/4
#GetMapping("/group/test/{id}")
public ResponseEntity<?> test(#PathVariable Long id) {
System.out.println("This is test");
return ResponseEntity.ok().body(id);
}
2) #RequestParam is more useful on a traditional web application where data is mostly passed in the query parameters while #PathVariable is more suitable for RESTful web services where URL contains values.
3) #RequestParam annotation can specify default values if a query parameter is not present or empty by using a defaultValue attribute, provided the required attribute is false:
#RestController
#RequestMapping("/home")
public class IndexController {
#RequestMapping(value = "/name")
String getName(#RequestParam(value = "person", defaultValue = "John") String personName) {
return "Required element of request param";
}
}
it may be that the application/x-www-form-urlencoded midia type convert space to +, and the reciever will decode the data by converting the + to space.check the url for more info.http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1
#PathVariable - must be placed in the endpoint uri and access the query parameter value from the request
#RequestParam - must be passed as method parameter (optional based on the required property)
http://localhost:8080/employee/call/7865467
#RequestMapping(value=“/call/{callId}", method = RequestMethod.GET)
public List<Calls> getAgentCallById(
#PathVariable(“callId") int callId,
#RequestParam(value = “status", required = false) String callStatus) {
}
http://localhost:8080/app/call/7865467?status=Cancelled
#RequestMapping(value=“/call/{callId}", method = RequestMethod.GET)
public List<Calls> getAgentCallById(
#PathVariable(“callId") int callId,
#RequestParam(value = “status", required = true) String callStatus) {
}
Both the annotations behave exactly in same manner.
Only 2 special characters '!' and '#' are accepted by the annotations #PathVariable and #RequestParam.
To check and confirm the behavior I have created a spring boot application that contains only 1 controller.
#RestController
public class Controller
{
#GetMapping("/pvar/{pdata}")
public #ResponseBody String testPathVariable(#PathVariable(name="pdata") String pathdata)
{
return pathdata;
}
#GetMapping("/rpvar")
public #ResponseBody String testRequestParam(#RequestParam("param") String paramdata)
{
return paramdata;
}
}
Hitting following Requests I got the same response:
localhost:7000/pvar/!##$%^&*()_+-=[]{}|;':",./<>?
localhost:7000/rpvar?param=!##$%^&*()_+-=[]{}|;':",./<>?
!# was received as response in both the requests
#RequestParam:We can say it is query param like a key value pair
#PathVariable:-It is came from URI
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);
}
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