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.
Related
From my understanding when Request Method is Get we should not have Request body, we use #RequestParam to read the url parameters. But spring test seems to be allowing it. Below is a sample code.
#Controller
public class SomeController {
#RequestMapping(value = "/abc", method = RequestMethod.GET)
public String greeting(#RequestBody Student student) {
return "Hello "+ student.name;
}
}
This is the test code and jsonString is the string representation of a Student object.
#Test
public void shouldReturnMessage() throws Exception {
this.mockMvc.perform(get("/abc").content(jsonString)).andDo(print()).andExpect(status().isOk());
}
My question here is, should Spring stop allowing #RequestBody with Get request? The above test runs fine and it's able to return me the student name. But when I try to call the same endpoint using curl it throws an error.
Reference : HTTP GET with request body
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) {
// ...
}
}
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?
I'm getting the following exception if I use multi level urls in class like #RequestMapping("/api/v0.1"):
java.lang.IllegalStateException: Ambiguous mapping found. Cannot map 'userController'
bean method getUsers()|to {[/api/v0.1]}: There is already 'userController' bean
method getUser(java.lang.String) mapped.
It's like the method level mappings doesn't get into consideration at all.
But it's ok if I put #RequestMapping("/api") i.e. remove the /v0.1 part.
Here is the configuration stripped up to the minimal case:
#Controller
#RequestMapping("/api/v0.1")
public class UserController {
#RequestMapping(value = "/users")
#ResponseBody
public List<User> getUsers() {
return null;
}
#RequestMapping(value = "/users/{username}")
#ResponseBody
public User getUser(#PathVariable String username) {
return null;
}
}
web.xml
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
servlet-context.xml:
<!-- Configures the #Controller programming model -->
<mvc:annotation-driven />
<!-- Forwards requests to the "/" resource to the "welcome" view -->
<mvc:view-controller path="/" view-name="home"/>
<!-- Handles HTTP GET requests for /assets/** by efficiently serving up static resources in the ${webappRoot}/resources/ directory -->
<mvc:resources mapping="/assets/**" location="/assets/" />
I'm using spring 3.1. I also tried to set alwaysUseFullPath property to true of the RequestMappingHandlerMapping bean but it didn't change the situation.
Very interesting issue - I checked what could be going on, you are right the "v0.1" is really throwing off the org.springframework.util.AntPathMatcher which creates the full URI path by combining the path from the controller and the path from the mapped method. If it sees a "file.extension" kind of a pattern in the Controller, then it totally ignores the path mapping of the method - this is the reason why your #PathVariable was getting ignored.
I am not sure if this is a bug or intended behavior in Spring MVC, temporary fix would be along what you have already mentioned -
1.To remove "v0.1" from the RequestMapping of Controller and make it without extension say v0_1
2.To put this mapping in the mapped method:
#Controller
#RequestMapping("/api")
public class UserController {
#RequestMapping(value = "/v0.1/users")
#ResponseBody
public List<User> getUsers() {
return null;
}
#RequestMapping(value = "/v0.1/users/{username}")
#ResponseBody
public User getUser(#PathVariable String username) {
return null;
}
}
You should use the #RequestMapping(value = "/{version:.*}/users") to include the dot '.' in the path variable
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}")