本文介绍了Spring DispatchServlet无法在Jetty中找到资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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:

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

最后,服务器启动后,尝试访问localhost:8080/login时出现以下错误404错误

Finally, after the server started, I got 404 error with the following message while trying to access localhost:8080/login

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

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?!

奇怪的限制是我无法在8小时内回答自己的问题.

Weird restriction that I cannot answer myself question within 8 hours.

通过跟踪Spring的源代码,最终使我的页面显示出来.原因是我将Jetty ServletContextHandler的ResourceBase设置为"webapp",并在其下创建了"WEB-INF"子文件夹,所有资源也都位于"WEB-INF/jsp/view/..."下.但是ResourceHttpRequestHandler无法看到WEB-INF文件夹,因为我们可以在其中看到代码:

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

因此,解决方案是将资源库更改为"webapp/WEB-INF",并将InternalResourceViewResolver前缀也更改为"/jsp/view".它确实可以工作!

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!

现在我的问题是,ResourceHttpRequestHandler被用来直接限制资源访问,一个servlet不应该使用它,为什么我的none-config版本会加载它?但不是XML-config版本?通过此限制或我缺少的东西,XML-config是否使用其他任何处理程序?感谢任何人转发.

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.

推荐答案

您需要告诉Spring您已经注释了bean.通常,这是通过XML(注解驱动)完成的.但是我相信您必须在元素中使用@AnnotationDrivenConfig alon,以便您的bean能够自动接线.

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.

如OP所述,@ AnnotationDrivenConfig已弃用.您可以尝试 https://stackoverflow.com/a/8076045/2231632 吗?

As OP mentioned @AnnotationDrivenConfig is deprecated.Can you try https://stackoverflow.com/a/8076045/2231632 ?

这篇关于Spring DispatchServlet无法在Jetty中找到资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-27 11:47
查看更多