컨텍스트 경로없이 요청 URI를 얻는 방법은 무엇입니까?


127

request.getRequestURI () 메서드 는 컨텍스트 경로와 함께 URI를 반환합니다.

응용 프로그램의 기본 URL 인 경우 예를 들어, http://localhost:8080/myapp/(즉, 컨텍스트 경로는 MyApp를 ) 내가 전화 request.getRequestURI()를 위해 http://localhost:8080/myapp/secure/users, 그것은 반환합니다 /myapp/secure/users.

이 부분 /secure/users, 즉 컨텍스트 경로가없는 URI 만 얻을 수있는 방법이 있습니까?


답변:


158

접두사 패턴에 매핑 된 프런트 컨트롤러 서블릿 내부에있는 경우 HttpServletRequest#getPathInfo().

String pathInfo = request.getPathInfo();
// ...

예제의 서블릿이에 매핑되었다고 가정하면 일반적인 프론트 컨트롤러 서블릿 내에서 유일한 관심 정보 /secure가 반환됩니다 /users.

그러나 서블릿이 접미사 패턴에 매핑 된 경우 (URL 예제는 이것이 사실임을 나타내지 않음) 또는 실제로 필터 내부에있을 때 (호출 될 서블릿이 아직 결정되지 않은 경우) getPathInfo())를 반환 할 수있는 경우 null가장 좋은 방법은 일반적인 String방법을 사용하여 컨텍스트 경로의 길이를 기반으로 요청 URI를 직접 부분 문자열로 지정하는 것입니다 .

HttpServletRequest request = (HttpServletRequest) req;
String path = request.getRequestURI().substring(request.getContextPath().length());
// ...

대신 이것을 사용하는 이유가 getServletPath()있습니까? 필터를 작성 중이며을 getPathInfo()반환 null하지만 getServletPath()컨텍스트를 제외한 경로를 반환합니다 (요청 디스패처에 전달하기에 적합).
Jason C

@JasonC : 대답했듯이 getPathInfo()프런트 컨트롤러 서블릿이 접두사 패턴에 매핑되지 않은 경우 null을 반환합니다.
BalusC

네. 내 말은 : getServletPath보다 getPathInfo를 선호하는 이유가 있습니까? 여기에있는 다른 많은 고득점 답변도 getServletPath를 사용하지 않습니다. 이것이 나를 의심하게 만드는 이유이며 궁금한 이유입니다. 작업중인 서블릿 프로젝트가 있고 내 기술을 연마하려고합니다.
Jason C

1
@JasonC : 서블릿 경로는 JSF 또는 Spring MVC와 같은 서블릿 기반 MVC 프레임 워크가 설치된 경우 변경 될 수 있습니다. 그런 다음 실제 요청 URI (최종 사용자가 브라우저의 주소 표시 줄에 표시되는 URI)가 /foo.xhtml아니라 MVC 프레임 워크의 내부 경로 (예 : 대신 /foo.jsf) 를 나타냅니다 . 이 경우 원래 서블릿 경로는 키가있는 요청 속성으로 확인할 수 RequestDispatcher.FORWARD_SERVLET_PATH있습니다. 어떤 식 으로든 질문은 명시 적으로 요청 URI (브라우저의 주소 표시 줄에서와 같이)를 요청하므로 답변은이를 기반으로합니다.
BalusC 2017-06-26

74
request.getRequestURI().substring(request.getContextPath().length())

대박! 이것이 바로 제가 찾던 것입니다.
장인

4
+1 getPathInfo가 null 및 기타 이상한 점이 될 수 있기 때문에 이것이 getPathInfo보다 더 나은 대답이라고 생각합니다. 다양한 Spring 코드가 getContextPath를 수행하고 getPathInfo 대신 수행 한 것처럼 URI에서이를 제거합니다.
Adam Gent

32

Spring을 사용하면 다음을 수행 할 수 있습니다.

String path = new UrlPathHelper().getPathWithinApplication(request);

1
물론 UrlPathHelper의 인스턴스를 클래스 멤버 변수로 유지하는 것이 합리적입니다 ...
James

실제 요청 매핑 URL을 어떻게 얻을 수 있습니까? 여기에서 안내하십시오 : stackoverflow.com/questions/60446807/…
Pra_A

14

getPathInfo ()는 때때로 null을 반환합니다. 문서 HttpServletRequest에서

이 메서드는 추가 경로 정보가없는 경우 null을 반환합니다.

필터에 컨텍스트 경로가없는 파일 경로가 필요하고 getPathInfo ()가 null을 반환합니다. 그래서 다른 방법을 사용합니다 : httpRequest.getServletPath ()

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;

    String newPath = parsePathToFile(httpRequest.getServletPath());
    ...

}

8

필터 내에서 request.getPathInfo ()를 사용하면 항상 null을 얻는 것처럼 보입니다 (적어도 부두에서는).

이 간결한 잘못된 버그 + 응답은 내가 생각하는 문제를 암시합니다.

https://issues.apache.org/bugzilla/show_bug.cgi?id=28323

서블릿이 요청을 받기 전에 필터가 실행된다는 사실과 관련이 있다고 생각합니다. 컨테이너 버그이거나 내가 식별 할 수없는 예상 된 동작 일 수 있습니다.

하지만 contextPath를 사용할 수 있으므로 fforws 솔루션은 필터에서도 작동합니다. 손으로해야하는 것은 싫지만 구현이 깨 졌거나


5

이를 수행하는 방법은 요청 URI에서 서블릿 컨텍스트 경로를 휴식하는 것입니다.

String p = request.getRequestURI();
String cp = getServletContext().getContextPath();

if (p.startsWith(cp)) {
  String.err.println(p.substring(cp.length());
}

여기에서 읽으 십시오 .


-1

예를 들어 '/ myapp'을 제거하기 위해 split 메소드를 사용할 수 있습니다.

string[] uris=request.getRequestURI().split("/");
string uri="/"+uri[1]+"/"+uris[2];

3
내 애플리케이션을 루트로 배포하고 기본 URL이 localhost : 8080 이되면 문제가 발생 합니다. 이 경우 request.getRequestURI ()는 "/ secure / user"를 반환하고 split 메서드는 여기서 문제를 일으킬 것입니다. 코드는 배포에 종속되지 않아야합니다.
장인
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.