Mappings in RestController not found - spring

I have a RestController that defines a default path and some endpoints like this:
#RestController
#EnableHypermediaSupport(type = EnableHypermediaSupport.HypermediaType.HAL)
#RequestMapping(path = "/somePath", produces = "application/hal+json")
public class SomeRestController {
#GetMapping (path = "/otherPath")
public String someEndpoint(){
return "hello";
}
...other endpoints...
}
I get a 404 for the mapped endpoints. However, if I delete the default RequestMapping the endpoints suddenly get picked up! I also tried RequestMapping ( path =..., method=RequestMethod.GET) for the endpoints, but same result...
If I delete the #GetMapping from one endpoint, the default path is mapped successfully.
What is going on here? Why do the endpoints don't get mapped if I have the default RequestMapping?

You have to concat both pathes:
localhost:8080/somePath/otherPath
because the mapping on top of the class is for all methods in this controller, and than the method specific path will be added

Related

Reading RequestMapping wildcard in webflux application

I am trying to obtain the wildcard value from a controller's #requestMapping within a Spring boot webflux application:
#Controller
#RequestMapping("/template/**")
public class TemplateController {
#GetMapping
public Mono<String> getTemplate ( ... ) {
String path = ... // obtain the value of ** in the #RequestMapping
return Mono.just(path);
}
}
Everything I have found regarding reading such a value is for an MVC application; those solutions don't work for a webflux application.
How does one access this value within a webflux context? I would prefer an annotation-based approach for reusability, but any solution would do.
You could get the path from ServerHttpRequest that could be obtained from ServerWebExchange passed to the controller method. From ServerHttpRequest you can get access to a structured representation of the full request path
#GetMapping("/endpoint")
public Mono<Void> endpoint(ServerWebExchange serverWebExchange) {
ServerHttpRequest request = serverWebExchange.getRequest();
RequestPath path = request.getPath();
String value = path.value();
return Mono.empty();
}
With this you can play around the methods of RequestPath, maybe it helps

spring boot mapping without slash

I'm having a controller mapping as shown below
#RestController
#RequestMapping("/v1/connector")
public class Controller
and the API mapping as below
#GetMapping("2/auth")
when I hit the URL it's giving me the response as request URL not found.
Can anyone tell why I'm getting this?
#GetMapping is a composed annotation that acts as a shortcut for #RequestMapping(method = RequestMethod. GET).
#RequestMapping maps HTTP requests to handler methods of MVC and REST controllers.
When you use a base path on your controller class, all controllers in that class accept URL paths that start with your given base path. In your case:
#RestController
#RequestMapping("/v1/connector")
public class Controller {
...
}
This means all of the controllers inside this class have the base path of /v1/connector and this means is a constant part of your URL and cant be changed.
So when you declare a #GetMapping("2/auth"), Spring will automatically add a / at the beginning of your path if there was no /. And your path will be http://YOUR-HOST-NAME/v1/connector/2/auth instead of http://YOUR-HOST-NAME/v1/connector2/auth.
See here for more clarification.
So If your application has paths like /v1/connector1, /v1/connector2, /v1/connector3, etc. It means the connector{n} is not constant and you must declare it on each of your controllers' methods separately.
#RestController
#RequestMapping("/v1")
public class Controller {
#GetMapping("/connector2/auth")
...
#GetMapping("/connector3/auth")
...
.
.
.
}

Request Mapping Configuration set globally in spring boot

I have a request mapping in every controller like below, now I want to set this configuration from one place of my applications
Here is my code:
#RestController(value = "AC1004Controller")
#RequestMapping(value = { "api/v1/accounting"},method = RequestMethod.POST ,consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_FORM_URLENCODED_VALUE})
public class AC1004Controller {
}
My target coding is, need to replace the below code from one place of our application
#RequestMapping(value = { "api/v1/accounting"},method = RequestMethod.POST ,consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_FORM_URLENCODED_VALUE})
Generally you map controller's methods with GET, POST, etc ..
so below should be configuration..
Define a property in application.properties
api.endpoint.accounting=/api/v1/accounting
Below controller should mapped with your accounting controller with different-2 methods for post, get to mapped with controller method.
#RestController(value = "AC1004Controller")
#RequestMapping(value = "${api.endpoint.accounting}")
public class AC1004Controller {
#PostMapping(consumes = {MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_FORM_URLENCODED_VALUE})
public ResponseEntity<?> addAccount(#RequestBody Account account) {
}
//for get mapping
#GetMapping
public ResponseEntity<?> getAccount() {
}
}
You need to set spring.mvc.servlet.path property in application.properties file.
Like this:
spring.mvc.servlet.path=/AC1004Controller
You just put any of these configurations on application properties file (yaml or properties).
spring.data.rest.basePath=/api
spring.data.rest.base-path=/api

Tomcat+Spring boot redirect ignoring contextPath

I'am using Spring boot and Tomcat7 to build a vehicle management system.
The base path is localhost:8080/vehicle
My server setting:
server.contextPath=/vehicle
My IndexController:
#RequestMapping("/")
public class IndexController extends BaseController {
#RequestMapping(value = "/", method = RequestMethod.GET)
public String index(Model model) {
return "redirect:/login";
}
}
But when I go straight to get this view, my path is ...../login instead of ..../vehicle/login And so it returns 404 Error.
Also when I tried to use return "redirect:/vehicle/login"; it still goes to ...../login.
So what is wrong with my code. Why the server can't recognize the contextPath.
In application.properties use : server.servlet.context-path=/contextPath.
Example:
server.servlet.context-path=/vehicle
Tomcat Server:
In the webapps folder, the context path(vehicle) must be the same as the folder name(vehicle).

Spring MVC : how to get the mapped URI within a method marked with #RequestMapping

I'm currently working on a Spring MVC application and as I mapped, within the web.xml file, all incoming URL to a single DispatcherServlet, I wanted to know whether it would be possible to retrieve the URI that has been effectively mapped. Here's an example to illustrate my concerns :
import static org.springframework.web.bind.annotation.RequestMethod.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class HomeController {
#RequestMapping(method={GET})
public String processAllRequest(){
return "viewName";
}
}
Since I've defined the URL-MAPPING in the web.xml as being "/*", all incoming requests will end up in my controller class, show above. For instance, both the following requests will be processed by the processAllRequest() method from my controller.
myApplicationContext/home
myApplicationContext/logout
Is it possible, somehow, to retrieve the mapped URI? That is, once I'm inside the processAllRequest(), how could I know if it's been called for .../home or .../logout?
Is it possible to retrieve this kind of info by injecting an HttpServletRequest or another object as argument of the method?
Spring does inject HttpServletRequest if you put it in your handler arguments, so you can do that if you like.
But if you need to distinguish between different URLs, just place them in different handlers:
#Controller
public class HomeController {
#RequestMapping(value="/home", method={GET})
public String processHome(){
return "viewName";
}
#RequestMapping(value="/login", method={GET})
public String processLogin(){
return "viewName";
}
}
The mapping in web.xml forwards all requests to the spring servlet. You can still write as many #Controllers as you like, and play with class-level and method-level #RequestMapping to split the application into logical components.
I might have formulated my question in an ambiguous way but what I was looking for, was rather path variable. So my problem was solved this way :
#Controller
public class HomeController {
#RequestMapping(value="/{uri}", method={GET})
public String processMappedUri(#PathVariable uri){
return uri;
}
}
With this solution whenever I request the following requests, the uri argument from my processMappedUri() method will hold the variable value :
myApplicationContext/home --> uri = home
myApplicationContext/logout --> uri = logout

Resources