HttpServletRequest에서 getRequestURI와 getPathInfo 메소드의 차이점은 무엇입니까?


143

간단하고 매우 가벼운 프론트 컨트롤러를 만들고 있습니다. 올바른 것을 선택하려면 요청 경로를 다른 처리기 (작업)와 일치시켜야합니다.

내 로컬 컴퓨터에서 HttpServletRequest.getPathInfo()HttpServletRequest.getRequestURI()동일한 결과를 반환합니다. 그러나 그들이 프로덕션 환경에서 무엇을 반환할지 잘 모르겠습니다.

그렇다면이 방법의 차이점과 무엇을 선택해야합니까?


1
이 답변도 유용 할 수 있습니다.
BalusC

@BalusC : 고마워, 나는 이미 그 대답의 몇 가지 팁을 사용하고 있습니다.
로마

:이 좋은 다이어그램의 차이에 대해 설명 agiletribe.wordpress.com/2016/02/23/...
AgilePro

답변:


77

getPathInfo()서블릿에 액세스하는 데 사용되는 URI 뒤에 추가 경로 정보를 getRequestURI()제공합니다. 여기서 완전한 URI 를 제공합니다.

서블릿이 먼저 고유 한 URI 패턴으로 구성되어야한다는 점에서 그것들이 다르다고 생각했을 것이다. 루트 (/)에서 서블릿을 제공 한 적이 없다고 생각합니다.

예를 들어 서블릿 'Foo'가 URI '/ foo'에 매핑되면 URI를 생각했을 것입니다.

/foo/path/to/resource

결과는 다음과 같습니다.

RequestURI = /foo/path/to/resource

PathInfo = /path/to/resource

20
디코딩 동작에 대해 언급 할 가치가 있습니다. getRequestURI ()는 문자열을 디코딩하지 않습니다. getPathInfo ()가 디코딩하는 위치
Kavindu Dodanduwa

1
어떤 경우에는 예상대로 getRequestURI()문자열 "/foo/path/to/resource"을 제공 하지만 getPathInfo()동일한 HttpServletRequest객체에 대해 나에게 제공합니다 null. 세계에서 무슨 일이 일어나고 있습니까? 편집 : 사용자 "30thh"에 의해 아래에 답변됩니다.
anddero

460

여기에 작은 비교 테이블을 넣을 것입니다 (어딘가에 갖기 위해).

서블릿은로 매핑되고 /test%3F/*응용 프로그램은 아래에 배포됩니다 /app.

http://30thh.loc:8480/app/test%3F/a%3F+b;jsessionid=S%3F+ID?p+1=c+d&p+2=e+f#a

Method              URL-Decoded Result           
----------------------------------------------------
getContextPath()        no      /app
getLocalAddr()                  127.0.0.1
getLocalName()                  30thh.loc
getLocalPort()                  8480
getMethod()                     GET
getPathInfo()           yes     /a?+b
getProtocol()                   HTTP/1.1
getQueryString()        no      p+1=c+d&p+2=e+f
getRequestedSessionId() no      S%3F+ID
getRequestURI()         no      /app/test%3F/a%3F+b;jsessionid=S+ID
getRequestURL()         no      http://30thh.loc:8480/app/test%3F/a%3F+b;jsessionid=S+ID
getScheme()                     http
getServerName()                 30thh.loc
getServerPort()                 8480
getServletPath()        yes     /test?
getParameterNames()     yes     [p 2, p 1]
getParameter("p 1")     yes     c d

위의 예에서 서버는에서 실행 중이며 localhost:8480이름 30thh.loc은 OS hosts파일에 저장되었습니다.

코멘트

  • "+"는 쿼리 문자열에서 공백으로 만 처리됩니다.

  • "#a"앵커는 서버로 전송되지 않습니다. 브라우저 만 사용할 수 있습니다.

  • 경우 url-pattern서블릿 매핑은 끝나지 않습니다 *(예 : /test또는 *.jsp) getPathInfo()반환 null.

Spring MVC를 사용하는 경우

  • 메소드가를 getPathInfo()반환합니다 null.

  • 메소드 getServletPath()는 컨텍스트 경로와 세션 ID 사이의 부분을 리턴합니다. 위의 예에서 값은/test?/a?+b

  • 의 URL 인코딩 된 부분에주의 @RequestMapping하고 @RequestParam봄입니다. 버그가 많으며 (현재 버전 3.2.4) 일반적 으로 예상대로 작동하지 않습니다 .


20
답변을 인쇄하여 사무실에 포스터로 올려 놓았습니다. 그것이 얼마나 유용합니다!
이브라힘 아리프

2
If the url-pattern in the servlet mapping does not end with * (for example /test or *.jsp), getPathInfo() returns null.훌륭한.
Boris Treukhov

1
나는 모두를 생각 getRequestURI()하고 getRequestURL(),이 경우, 비 디코딩 JSESSIONID를 반환해야합니다 S%3F+ID. 적어도 Tomcat / 8.5.6에서는 작동합니다.
Gediminas Rimsa

30

클라이언트가 주소 표시 줄에 입력하여 서블릿에 도달하는 전체 URL을 분류 해 보겠습니다.

http://www.example.com:80/awesome-application/path/to/servlet/path/info?a=1&b=2#boo

부품은 다음과 같습니다.

  1. 계획: http
  2. 호스트 이름 : www.example.com
  3. 포트: 80
  4. 컨텍스트 경로 : awesome-application
  5. 서블릿 경로 : path/to/servlet
  6. 경로 정보 : path/info
  7. 질문: a=1&b=2
  8. 파편: boo

getRequestURI에 의해 리턴 된 요청 URI 는 파트 4, 5 및 6에 해당합니다.

(실제로 이것을 요청하지 않더라도 getRequestURL 메소드 는 파트 1, 2, 3, 4, 5 및 6을 제공합니다).

지금:

  • 4 부 (컨텍스트 경로)는 서버에서 실행될 수있는 다른 많은 응용 프로그램 중에서 특정 응용 프로그램을 선택하는 데 사용됩니다.
  • 파트 5 (서블릿 경로)는 애플리케이션의 WAR에 번들로 제공 될 수있는 다른 많은 서블릿 중에서 특정 서블릿을 선택하는 데 사용됩니다.
  • 파트 6 (경로 정보)은 서블릿의 논리에 의해 해석됩니다 (예 : 서블릿이 제어하는 ​​일부 리소스를 가리킬 수 있음).
  • 파트 7 (조회)도 getQueryString을 사용하여 서블릿에서 사용 가능합니다.
  • 파트 8 (조각)은 서버로 전송되지 않으며 클라이언트에게만 관련이 있으며

다음은 항상 유지합니다 (URL 인코딩 차이점 제외).

requestURI = contextPath + servletPath + pathInfo

Servlet 3.0 스펙 의 다음 예제 가 매우 유용합니다.


참고 : 이미지는 다음과 같습니다 .HTML로 다시 만들 시간이 없습니다.

여기에 이미지 설명을 입력하십시오


16

다음 서블릿 conf를 고려하십시오.

   <servlet>
        <servlet-name>NewServlet</servlet-name>
        <servlet-class>NewServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>NewServlet</servlet-name>
        <url-pattern>/NewServlet/*</url-pattern>
    </servlet-mapping>

이제 URL에 도달하면 위에서 설명한 패턴으로 매핑되어 http://localhost:8084/JSPTemp1/NewServlet/jhi호출 NewServlet됩니다.

여기:

getRequestURI() =  /JSPTemp1/NewServlet/jhi
getPathInfo() = /jhi

우리는 그 것들을 가지고 있습니다 :

  • getPathInfo()


    서블릿 경로 뒤에 있지만 요청 URL에서 쿼리 문자열 앞에 오는 추가 경로 정보를 지정하여 웹 컨테이너에 의해 디코딩 된 문자열을 리턴 합니다. URL에 추가 경로 정보가없는 경우 null

  • getRequestURI()


    프로토콜 이름에서 쿼리 문자열까지 URL의 일부를 포함하는 문자열을 반환 합니다.

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