Spring mvc 3.1 not able to resolve URI templates - spring-mvc

I have a controller class configured with a URI template pattern. However when I redirect to this controller from another controller class it is not able to find this handler method.
I see an error in the logs which says "RequestMappingHandlerMapping - Did not find handler method for /path2/2" and then "No mapping found for HTTP request with URI [/path2/2] in DispatcherServlet.
#Controller
#RequestMapping("/path1")
public class Controller1 {
#RequestMapping (method = MethodRequest.POST)
public String postMethod() {
// some logic
return "redirect:/path2/" + 2;
}
}
#Controller
#RequestMapping("/path2/${id}")
public class Controller2 {
#RequestMapping(method=RequestMethod.GET)
public ModelAndView getMethod(#PathVariable("id") long id) {
return new ModelAndView("some jsp");
}
}
If I change the RequestMapping on Controller2 class to just "/path2/" and redirect to that url, the redirection works fine. Can someone please advise?
I have DispatcherServlet configured in my web.xml and an InternalResourceViewResolver in my servlet context file.
Thanks in advance!!

The syntax is
#RequestMapping("/path2/{id}")
not
#RequestMapping("/path2/${id}")

Related

How to make a method forbidden to direct request but allowed for server requests on Spring MVC?

What I basically want to know is this:
Suppose I have a method annotated with #RequestMapping and the value "/test/ajax". Can I make that specific method accessible only to internal calls but not to the client? If I run an ajax request on that url from within the server it should work normally, but if I run it directly from the browser it should return a 403.
Is that in any way possible?
add the spring annotation #CrossOrigin on controller layer for example
also, follow the given link https://spring.io/blog/2015/06/08/cors-support-in-spring-framework
#CrossOrigin
#RestController
#RequestMapping("/account")
public class AccountController {
#GetMapping("/{id}")
public Account retrieve(#PathVariable Long id) {
// ...
}
#DeleteMapping("/{id}")
public void remove(#PathVariable Long id) {
// ...
}
}
If you allow only a method pass like this
#RestController
#RequestMapping("/account")
public class AccountController {
#CrossOrigin
#GetMapping("/{id}")
public Account retrieve(#PathVariable Long id) {
// ...
}
#DeleteMapping("/{id}")
public void remove(#PathVariable Long id) {
// ...
}
}

Combining POST and GET in SpringMvc

For a user registration form (registration.html) I created a view controller through:
#Configuration
#EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(final ViewControllerRegistry registry) {
super.addViewControllers(registry);
registry.addViewController("/user/registration").setViewName("registration");
}
This works fine, and if I go to /user/registration (i.e. GET), I can see the registration form.
However if I now want to create a controller for POST requests at the same uri through:
#Controller
public class RegistrationController {
#RequestMapping(value = "/user/registration", method = RequestMethod.POST)
#ResponseBody
public GenericResponse registerUserAccount(#Valid final UserDto accountDto, final HttpServletRequest request) {
// some code
}
}
I get an error message at the /user/registration uri saying:
Request method 'GET' not supported
So it seems that my post controller is somehow overriding the GET controller which was working before. Why is that? Is it possible to make the two work together or do I have to write my own GET controller in the same way as my post controller?

Route all Web API requests to one controller method

Is it possible to customize ASP.NET Web API's routing mechanism to route all requests to the API to one controller method?
If a request comes in to
www.mysite.com/api/products/
or
www.mysite.com/api/otherResource/7
All would be routed to my SuperDuperController's Get() method?
I ran into a case where I needed to do this. (Web API 2)
I first looked into creating custom IHttpControllerSelector and IHttpActionSelectors. However, that was a bit of a murky way around. So I finally settled on this dead simple implementation. All you have to do is setup a wildcard route. Example:
public class SuperDuperController : ApiController
{
[Route("api/{*url}")]
public HttpResponseMessage Get()
{
// url information
Request.RequestUri
// route values, including "url"
Request.GetRouteData().Values
}
}
Any GET request that starts with "api/" will get routed to the above method. That includes the above mentioned URLs in your question. You will have to dig out information from the Request or context objects yourself since this circumvents automatic route value and model parsing.
The good thing about this is you can still use other controllers as well (as long as their routes don't start with "api/").
I don't konw why you would want to do this and I certainly wouldn't recommend routing everything through one controller, however you could achieve this as follows. Assuming you are only ever going to have a resource with an optional id in your calls, add this to your WebApiConfig:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{resource}/{id}",
defaults: new { controller = "SuperDuper", id = RouteParameter.Optional }
);
}
}
Then define your controller method as follows:
public class SuperDuperController : ApiController
{
public IHttpActionResult Get(string resource, int? id = null)
{
return Ok();
}
}
You would need to decide on an appropriate IHttpActionResult to return for each different type of resource.
Alternatively using Attribute Routing, ensure that config.MapHttpAttributeRoutes() is present in your WebApiConfig and add the following attributes to your controller method:
[RoutePrefix("api")]
public class SuperDuperController : ApiController
{
[Route("{resource}/{id?}")]
public IHttpActionResult Get(string resource, int? id = null)
{
return Ok();
}
}

Configure multiple controllers in Spring MVC, and call one controller's method from another controller

I am trying to configure multiple controller in my application and also trying to redirect from one controller to other.
Error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'nc' bean method.
EDIT :
First Controller
#Controller
#RequestMapping(value = "/nc")
public class StockController {
#RequestMapping(value = "/testMap", method = RequestMethod.GET)
public String redirectToStockList(#RequestParam(value = "testInput") String testInput) {
System.out.println("In StockController..!!");
return "SampleTamplate";
}
}
Second Controller
#Controller
public class WelcomeController {
#Autowired
private UsersServiceImpl serviceImpl;
private String redirectedURL;
private static final Logger logger = LoggerFactory
.getLogger(WelcomeController.class);
#RequestMapping(value = { "/", "/login" }, method = RequestMethod.GET)
public String login(#RequestParam(value = "username") String username) {
logger.debug("In login() method.");
System.out.println("In WelcomeController..!!");
return "Login";
}
}
jsp:
First Form:
<form action="testMap" method="post">
<input type="text" class="form-control" name="testInput"/>
</form>
Second Form:
<form action="login" method="post">
<input type="text" class="form-control" name="username"/>
</form>
When I submit both forms one by one, control goes to 'WelcomeController' every time. And for first form, It gives 'resources not found' error that's OK because there is no mapping present as "/testMap" in welcome controller.
So what I want is, to call specific controller on my form submission and also call one controller's method from another controller.
Any help would be appreciated.
I will try to answer this question in both Grails and Spring way as this is the best time to introduce Grails here.
In spring when call is leaving from controller then RequestDispatcher actually helps to catch the call or to check the exact view resolver. Now, as you want to transfer call to another controller here sping provides API (http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#mvc-redirecting) Inshort you have to use view name like "forward:controllerName" like
#RequestMapping({"/someurl"})
public String execute(Model model) {
if (someCondition) {
return "forward:/someUrlA";
} else {
return "forward:/someUrlB";
}
In grails there is forward method you can find in controller API which does things for you (http://grails.github.io/grails-doc/2.0.4/api/org/codehaus/groovy/grails/plugins/web/api/ControllersApi.html). It actually passes the same session to next requested controller.
Request you to please try to use it. Hope this help.
In the below example the LoginController redirects to the /menu URL if there are validation errors upon submitting a login form by calling the menuMapping() method that resides within the MenuController class.
(NOTE: I have included the use of the BindingResult class and a hypothetical form as this would be a valid reason for wanting to redirect to another controller. However, below solution would still work as well without the BindingResult and if statement without the use of a form).
#Controller
public class LoginController {
MenuController menuController;
#RequestMapping(value = "/login")
public String loginMapping(BindingResult result){
if(result.hasErrors) {
return "login";
}
else {
return menuController.menuMapping();
}
}
With your MenuController in another class like so:
#Controller
public class MenuController {
#RequestMapping(value = "/menu")
public String menuMapping(){
return "menu";
}
}
(EDIT: if you wanted to apply the redirect and the controller methods were within the same class then the loginMapping return statement would simply be return menuMapping(); rather than return menuController.menuMapping();

Request mapping for CSS

I have controller that should manage all requests on server:
#RequestMapping(value = "/**", produces = {"text/plain", "application/*"})
#Controller
public class HomeController {
...
}
Also I have mapping for resources in xml:
<mvc:resources location="/resources/" mapping="/assets/**"/>
Homecontroller intercept all requests to server (include to /assets/** mapping). But when client requests CCS files server returns 406 error (and Homecontroller method didn't called):
The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers.
Is there any chance to fix order for Spring resource handler or fix response for CSS files at all so I could manually return it from server?
Thanks!
I just had the same problem. It causes bad mapping configuration. In your case you should use
#RequestMapping(value = "/", produces = {"text/plain", "application/*"})
#Controller
public class HomeController {
...
}
insead of
#RequestMapping(value = "/**", produces = {"text/plain", "application/*"})
#Controller
public class HomeController {
...
}
In my case, problem appears when i wrote
#RequestMapping(name="/method", method=RequestMethod.GET)
public String myMethod(Model model){
...
}
instead of
#RequestMapping(value="/method", method=RequestMethod.GET)
public String myMethod(Model model){
...
}
The problem is the same in all cases - remapping all request to your method/controller so that css (js, or whatever) static files are redirected to your code.

Resources