간단하고 매우 가벼운 프론트 컨트롤러를 만들고 있습니다. 올바른 것을 선택하려면 요청 경로를 다른 처리기 (작업)와 일치시켜야합니다.
내 로컬 컴퓨터에서 HttpServletRequest.getPathInfo()
와 HttpServletRequest.getRequestURI()
동일한 결과를 반환합니다. 그러나 그들이 프로덕션 환경에서 무엇을 반환할지 잘 모르겠습니다.
그렇다면이 방법의 차이점과 무엇을 선택해야합니까?
답변
getPathInfo()
서블릿에 액세스하는 데 사용되는 URI 뒤에 추가 경로 정보를 getRequestURI()
제공합니다. 여기서 완전한 URI 를 제공합니다.
서블릿이 먼저 고유 한 URI 패턴으로 구성되어야한다는 점에서 그것들이 다르다고 생각했을 것이다. 루트 (/)에서 서블릿을 제공 한 적이 없다고 생각합니다.
예를 들어 서블릿 ‘Foo’가 URI ‘/ foo’에 매핑되면 URI를 생각했을 것입니다.
/foo/path/to/resource
결과는 다음과 같습니다.
RequestURI = /foo/path/to/resource
과
PathInfo = /path/to/resource
답변
여기에 작은 비교 테이블을 넣을 것입니다 (어딘가에 갖기 위해).
서블릿은로 매핑되고 /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) 일반적 으로 예상대로 작동하지 않습니다 .
답변
클라이언트가 주소 표시 줄에 입력하여 서블릿에 도달하는 전체 URL을 분류 해 보겠습니다.
http://www.example.com:80/awesome-application/path/to/servlet/path/info?a=1&b=2#boo
부품은 다음과 같습니다.
- 계획:
http
- 호스트 이름 :
www.example.com
- 포트:
80
- 컨텍스트 경로 :
awesome-application
- 서블릿 경로 :
path/to/servlet
- 경로 정보 :
path/info
- 질문:
a=1&b=2
- 파편:
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로 다시 만들 시간이 없습니다.
답변
다음 서블릿 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의 일부를 포함하는 문자열을 반환 합니다.