Java에서 서블릿 필터를 사용하여 수신 서블릿 요청 URL을 변경하는 방법은 무엇입니까?


186

서블릿 필터를 사용하여 수신 서블릿 요청 URL을 변경하는 방법

http://nm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123

http://nm-java.appspot.com/Check_License?Contact_Id=My_Obj_123

?


업데이트 : 아래 BalusC의 단계에 따라 다음 코드를 생각해 냈습니다.

public class UrlRewriteFilter implements Filter {

    @Override
    public void init(FilterConfig config) throws ServletException {
        //
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        String requestURI = request.getRequestURI();

        if (requestURI.startsWith("/Check_License/Dir_My_App/")) {
            String toReplace = requestURI.substring(requestURI.indexOf("/Dir_My_App"), requestURI.lastIndexOf("/") + 1);
            String newURI = requestURI.replace(toReplace, "?Contact_Id=");
            req.getRequestDispatcher(newURI).forward(req, res);
        } else {
            chain.doFilter(req, res);
        }
    }

    @Override
    public void destroy() {
        //
    }
}

관련 항목은 web.xml다음과 같습니다.

<filter>
    <filter-name>urlRewriteFilter</filter-name>
    <filter-class>com.example.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>urlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

예상 결과로 서버 측 및 클라이언트 측 리디렉션을 모두 시도했습니다. BalusC 덕분에 효과가있었습니다!



어떤 버전의 서블릿 스펙을 사용하고 있습니까? 요청을 다른 버전으로 전달하는 방법
Romain Hippeau

이 포스트를보십시오 그것은 또한 당신이 원하는 것을하는 필터를 가지고 있습니다
Romain Hippeau

원래 URL에 매개 변수 (예 : nm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123 ? ** param1 = A & param2 = B **)가 포함 된 경우 이러한 매개 변수도 다음 서블릿 / jsp로 전달됩니다. 원래 매개 변수를 제거하거나 바꾸는 방법을 찾지 못했습니다 (HttpServletRequestWrapper 만 사용). 어떤 아이디어 .. 업데이트 : 그것은 것 같다 http://ocpsoft.org/opensource/how-to-safely-add-modify-servlet-request-parameter-values/가 이 문제를 해결합니다.
Lopotun

감사합니다. URL 재 작성 및 암호화에 대한 예를 찾고있었습니다.
Aditya Yada

답변:


281
  1. 구현 javax.servlet.Filter.
  2. 에서 doFilter()방법, 수신 캐스트 ServletRequest에를 HttpServletRequest.
  3. HttpServletRequest#getRequestURI()경로를 잡는 데 사용 합니다.
  4. , 등의 간단한 java.lang.String방법 을 사용하여 관심있는 부분을 추출하고 새 경로를 작성하십시오.substring()split()concat()
  5. 둘 중 하나를 사용하십시오 ServletRequest#getRequestDispatcher() 다음 RequestDispatcher#forward()새 URL (브라우저의 주소 표시 줄에 반영되지 서버 측 리디렉션)에 대한 요청 / 응답을 전달에 또는 캐스트 수신을 ServletResponseHttpServletResponse다음 HttpServletResponse#sendRedirect()에 반영 새로운 URL에 대한 응답 (클라이언트 측 리디렉션을, 리디렉션 브라우저 주소 표시 줄).
  6. 에 필터를 등록 web.xmlurl-pattern/*/Check_License/*, 컨텍스트 경로에 따라, 또는 이미 서블릿 3.0 인 경우, 사용 @WebFilter하는 대신에 대한 주석을.

URL 을 변경 해야하는 경우 코드에 확인을 추가 하고을 호출 하지 않으면 을 호출하십시오 FilterChain#doFilter(). 그렇지 않으면 무한 루프로 자체 호출됩니다.

또는 기존 타사 API를 사용하여 다음과 같은 모든 작업을 수행 할 수도 있습니다. Apache의 작업 방식과 같이 구성 할 수있는 Tuckey 's UrlRewriteFilter 수도 있습니다 mod_rewrite.


1
위의 어딘가에 doFilter () 샘플 코드가 있습니까? 감사.
Frank

20
정확히 어느 단계에서 붙어 있습니까? 내 대답은 거의 코드 자체를 작성합니다. 파란색으로 표시된 코드 참조는 실제로 클래스 / 메소드 동작을 자세히 설명하는 Javadoc에 대한 링크라는 점에 유의 했습니까? 어떤 식 으로든에서, 만나실 수 있습니다 여기여기에 좋은 JSP / 서블릿 자습서, 특히 필터에 대한 하나.
BalusC

1
나는 그것이 맞다고 가정하지만 필터가 체인의 첫 번째 필터 중 하나 RequestDispatcher#forward()이고 실행되면 나머지 필터는 실행되지 않습니다. 그렇다면 서블릿으로 이것을하는 것이 더 좋은 방법은 아닐까요?
lucasvc

2
@datakey : 순서를 다시 정렬하거나 <dispatcher>FORWARD</dispatcher>필터 매핑에 추가하십시오 .
BalusC

1
@ JimJim2000 : 순서를 다시 정렬하거나 <dispatcher>FORWARD</dispatcher>필터 매핑에 추가하십시오 .
BalusC

21

다음 과 같은 규칙으로 바로 사용할 수있는 URL 재 작성 필터 를 사용할 수 있습니다 .

<rule>
  <from>^/Check_License/Dir_My_App/Dir_ABC/My_Obj_([0-9]+)$</from>
  <to>/Check_License?Contact_Id=My_Obj_$1</to>
</rule>

자세한 내용 은 예제 를 확인하십시오 .


7

BalusC의 답변 단계에 기반한 간단한 JSF Url Prettyfier 필터 . 필터는 / ui 경로로 시작하는 모든 요청 (여기에 모든 xhtml 파일이 저장되어 있다고 가정)을 동일한 경로로 전달하지만 xhtml 접미사를 추가합니다.

public class UrlPrettyfierFilter implements Filter {

    private static final String JSF_VIEW_ROOT_PATH = "/ui";

    private static final String JSF_VIEW_SUFFIX = ".xhtml";

    @Override
    public void destroy() {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpServletRequest = ((HttpServletRequest) request);
        String requestURI = httpServletRequest.getRequestURI();
        //Only process the paths starting with /ui, so as other requests get unprocessed. 
        //You can register the filter itself for /ui/* only, too
        if (requestURI.startsWith(JSF_VIEW_ROOT_PATH) 
                && !requestURI.contains(JSF_VIEW_SUFFIX)) {
            request.getRequestDispatcher(requestURI.concat(JSF_VIEW_SUFFIX))
                .forward(request,response);
        } else {
            chain.doFilter(httpServletRequest, response);
        }
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {

    }

}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.