programing

정적 컨텐츠 디렉토리를 제외하고 모든 요청을 처리하도록 SpringMVC를 구성할 수 있습니까?

css3 2023. 8. 8. 21:48

정적 컨텐츠 디렉토리를 제외하고 모든 요청을 처리하도록 SpringMVC를 구성할 수 있습니까?

모든 수신 요청('/*')을 처리하도록 스프링 응용 프로그램을 매핑하면 정적 콘텐츠 요청이 404를 반환합니다.예를 들어, "myhost.com/css/global.css "에 대한 요청은 Spring이 요청을 가로채는 동안 리소스가 존재하더라도 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>

이상적으로 저는 다음과 같은 매핑을 원합니다.

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

이런 종류의 일이 가능합니까?

참고: 이 답변은 스프링 3.0.4+에만 적용됩니다.

(BTW, 이 질문은 여기서도 다루었습니다: mvc:resources, 잘못된 xsd로 정적 콘텐츠를 제공하는 봄)

Spring 하위 버전 샘플 저장소에서 Spring mvc-showcase 프로젝트를 확인하십시오.Disapatcher Servlet에서 처리되지 않는 정적 리소스를 설명할 수 있다는 것을 정확히 보여줍니다.파일 참조/mvc-showcase/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml 및 앱 가 은다 JS, 에 매핑된 경우)에 이러한하는 방법에 mvc:

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

고객에게 콘텐츠를 제공하는 '기본' 서블릿을 통해 정적 콘텐츠를 제공함으로써 해결했습니다.그래서 나의 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 -->

이게 도움이 되길 바랍니다.

Spring으로만 이 작업을 수행하려면 가능하지만 약간 지저분합니다.

  1. 컨트롤러에 매핑해야 하는 URL 패턴을 명시적으로 지정할 수 있는 SimpleUrlHandlerMapping을 사용하거나 "css/**"와 같은 "무시" URL을 지원하도록 확장해야 합니다.
  2. 요청한 리소스를 그대로 반환하려면 기본적으로 "getServletContext().getRequestDsipatcher().include()" 호출로 구성된 HttpRequestHandler 구현을 작성해야 합니다.
  3. 위의 SimpleUrlHandlerMapping에 대해 해당 핸들러를 defaultHandler로 등록해야 합니다.

작업이수 의 이모작업완컨매에수없핑모로 됩니다.HttpRequestHandler그리고 "있는 그대로" 대접했습니다.

나에게 가장 간단한 방법은 (충분히 늦은 버전의 스프링을 사용하는 경우)

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

한 가지 방법은 필터를 사용하는 것입니다.당신은 약간의 커스텀 코드를 작성해야 하지만 나쁘지 않습니다.다음은 *.css 또는 *.js 파일을 Spring 서블릿에 전달하지 않으려는 경우의 예입니다.

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

저는 이것을 테스트해 본 적이 없지만, 효과가 있을 것이라고 생각합니다.

편집: 서블릿 사양에는 제외 기능이 없습니다.저는 봄 내에 이것을 하는 좋은 방법이 없다고 생각하지만, 그것은 본질적으로 당신의 게시물에서 같은 것을 달성합니다.

편집 2: 필터링된 내용을 쉽게 변경하려면 스프링을 사용하여 실행 시 필터에 무언가를 주입하면 됩니다.

EDIT 3: 파일로 직접 전달하면 필터가 다시 작동하고 무한 루프에 걸릴 수 있다는 것을 방금 알았습니다.필터를 사용하여 이 작업을 수행할 수 있는 다른 방법이 있을 수 있지만, 솔직히 무엇인지 잘 모르겠습니다.

정적 이미지를 제공하기 위해 무엇을 사용하고 있습니까?Apache인 경우 앱 서버에 CSS/js 요청을 전달하지 않도록 Apache를 구성할 수 있습니다.

Tomcat을 사용하는 경우 httpd.conf에 다음과 같은 것을 넣을 수 있습니다.

JkUnMount /*.css  webapp

여기서 'webapp'은 workers.properties의 항목입니다.

순수한 봄 솔루션을 드릴 수는 없지만, 제가 하는 방법은 이렇습니다.

저도 같은 문제를 얻었고, 그 문제를 해결한 방법은 다음과 같습니다.

다음이 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 서블릿 been 정의 파일(applicationContext.xml, web.xml에서 contextConfigLocation으로 구성된 파일)에 추가되었습니다.

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

Spring dispatcher에서 처리할 요청에 대해 일관된 확장자가 있습니까(대부분의 Spring 예제는 *.htm을 사용합니다)?그런 경우, 당신은 당신의 css와 js 파일을 우회하는 당신이 처리하기를 원하는 확장자에 매핑할 수 있습니다.

그렇지 않으면 Nalandial의 의견에 동의합니다. 필터 접근 방식이 현 시점에서 가장 좋은 해결 방법일 것입니다.

가상 URL 경로를 사용하여 필요한 리소스를 검색합니다.일반적으로 저는 Spring MVC를 사용하기 때문에 /WEB-INF/views 폴더 아래에 Javascript와 CSS를 둘 수 없었습니다./WEB-INF/views 폴더에 있는 .js & .css 파일에만 액세스할 수 있도록 이 사용자 지정 서블릿을 고안했습니다.당신의 경우, /css 폴더와 /js 폴더를 /resource와 같은 상위 폴더로 이동하면 나의 솔루션이 당신에게 적용될 것입니다.

String 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>

서블릿

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

Spring 3.0.4 이상을 사용하는 경우 트레인에서 제공하는 솔루션을 사용해야 합니다.

그렇지 않으면 다음과 같은 간단한 작업을 수행할 수 있습니다.

아마도 당신은 당신이 서비스하기를 원하는 다음과 같은 정적 디렉토리 구조를 가지고 있을 것입니다.

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

Eclipse동적 웹 프로젝트는 기본적으로 다음 구조를 생성합니다.WebContent/WEB-INF이동publicWEB-INF 디렉토리에서 폴더로 이동WebContent디렉토리입니다.

고객측

다음과 같은 방법으로 정적 파일을 참조합니다.

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

여기 제 추천서가 있습니다.

제 경우에는 모든 것이 괜찮았습니다.하지만 컨트롤러에 문제가 있습니다.

그것이 제 문제 @RequestMapping(method = RequestMethod)이었습니다.GET)

y 변경 내용:

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

그리고 그것은 동작한다.

잘못된 @RequestMappgin 및 변경 사항이 있는 컨트롤러를 찾습니다.

UrlRewriteFilter를 사용하여 요청을 서블릿으로 리디렉션하는 것이 더 좋습니다. 여기에 다음 예제가 있습니다.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

일반적으로 대형 웹 사이트는 정적인 내용만 처리하기 위해 다른 서버를 사용하는 것을 선호합니다.정적 콘텐츠 요청은 한 서버로 이동하고 동적 콘텐츠 요청은 다른 서버로 이동합니다(이 경우 스프링 포함).

대부분의 경우 Nginx 서버(http://nginx.com/), 는 최신의 매우 빠른 서버입니다.

하지만 이것은 사소한 일이 아닙니다.많은 구성.

언급URL : https://stackoverflow.com/questions/1234298/can-springmvc-be-configured-to-process-all-requests-but-exclude-static-content