用SpringMVC可以配置为处理所有请求,但不包括静态内容目录?(Can SpringMVC be

2019-06-18 02:07发布

如果我映射我春天应用程序处理所有传入的请求(“/ *”),然后对静态内容返回404的请求。 例如,对于“myhost.com/css/global.css”的请求将返回404,尽管存在资源作为春天拦截请求。

另一种方法是用SpringMVC映射到一个子目录(如“/ home /”),但在这种情况下,你必须在应用程序中的所有链接该目录通过。 有没有办法来用SpringMVC映射到“/”,并排除了一套从处理目录?

我现在的web.xml配置是:

<servlet>
    <servlet-name>springApp</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>springApp</servlet-name>
    <url-pattern>/home/*</url-pattern>
</servlet-mapping>

Idealy我想有映射是类似以下内容:

 <servlet-mapping>
    <servlet-name>springApp</servlet-name>
    <url-pattern>/*</url-pattern>
    <exclude>/css/*,/js/*</exclude>
 </servlet-mapping>

这类型的事可能吗?

Answer 1:

如果你想用Spring来做到这一点而已,这是可能的,但有点混乱:

  1. 你要么需要使用SimpleUrlHandlerMapping建立的,你可以明确地指定应映射到控制器的URL模式或扩展,以支持“忽略”的网址,如“CSS / **”。
  2. 你需要编写自己的HttpRequestHandler实现,将基本上包括“getServletContext()方法。getRequestDsipatcher()。包括()”调用返回所请求的资源为是。
  3. 你必须注册一个处理程序的DefaultHandler为上述SimpleUrlHandlerMapping建立。

一旦所有做到这一点,这是不能被映射到控制器内的所有请求都将被转发到您的HttpRequestHandler并担任“原样”。



Answer 2:

注:此答案适用于春天3.0.4+ ONLY

(顺便说一句,这个问题也已经在这里讨论: 春天提供静态内容与MVC:资源,无效的XSD )

查核在春天的Spring MVC-展示项目颠覆样本库 。 它显示正是你想做的事,即你可以划定,不会被DisapatcherServlet处理静态资源的内容。 请参阅文件/mvc-showcase/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml 。 下面是我如何处理这些例外,那里的JS,CSS和图像是在应用程序上下文根(与映射到MVC命名空间的一个片段mvc

<!-- resources exclusions from servlet mapping -->
<mvc:resources mapping="/css/**" location="/css/" />
<mvc:resources mapping="/images/**" location="/images/" />
<mvc:resources mapping="/js/**" location="/js/" />


Answer 3:

我的服务通过“默认”的servlet静态内容解决,只是服务的内容给客户端。 所以,我的web.xml看起来是这样的:

<servlet>
    <servlet-name>MyApp</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>MyApp</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping> <!-- The 'dynamic' content -->

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.jpg</url-pattern>
</servlet-mapping> <!-- The 'static' content -->

希望这可以帮助。



Answer 4:

对我来说最简单的方法(如果使用Spring的后期足够版)是

<mvc:resources mapping="/**/*.js" location="/"/>
<mvc:resources mapping="/**/*.css" location="/"/>
...


Answer 5:

一种方式做这将是使用滤镜。 你必须编写的自定义代码一点点,但它不坏。 下面是如果你不想*的CSS或* .js文件传给你的servlet春天的例子:

web.xml中:

<filter-mapping>
    <filter-name>fileTypeFilter</filter-name>
    <filter-class>foo.FileTypeFilter</filter-class>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Java类:

public class FileTypeFilter implements Filter {
     public void init(FilterConfig conf) {
         // init logic here
     }

     public void destroy() {
        // release resources here
     }

     public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
          if(shouldExclude(req)) {
              chain.doFilter(req, res);
              //some logic so the request doesnt go to the servlet

              //maybe you could just forward
              //the request directly to the file getting accessed.  not sure if that would work
          }

          //file should be passed to the servlet; you can do some logic here
          //if you want         
     }
     private boolean shouldExclude(ServletRequest req) {
         if(req instanceof HttpServletRequest) {
             HttpServletRequest hreq = (HttpServletRequest) req;
             return (hreq.getRequestURI().endsWith(".css") ||
                     hreq.getRequestURI().endsWith(".js"));
         }
         return false;
    }
}

我没有测试过这一点,但我认为它会工作。

编辑 :有没有在Servlet规范的任何排除功能。 我不认为这是对在Spring中做到这一点的好办法,但它本质上实现了您的文章同样的事情。

编辑2:如果您希望能够轻松地改变什么被过滤,你可以只使用Spring注入到东西在运行时过滤器。

编辑3:我只是,如果你直接递交文件实现的,它会再次这样做的过滤器,你会陷入无限循环。 有可能是另一种方式与过滤器来做到这一点,但我真的不知道它是什么。



Answer 6:

什么是您使用提供给您的静态图像? 如果是Apache的,那么你可以配置Apache的CSS / JS请求不能传递给你的应用服务器。

如果您使用的是Tomcat,你会把这样的事情在你的httpd.conf:

JkUnMount /*.css  webapp

其中,“Web应用程序”是从你的workers.properties的条目。

对不起,我不能给你一个纯Spring的解决方案,但是这是我要做的事。



Answer 7:

我得到了同样的问题,这是我如何解决它:

下面加入到web.xml文件:

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.js</url-pattern>
    <url-pattern>*.css</url-pattern>
    <url-pattern>*.ico</url-pattern>
    <url-pattern>*.png</url-pattern>
    <url-pattern>*.jpg</url-pattern>
    <url-pattern>*.htc</url-pattern>
    <url-pattern>*.gif</url-pattern>
    <url-pattern>*.html</url-pattern>
    <url-pattern>*.htm</url-pattern>
</servlet-mapping>

以下加入到spring3 MVC的servlet bean定义文件(如applicationContext.xml中,即在web.xml作为contextConfigLocation的配置的文件。):

<mvc:annotation-driven /> 
<mvc:default-servlet-handler />


Answer 8:

你有你想要的春天调度处理的请求一致的扩展名(S)(我相信大多数的春天示例使用的* .htm)? 在这种情况下,你可以映射到要处理完扩展,它会绕过你的CSS和JS文件。

否则,我与Nalandial同意,过滤器的方法可能是在这一点上最好的解决办法。



Answer 9:

我使用虚拟URL路径检索我所需要的资源。 通常我使用Spring MVC的,所以我不能有下/ WEB-INF / views文件夹JavaScript和CSS。 我想出了这个特定的servlet,只允许内/ WEB-INF / views文件夹访问的.js和.css文件。 在你的情况,如果移动/ css文件夹和/ JS文件夹的父文件夹如/资源,那么我的解决方案将适用于你。

您可以更改字符串URL =“YOUR_RESOURCE_FOLDER”

因此,例如,虚拟路径可以像http://www.mysite.com/resources/path/path/app.js

这将映射到我的/WEB-INF/views/path/path/app.js

web.xml中

<servlet>
    <servlet-name>ResourceDispatcherServlet</servlet-name>
    <servlet-class>mywebapp.web.ResourceDispatcherServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>ResourceDispatcherServlet</servlet-name>
    <url-pattern>/resource/*</url-pattern>
</servlet-mapping>

的servlet

public class ResourceDispatcherServlet extends HttpServlet {

    public void init() throws ServletException {

    }

    public void doGet(HttpServletRequest req, HttpServletResponse rsp) throws ServletException, IOException {


        String servletPath = req.getServletPath();   // /resource
        String pathInfo = req.getPathInfo();         // /path/path/app.js

        String url = "/WEB-INF/views" + pathInfo;

        String lastPath = StringUtil.substringAfterLast(pathInfo, "/");
        String extension = StringUtil.substringAfterLast(lastPath, ".");

        try {
            RequestDispatcher dispatcher = null;
            if (!StringUtil.isEmpty(extension) && ("js".equals(extension) || "css".equals(extension))) {
                dispatcher = req.getRequestDispatcher(url);
            }

            if (dispatcher != null) {
                dispatcher.include(req, rsp);
            }
            else {
                rsp.sendError(404);
            }
        }
        catch (Exception e) {
            if (!rsp.isCommitted()) {
                rsp.sendError(500);
            }
        }
    }
}


Answer 10:

如果您在使用Spring 3.0.4及以上,你应该使用由atrain提供解决方案

否则,你可以这样做简单的事情:

也许你下面要为静态的目录结构:

WebContent
   |
   WEB-INF
     |
    public
        |
       css
        |
       js
        |
       img

Eclipse默认动态web项目产生以下结构: WebContent/WEB-INF 。 移动public文件夹出你的WEB-INF目录的进入WebContent目录。

在客户端

指在下列方式的静态文件:

<link rel="stylesheet" type="text/css" href="public/css/mystyles.css">

这是我参考。



Answer 11:

它的清洁剂使用UrlRewriteFilter请求重定向到你的servlet,这里的例子urlrewrite.xml

<urlrewrite>
    <rule>
        <from>^/img/(.*)$</from>
        <to>/img/$1</to>
    </rule>
    <rule>
        <from>^/js/(.*)$</from>
        <to>/js/$1</to>
    </rule>
    <rule>
        <from>^/css/(.*)$</from>
        <to>/css/$1</to>
    </rule>
    <rule>
        <from>^/(.*)$</from>
        <to>/app/$1</to>
    </rule>
    <outbound-rule>
        <from>/app/(.*)$</from>
        <to>/$1</to>
    </outbound-rule>
</urlrewrite>

笔记:

  • 这一点很重要,最后<rule>是在底部,所以IMG,JS,CSS将首先被抓
  • <outbound-rule>是可选的,只是为了让现有的
    <c:url value="/app/some" />渲染/some代替/app/some


Answer 12:

通常情况下,大的网站更喜欢使用另一台服务器只能处理静态内容。 静态内容请进入一个服务器和动态变到另一个(带弹簧,在这种情况下)。

在许多情况下,Nginx的服务器(http://nginx.com/),最近的和非常快的服务器。

但是,这并不容易做到。 不少配置。



Answer 13:

在我的情况一切正常。 但我有一个控制器出现问题

这是我的问题@RequestMapping(方法= RequestMethod.GET)

此ÿ变化:

@RequestMapping(value = "/usuario", method = RequestMethod.GET)

和它的作品

寻找那些有坏@RequestMappgin和变化的控制器。



文章来源: Can SpringMVC be configured to process all requests, but exclude static content directories?