I am working on a project using hibernate and Spring MVC architecture.
My problem is that I am using (*.htm) url pattern in my web application , in this case when I sent a product's id to controller for editing, the product's id is shown in url for eg.
"localhost:8080/MyApp/editProduct.htm?productId=03".
But I don't want this . I just want
"localhost:8080/MyApp/editProduct.htm?productId" or "localhost:8080/MyApp/editProduct.htm/productId/03"
and I am unable to use #PathVariable Annotation in my controller because of my url pattern(*.htm) and using of #PathVariable Annotation the JSP page never load properly.
Any Suggestions . Thanks in Advance.
Controller:-
#RequestMapping(value = "/{sId}/deleteState.htm")
public ModelAndView deleteState(#PathVariable("sId") int sId ){
ModelAndView mav = new ModelAndView();
try{
stateDAO.deleteById(sId);
mav.addAllObjects(prepapareModel());
mav.addObject("msg", "State Deleted Succesdfully");
mav.setViewName("admin/viewState");
return mav;
}catch(Exception e){
e.printStackTrace();
mav.addAllObjects(prepapareModel());
mav.addObject("err", "Failed to Delete State");
mav.setViewName("admin/viewState");
return mav;
}
}
public Map prepapareModel(){
Map map = new HashMap();
map.put("states", stateDAO.findAll());
return map;
}
Url after deleting the State from database:-
http://localhost:8080/PujaInBox/10/deleteState.htm
I think the Id of State is creating the problem . 10 is Id of state.
If you want to make use of #PathVariable annoation, then URL should be
/MyApp/productId/03/editProduct.htm - ending with your extension and your controller mapping should be like this
#RequestMapping(value="/productId/{id}/editProduct")
public String editProduct(#PathVariable String id, Model model) {
}
One more change to note here is that I mentioned a relative URL instead of absolute URL like localhost:8080/MyApp/productId/03/editProduct.htm including host name and port. This won't work when you deploy your application in an actual server because localhost always refers to your current machine but your application is deployed on some other host.
Hope that makes sense :)
Change servlet default url pattern to:
<servlet-mapping>
<servlet-name>servlet_name</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
But in this situation better option is to manage your #PathVariables in the middle part of URL, like:
/myapp/product/{productId}/edit.html
I am doing an assignment in a class.
I am guessing the first step is to use wildcard (*) to map your URL. In your pages, you can use whatever the URL you prefer.
Then you can invoke the method getPathInfo() in your servlet.
String action = request.getPathInfo();
Or you can call getHeader("referer") to get your URL then manipulate your string to get the information you need.
Finally, you can put the string in your if-else or switch statement.
All you have to do is create a form in your html page with method=post
<form method="post">
Then create fields inside this form and if you don't have any fields that should be displayed used input with type hidden.
<input type="hidden" name="parametername" id="parameterid" value="parametervalue">
This will do the trick, it won't show any parameter value in the URL and you can access the values as you already do.
Hope this helps....
Related
Here is some code:
1.
#GetMapping(path = "/register", produces = MediaType.TEXT_HTML_VALUE)
public String register(#RequestParam("name") String name,
RedirectAttributes redirectAttributes) {
// call to service
redirectAttributes.addAttribute("name", name);
return "redirect:/success";
}
This endpoint gets hit first and registers the user with provided name and redirects to the success page. It also supplies the user name.
2.
#GetMapping(value = "/success", produces = MediaType.TEXT_HTML_VALUE)
public String success(#ModelAttribute("name") String name, Model model) {
model.addAttribute("name", name);
return "success";
}
This endpoint changes the path in browser URL tab to /success and displays success.html template. It also sets the username in model so that on we can show on UI that ${name} registered successfully.
success.html is a template in /templates folder, which we want to show once this operation is over on /success page.
Everything works as expected. The problem? name of the use shows up in URL on /success page.
So after registration, while we expect the URL to be just /success, it actually is /success?name=John. It is possible to hide the request parameter part? Or to send the data in body somehow rather than request parameter.
Thanks in advance, let me know if any other detail is required.
Sure. It can be done for example by using redirectAttributes.addFlashAttribute("name", name) instead of redirectAttributes.addAttribute("name", name) in the first controller.
You can get more info here.
i would like to redirect a request something like this
localhost:8080 /firstSpringProject/{uniqueusername}
to a specific controller named 'profile':
#RequestMapping(value="/profile")
public String profiles(Model model){
based on the uniqueusername i would like to render a profile page
return "profile";
}
I am using spring mvc; how can I resolve this situation is there any other way to do this?
Spring documentation says on redirect view:
Note that URI template variables from the present request are
automatically made available when expanding a redirect URL and do not
need to be added explicitly neither through Model nor
RedirectAttributes. For example:
#RequestMapping(value = "/files/{path}", method = RequestMethod.POST)
public String upload(...) {
// ...
return "redirect:files/{path}";
}
Keep in mind that version lower than 3.1.4 are affected by a memory leak due to caching redirect views.
If you are using Spring 3.1.3 or lower and you are doing this
return "redirect : profile?username="+username;
you will see OutOfMemoryError sometime.
I think you may use spring path variable here. You have to create a controller method that will take username as per your URL requirement and will redirect to profile method with username parameter.
#RequestMapping(value="/{username}")
public String getUserName(Model model,#PathVariable("username") String username){
//process username here and then redirect to ur profile method
return "redirect : profile?username="+username;
}
#RequestMapping(value="/profile")
public String profiles(Model model,String username){
//have a username and render a profile page
return "profile";
}
Thank you
I am unable to get the ModelAttribute for second request.
My first request is initForm() method I prepared Command object and able to display the command in jsp.
Through initForm() I am populating command and that command I want in editForm when I will do ajax call.
Here is my spring form
<form:form method="POST" action="addstudentdetails.htm" commandName="command">
Ignore what is inside this
Name: Shoaib Age:23 edit
</form:form>
My ajax request:
function editStudentDetails(studentId,index){
$.ajax(
{url:"editstudentdetails.htm",
method:"GET",
data:{"action":"edit","id":studentId,"index":index},
success: function(data) {
jQuery("#studentDetailsDiv").html(data)
}
}
)
}
In editStudentDetails() method I have method ajax call to go editForm() of the controller.
Here is my controller:
#Controller
public class StudentDetailsController {
#Autowired
private StudentDetailsDAO studentDetailsDAO;
#RequestMapping(value="/studentdetails.htm",method = RequestMethod.GET)
public String initForm(HttpServletRequest request,ModelMap map){
String action=request.getParameter("action");
StudentDetailsCommand command=new StudentDetailsCommand();
System.out.println("in controller"+action);
command.setStudents(studentDetailsDAO.findAll());
map.addAttribute("command", command);
return "studentdetails";
}
#RequestMapping(value="/editstudentdetails.htm",method = RequestMethod.GET)
public String editForm(ModelMap map,HttpServletRequest request){
map.addObject("index", request.getParameter("index"));
StudentDetailsCommand command=(StudentDetailsCommand)map.get("command");
System.out.println(command);
System.out.println(command.getStudents());//NullPointerException here.
map.addObject("command", command);
return "studentdetails";
}
}
Even tried #ModelAttribute("studentDetailsCommand") but didn't worked.
I am new to Spring 3.0 and I followed all solutions which are given here but nothing worked.Can anyone help me out please?
Model attributes only exist during the life cycle of one HttpServletRequest. Consider reading my answer here.
In your initForm method, you do the following
map.addAttribute("command", command);
this add an attribute named command to the model attributes. This attribute will eventually find its way into the HttpServletRequest attributes and be available to your JSP. In here
<form:form [...] modelAttribute="studentDetailsCommand" commandName="command">
first of all, modelAttribute and commandName have the same purpose, ie. to find an attribute in the model. If you remove commandName you will get an Exception because there is no model attribute named studentDetailsCommand. Here your commandName's value is overwriting your modelAttribute's value.
When the Servlet container is finished rendering your JSP, the rendered content is sent as the body of the HTTP response. At this point, the request has been handled and the HttpServletRequest and the model attributes are garbage collected.
When you send your new request through AJAX, there is no longer any model attribute named studentDetailsCommand (there actually never was).
Consider using Flash Attributes.
Related:
How to read flash attributes after redirection in Spring MVC 3.1?
Spring RedirectAttributes: addAttribute vs addFlashAttribute
Use of getFlashAttributes() in Spring's RedirectAttributes
What's the difference between localhost/user/user123, localhost/user?user=user123 and localhost/?user=user123?
How to get the parameter user123 from a URL localhost/user/user123 in servlet?
Thanks in advance
You can parse from the getPathInfo() of HttpServletRequest Object.
sample code
String urlPath = request.getPathInfo();
System.out.println("" + urlPath.substring(urlPath.lastIndexOf("/"), urlPath.length()- 1));
localhost/user/user123 looks like a RESTful way to identify a resource.
The two others aren't, I think.
These all are accessible from Servlet API. Check HttpServletRequest, you can access all information from there.
The actual values may differ how your webapp was deployed, but usually
localhost is the Context Path
the String after that is the Servlet PAth
the parameters after the ? is the Query String - you have to parse it, if you want to use
Generally you pass parameters like
/localhost/Servlet?parameter1=one
or for a JSP
/localhost/mypage.jsp?parameter1=one
In a servlet you can access the parameters by using the request object. So generally like this:
String parameter1 = request.getParameter("parameter1");
Here is some detail on getParameter for HttpServletRequest
Hope this helps.
localhost/user/user123 - this url will be handled by pattern /user/user123
localhost/user?user=user123 - this url will be handled by pattern /user, with user parameter set to user123 (for GET request)
localhost/?user=user123 - this url will be handled by pattern / with user parameter set to user123 (again, for GET)
I don't know how to retrieve user123 from url localhost/user/user123 with pure servlets, but it's pretty easy with web MVC frameworks. Spring example:
#Controller
#RequestMapping("/user")
public class Controller {
#RequestMapping(value = "/{user}")
public String getUser((#PathVariable String user) {
//here variable "user" is available and set to "user123" in your case
}
}
I want to use a normal spring mvc controler and request mapping using path variables.
I do not want to forward or redirect, just change the string that user sees.
#RequestMapping(value = "/Foo/{id}/*", method = RequestMethod.GET)
public ModelAndView getFoo(#PathVariable final String friendlyUrl) {
//how can I rewite the url that user sees ?
}
(the same behaviour as when you change the title of an existing question on stackoverflow)
If you watch the traffic in wireshark, firebug or something you see, that stackoverflow sends a HTTP 301 Moved Permanently to the final URL.
You could do the same.
For this you need the HttpServletResponse, you can add it to the method signature to get it injected.
Set the permanent redirect:
String rightUrl = urlCompleter.complete(friendlyUrl);
response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
response.setHeader("Location", rightUrl);
Where you need to implement urlCompleter on your own, eg. look in the database table of entries and locate the right url component.