我有一个Spring Boot应用程序,其中REST API映射在/api
上。我需要在/
上定义其他servlet。我希望所有匹配/api
的请求都由REST API处理,而其他所有请求都由servlet处理。如何做到这一点?
最初的回答:
您可以使用Spring Boot中的ServletRegistrationBean来注册您的servlet,并将其映射到/
上。然后,您可以使用RequestMapping和PathVariable注释来指定哪些请求应该由REST API处理。
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@RestController
@RequestMapping("/api")
public class ApiController {
@GetMapping
public String get() {
return "api";
}
}
@Bean
public ServletRegistrationBean customServletBean() {
return new ServletRegistrationBean<>(new HttpServlet() {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.getWriter().println("custom");
}
}, "/*");
}
}
在上面的代码中,我想要像这样的东西:
最初的回答:
curl http://localhost:8080/api/
> api⏎
curl http://localhost:8080/custom/
> custom
我尝试使用过滤器来重定向请求,但所有请求都会进入自定义servlet: "最初的回答"
我尝试使用过滤器来重定向请求,但所有请求都会进入自定义servlet:
@Bean
public FilterRegistrationBean apiResolverFilter() {
final FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter((req, response, chain) -> {
HttpServletRequest request = (HttpServletRequest) req;
String path = request.getRequestURI().substring(request.getContextPath().length());
if (path.startsWith("/api/")) {
request.getRequestDispatcher(path).forward(request, response);
} else {
chain.doFilter(request, response);
}
});
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
这个项目可以在Github上找到:https://github.com/mariuszs/nestedweb,原始回答的意思是这个链接指向最初的答案。
DispatcherServlet
已经映射到/
,注册另一个将会破坏DispatcherServlet
。为什么它需要是一个 servlet,而不是一个普通的控制器?你想要实现什么? - M. DeinumDispatcherServlet
是不可能的。您可以尝试使用ServletWrappingController
将其放置在DispatcherServlet
之后。 - M. Deinum