I saw a lot people has similar problem but no answer works for me. What I'm doing is trying to embed Jetty with Spring 4 with zero configuration. I put some of my code below for better describe my question:
JettyStarter.class
public class JettyStarter {
...
private static final String CONFIG_LOCATION = "com....config";
private static final String DEFAULT_MAPPING_URL = "/*";
private static final String DEFAULT_CONTEXT_PATH = "/";
...
private ServletContextHandler getServletContextHandler() throws IOException {
WebApplicationContext context = getContext();
ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
contextHandler.setErrorHandler(null);
DispatcherServlet dispatcherServlet = new DispatcherServlet(context);
ServletHolder servletHolder = new ServletHolder("Servlet Dispatcher", dispatcherServlet);
servletHolder.setInitOrder(1);
contextHandler.addServlet(servletHolder, DEFAULT_MAPPING_URL);
contextHandler.addEventListener(new ContextLoaderListener(context));
contextHandler.setResourceBase(new ClassPathResource("webapp").getURI().toString());
contextHandler.setContextPath(DEFAULT_CONTEXT_PATH);
return contextHandler;
}
private void startJetty() throws Exception
{
...
HandlerCollection handlers = new HandlerCollection();
handlers.addHandler(getServletContextHandler());
...
server.setHandler(handlers);
server.start();
server.join();
}
private WebApplicationContext getContext() throws IOException {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setConfigLocation(CONFIG_LOCATION);
...
return context;
}
...
}
WebMvcConfig.class
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com...controllers")
public class WebMvcConfig extends WebMvcConfigurerAdapter{
...
@Bean
public InternalResourceViewResolver getInternalResourceViewResolver()
{
InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
internalResourceViewResolver.setPrefix("/WEB-INF/jsp/view");
internalResourceViewResolver.setSuffix(".jsp");
internalResourceViewResolver.setViewClass(org.springframework.web.servlet.view.JstlView.class);
return internalResourceViewResolver;
}
}
HomeController.class
@Controller
public class HomeController {
@RequestMapping(value = "/login", method = RequestMethod.GET)
public String login(@RequestParam(value="error", required=false) boolean error, ModelMap model)
{
...
return "/pub/login";
}
}
Finally, after the server started, I got 404 error with the following message while trying to access localhost:8080/login
WARNING: No mapping found for HTTP request with URI [/WEB-INF/jsp/view/pub/login.jsp] in DispatcherServlet with name 'Servlet Dispatcher'
I'm pretty sure resource "login.jsp" is under the folder "/webapp/WEB-INF/jsp/view/pub" within the package. But why it keeping saying it can not be found?!
Solution:
Weird restriction that I cannot answer myself question within 8 hours.
By traced in Spring's source code, I eventually got my page display. The reason is I set Jetty ServletContextHandler's ResourceBase as "webapp", and created "WEB-INF" sub folder under it, all resources under "WEB-INF/jsp/view/..." as well. But the folder WEB-INF is unseeable by ResourceHttpRequestHandler as we can see the code there:
protected boolean isInvalidPath(String path) {
return (path.contains("WEB-INF") || path.contains("META-INF") || StringUtils.cleanPath(path).startsWith(".."));
}
So, the solution is change the resource base to "webapp/WEB-INF", and change InternalResourceViewResolver prefix to "/jsp/view" as well. It does work though!
Now my question is, ResourceHttpRequestHandler is known by to be used to restrict directly resource access, a servlet should not use it, why my none-config version load it in? but not for XML-config version? is XML-config using any other handler by pass this restriction or something I'm missing? Appreciate for anybody to forward.
You need to tell Spring that you have annotated your beans. This is usually done in an XML saying annotation-driven. But I believe you'll have to use
@AnnotationDrivenConfig
alon with your @Configuration element so that your beans get autowired.EDIT: As OP mentioned @AnnotationDrivenConfig is deprecated. Can you try https://stackoverflow.com/a/8076045/2231632 ?