Spring MVC RequestMapping Post method - java

few days ago I passed SpringMVC level evaluation test on my company, and I found that I don't have enough knowledge to answer one question. But I'm wondering what is the correct answer??? So it will be awesome if You help me!
You have the following PersonController class and correctly defined web.xml and Spring context
The following request has been submitted using POST method:
http://xxxx/person/add?name=John
Please, fill the placeholders so that submitted request would result into person object being saved successfully and method addPerson would be called only in case request doesn't contain "id" parameter. Values in placeholders should not contain spaces.

PLACEHOLDER1 :
#Controller
#RequestMapping("person")
PLACEHOLDER2 :
#RequestMapping(value = "add", method = RequestMethod.POST)
And you can read document from Spring official site.
Edited:
About id, if you request url is like http://xxxx/person/add/12345?name=John, then you can do it like this:
#RequestMapping(value = "add/{id}", method = RequestMethod.POST)
public String addPerson(#RequestParam("name") String name, #PathVariable("id") String id)
here you can get 12345 as id.

Related

How to get URI value coming from HTML to Variable in Spring (There are multiple Links associated with corresponding method)

I have multiple links in my HTML, which are referring to URI in Controller Class,
How can I get this URI in some variable which can be used further, at last, I want to store these URI in DB.
HTML Code :
<td>Win Report</td>
<td>Win Report</td>
Spring Controller Class :
#RequestMapping(value = "/ui/report/win", method = RequestMethod.GET)
public String winReport() {
return "win_report";
}
#RequestMapping(value = "/ui/report/niw", method = RequestMethod.GET)
public String niwReport() {
return "niw_report";
}
You can use the below solution to retrieve the page Url as well as avoid using repetitive method calls.
You can use a Spring Boot HandlerInterceptor, here's a brief description of the same :
Handler interceptors are used when you want to apply specific
functionality to certain or all requests.
Handler Interceptors should implement the interface HandlerInterceptor. HandlerInterceptor can be used to avoid repetitive handler code.
We can use HandlerInterceptor for different purposes like authorization checks, locale checks, logging, creating common application parameters etc.
HandlerInterceptor works similar to the servlet filter. But in some cases filters are more powerful than HandlerInterceptor.
In Spring-MVC the HandlerInterceptor is configured in spring application context xml file or by Java configuration.
HandlerInterceptor has three methods.
preHandle( ) : It is executed before actual handler is executed.
postHandle( ) : It is executed after handler is executed.
afterCompletion( ) : It is executed after the complete request is finished.
For more details, you can use an example from the below link
https://www.tuturself.com/posts/view?menuId=3&postId=1071
You can get the entire sample project which can help you with the setup at
https://github.com/ninja-panda
To get the request url you can do the following:
#RequestMapping(value = "/ui/report/win", method = RequestMethod.GET)
public String winReport(HttpServletRequest request){
String request = request.getRequestURI();
// do somehting here
return "win_report"
}
Spring will automatically inject the HttpServletRequest.
Update:
If your want get the urls for all of your methods in your controller, you can go with RequestMappingHandlerMapping:
private final RequestMappingHandlerMapping handlerMapping;
#Autowired
public YourController(RequestMappingHandlerMapping handlerMapping) {
this.handlerMapping = handlerMapping;
}
With handlerMapping.getHandlerMethods(), you can access all mappings decleared in your controller. With reflection and getMappingAnnotation, you can then read the value of each RequestMapping annotation.
You can try the getServletPath() like following:
#RequestMapping(value = "/ui/report/win", method = RequestMethod.GET)
public String winReport(HttpServletRequest request){
String mapping = request.getServletPath();
// do somehting here
System.out.println(mapping); // Will print /ui/report/win
return "win_report"
}

How to return a variable in every page from my Spring MVC application from the same controller method?

I want to return a model from my Spring MVC controller, which will be visible to all pages in my application.
So, I need a variable which return some user details.
This is my code:
#RequestMapping(value = "/*", method = RequestMethod.GET)
public void status(Model model){
Authentication auth = SecurityContextHolder.getContext()
.getAuthentication();
String username = auth.getName();
Manager mgr = managerService.findOne(username);
model.addAttribute("buget", mgr.getTeam().getTeamBuget());
}
And in my jsp page, i write something like this:
<li> <c:out value="${buget}" /> <span class="glyphicon glyphicon-euro"></span></li>
I want to be able to print the ${buget} in every page from my app.
So, my method don't work, nothing is appear in my pages and the biggest problem
for me is that I don't get any exceptions or errors which could help me. Who can help me with some advices?
I'm not entirely sure what it is that you're trying to do. Do you mean that you want buget to be part of every page that you hit? If so, you have to insert it into the model. Based on your code, I'm assuming that you have the mistaken impression that status is going to be called regardless of whatever page you hit. Spring will resolve to the most-specific handler and so if you have another handler method in another controller that is more specific, Spring will use that. But even if the one you have was called, how would Spring know that it has to call the most-specific one next? So how would you add page-dependent model attributes to the model?
If you want buget to be part of every response, you can use #ControllerAdvice (see here for a blog post with more details):
#ControllerAdvice
public class BugetControllerAdvice {
#ModelAttribute
public void addBugetToModel(Model model) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String username = auth.getName();
Manager mgr = managerService.findOne(username);
model.addAttribute("buget", mgr.getTeam().getTeamBuget());
}
}
Spring will now call this method before every handler-method in every controller. You can also take a look at the Spring Reference for more information.

post json to spring mvc controller

Controller signature (I have tried as requestbody as well) :
#RequestMapping(value = "/Lame", method = RequestMethod.POST)
public
#ResponseBody
boolean getLame(#RequestParam String strToMatchA, #RequestParam String strToMatchB) {}
And this as my json :
{
"strToMatchA": "EN",
"strToMatchB": "lon"
}
Not working, I receive the error :
org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'strToMatchA' is not present
Removing this first parameter from method signature then makes it work (the method gets called correctly), what should I be doing ?
When I change method parameters to be annotated with #RequestBody I get the following error :
java.io.IOException: Stream closed
Your json is fine but not the controller signature.
Create a class with setters matching the json.
Use it as argument instead of your strings.
Annotate it with requestbody. It should work.

In Spring MVC, how can I map nested URLs such as /settings/, /settings/users/, and /settings/users/delete?

In Spring 3 MVC, I have a controller that I call SettingsController, and it has methods such as displayUsers() for displaying a list of users, saveUser(), and deleteUser(). SettingsContoller also controls roles and other things.
I'd love to be able to use URL routing such that /settings/users would call displayUsers(), /settings/users/save would call saveUser(), and /settings/users/delete would call deleteUser().
My code is below, and I'm getting the error message that follows the code. What am I doing wrong? Thanks!
#Controller
#RequestMapping("/settings")
public class SettingsController {
#Transactional
#RequestMapping(value = {"/users/save"}, method = {RequestMethod.POST})
public ModelAndView saveUser(details removed){
//details removed
}
#RequestMapping(value = {"/users/delete"}, method = {RequestMethod.POST})
public ModelAndView deleteUser(details removed){
//details removed
}
#RequestMapping(value = {"/users"}, method = RequestMethod.GET)
public ModelAndView settingsUsers(details removed){
//details removed
}
}
Error:
HTTP ERROR: 500
Could not resolve view with name 'settings/users/delete' in servlet with name 'spring'
RequestURI=/das-portal/srv/settings/users/delete
Caused by:
javax.servlet.ServletException: Could not resolve view with name 'settings/users/delete' in servlet with name 'spring'
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1029)
...
It looks to me like you've set up your controller correctly. As you pointed out, the problem might be in how Spring parses annotations upon start up.
How did you configure Sprint to parse annotations such as #Controller? Do you explicitly set up any sort of HandlerMapping? If you use <context:component-scan>, then it registers a DefaultAnnotationHandlerMapping for you.
The good news is that you can chain multiple handler mapping classes together. The DispatcherServlet will check each one in the order that you specify via the order property of the handler mapping beans (in other words, use the order property to indicate the precedence of your handlers).
So, throw <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/> into your configuration and set its order property as appropriate.
What about using just one method checking mode?
#RequestMapping(value = "/users/{action}", method = RequestMethod.POST)
public String userAction(#PathVariable String action, ...) {
if (mode.equals("save")) {
//your save code here
}
}

Access Model object in a JSP without using the ModelAndView object?

I am using spring mvc with Annotations, see the following snippet
#RequestMapping(value = "/configuration/", method = RequestMethod.GET)
public MyModel viewConfiguration() {
The problem I am having accessing the 'MyModel' class in my JSP.
How can I do this, without using the ModelAndView object?
This shorthand syntax means that MyModel becomes a model attribute named myModel (i.e. class name with the first letter decapitalized).
View name is inferred from the URL.
See also:
15.3.2.3 Supported handler method arguments and return types
15.10.3 The View - RequestToViewNameTranslator
You could set MyModel as a request attribute to be accessed in your JSP. I'm curious, why don't you want to use ModelAndView? After all, it does what you want to do here, which displays the view and provides a container to hold your objects you want to reference in your view.
By the way, if this is an Ajax call, you will need to add #ResponseBody to the API so that your javascript can read the response in the callback function:-
#RequestMapping(value = "/configuration/", method = RequestMethod.GET)
public #ResponseBody MyModel viewConfiguration() {
...
}

Categories

Resources