提问者:小点点

Spring DispatchServlet在Jetty中找不到资源


我看到很多人都有类似的问题,但没有答案适合我。我正在做的是尝试以零配置将Jetty嵌入Spring 4。我在下面放了一些代码,以便更好地描述我的问题:

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;
}
    ...
}
@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;
    }
}
@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";
    }
}

最后,服务器启动后,我得到404错误与以下消息,同时尝试访问localhost:8080/login

警告:没有找到HTTP请求的映射,URI[/WEB-INF/jsp/view/pub/login. jsp]在名为'Servlet Dispatcher'的DispatcherServlet中

我很确定资源“login. jsp”位于包中的文件夹“/webapp/WEB-INF/jsp/view/pub”下。但是为什么它一直说找不到它?!

奇怪的限制,我不能在8小时内回答自己的问题。

通过跟踪Spring的源代码,我最终得到了我的页面显示。原因是我将Jetty ServletContextHandler的ResourceBase设置为“webapp”,并在其下创建了“WEB-INF”子文件夹,“WEB-INF/jsp/view/…”下的所有资源也是如此。但是文件夹WEB-INF是ResourceHttpRequest estHandler看不到的,因为我们可以看到那里的代码:

protected boolean isInvalidPath(String path) {
    return (path.contains("WEB-INF") || path.contains("META-INF") || StringUtils.cleanPath(path).startsWith(".."));
}

因此,解决方案是将资源库更改为“webapp/WEB-INF”,并将InternalResourceViewResolver前缀更改为“/jsp/view”。不过它确实有效!

现在我的问题是,ResourceHttpRequest estHandler已知用于直接限制资源访问,servlet不应该使用它,为什么我的无配置版本加载它?但不是XML-config版本?XML-config是否通过传递此限制或我缺少的东西使用任何其他处理程序?感谢任何人转发。


共1个答案

匿名用户

你需要告诉Spring你已经注释了你的bean。这通常是在注释驱动的XML中完成的。但是我相信你必须在@Configuration元素中使用@AnnotationDrivenConfigalon,这样你的bean才能自动装配。

编辑:正如OP提到的@AnnotationDrivenConfig已弃用。你能试试https://stackoverflow.com/a/8076045/2231632吗?