[SPRING] Spring / Rest @PathVariable 문자 인코딩
SPRINGSpring / Rest @PathVariable 문자 인코딩
내가 사용하는 환경 (Tomcat 6)에서 경로 세그먼트의 백분율 시퀀스는 @PathVariable에 매핑 될 때 ISO-8859-1을 사용하여 분명히 디코딩됩니다.
나는 그것이 UTF-8이되기를 바랍니다.
server.xml에서 URIEncoding 속성을 사용하여 UTF-8을 사용하도록 Tomcat을 구성했습니다.
Spring / Rest가 독자적으로 디코딩을하고 있습니까? 그렇다면 기본 인코딩을 대체 할 수있는 위치는 어디입니까?
추가 정보; 여기에 내 테스트 코드 :
@RequestMapping( value = "/enc/{foo}", method = RequestMethod.GET )
public HttpEntity<String> enc( @PathVariable( "foo" ) String foo, HttpServletRequest req )
{
String resp;
resp = " path variable foo: " + foo + "\n" +
" req.getPathInfo(): " + req.getPathInfo() + "\n" +
"req.getPathTranslated(): " + req.getPathTranslated() + "\n" +
" req.getRequestURI(): " + req.getRequestURI() + "\n" +
" req.getContextPath(): " + req.getContextPath() + "\n";
HttpHeaders headers = new HttpHeaders();
headers.setContentType( new MediaType( "text", "plain", Charset.forName( "UTF-8" ) ) );
return new HttpEntity<String>( resp, headers );
}
다음 URI 경로로 HTTP GET 요청을하면 :
/TEST/enc/%c2%a3%20and%20%e2%82%ac%20rates
UTF-8로 인코딩 된 다음 백분율로 인코딩 된 형식의
/TEST/enc/£ and € rates
내가 얻는 결과는 다음과 같다.
path variable foo: £ and ⬠rates
req.getPathInfo(): /enc/£ and € rates
req.getPathTranslated(): C:\Users\jre\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\TEST\enc\£ and € rates
req.getRequestURI(): /TEST/enc/%C2%A3%20and%20%E2%82%AC%20rates
req.getContextPath(): /TEST
나에게 URIEncoding 속성을 설정 한 후 Tomcat이 올바른 일을하지만 (getPathInfo () 참조) 경로 변수는 ISO-8859-1에서 여전히 디코딩된다는 것을 보여줍니다.
그리고 그 대답은 :
Spring / Rest는 요청 인코딩을 사용합니다. 이것은 매우 이상한 일입니다. 이것은 URI가 아닌 본문에 관한 것입니다. 한숨.
추가 :
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
문제가 해결되었습니다. 정말 간단해야합니다.
실제로, 그것은 더 나쁩니다.
메소드에 실제로 요청 본문이 있고 UTF-8로 인코딩되지 않은 경우 추가 forceEncoding 매개 변수가 필요합니다. 이것은 효과가있는 것으로 보이지만 나중에 문제가 더 많이 발생할 것이라는 점에 우려하고 있습니다.
또 다른 접근법
그동안 디코딩을 사용하지 않도록 설정할 수 있다는 것을 알았습니다.
<property name="urlDecode" value="false"/>
...받는 사람은 올바른 일을 할 수 있습니다. 물론 이것은 많은 다른 것들을 더 어렵게 만들 것입니다.
해결법
-
==============================
1.web.xml에 필터를 추가해야하는 것
web.xml에 필터를 추가해야하는 것
<filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
-
==============================
2.문자 인코딩 필터가있는 경우에도 path 변수가 ISO-8859-1에서 여전히 디코드됩니다. 여기이 문제를 해결하기 위해해야 할 일이 있습니다. 다른 아이디어가 있으면 알려주세요!
문자 인코딩 필터가있는 경우에도 path 변수가 ISO-8859-1에서 여전히 디코드됩니다. 여기이 문제를 해결하기 위해해야 할 일이 있습니다. 다른 아이디어가 있으면 알려주세요!
서버에서 실제 UTF-8 디코딩 된 문자를 보려면이 작업을 수행하고 값을 살펴보십시오 (컨트롤러 매개 변수에 "HttpServletRequest httpServletRequest"를 추가해야 함).
String requestURI = httpServletRequest.getRequestURI(); String decodedURI = URLDecoder.decode(requestURI, "UTF-8");
그런 다음 서버에서 올바른 데이터를 디코딩 했으므로 원하는대로 (디코딩 된 URI에서 매개 변수를 수동으로 가져 오는 것과 같이) 할 수 있습니다.
-
==============================
3.server.xml의 Tomcat에 커넥터를 구성하십시오. useBodyEncodingForURI = "true"또는 URIEncoding = "UTF-8"을 Connector 태그에 추가하십시오. 예 :
server.xml의 Tomcat에 커넥터를 구성하십시오. useBodyEncodingForURI = "true"또는 URIEncoding = "UTF-8"을 Connector 태그에 추가하십시오. 예 :
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" useBodyEncodingForURI="true" redirectPort="8443" />
-
==============================
4.하지만이 작업을하기 위해 Tomcat 구성 (URIEncoding)을 혼란에 빠뜨리면 안된다. 서블릿 API가 경로를 얻고 매개 변수를 압축 해제 된 표현으로 요청할 수있는 방법을 제공하면 애플리케이션 (또는 Spring)은 자체적으로 디코딩을 완전히 처리 할 수 있습니다. 그리고 분명히, HttpServletRequest # getPathInfo와 HttpServletRequest # getQueryString은 이것을 제공 할 것이지만, 후자의 경우 이것은 Spring이 HttpServletRequest # getParameter와 friends에 의존하지 않고 쿼리 문자열을 해석하고 해독해야한다는 것을 의미합니다. 분명히 그들은 이것을하지 않습니다. 즉, @RequestParam 또는 @PathVariable을 사용하여 servlet 컨테이너의 구성에 의존하지 않고 us-ascii 문자열 이외의 문자열을 안전하게 캡처 할 수 없습니다.
하지만이 작업을하기 위해 Tomcat 구성 (URIEncoding)을 혼란에 빠뜨리면 안된다. 서블릿 API가 경로를 얻고 매개 변수를 압축 해제 된 표현으로 요청할 수있는 방법을 제공하면 애플리케이션 (또는 Spring)은 자체적으로 디코딩을 완전히 처리 할 수 있습니다. 그리고 분명히, HttpServletRequest # getPathInfo와 HttpServletRequest # getQueryString은 이것을 제공 할 것이지만, 후자의 경우 이것은 Spring이 HttpServletRequest # getParameter와 friends에 의존하지 않고 쿼리 문자열을 해석하고 해독해야한다는 것을 의미합니다. 분명히 그들은 이것을하지 않습니다. 즉, @RequestParam 또는 @PathVariable을 사용하여 servlet 컨테이너의 구성에 의존하지 않고 us-ascii 문자열 이외의 문자열을 안전하게 캡처 할 수 없습니다.
from https://stackoverflow.com/questions/4470787/spring-rest-pathvariable-character-encoding by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] @Scheduled 주석을 사용하여 시작된 예약 된 작업을 중지하는 방법은 무엇입니까? (0) | 2018.12.19 |
---|---|
[SPRING] 최대 절전 모드, 봄, JPA 및 격리 - 사용자 정의 격리는 지원되지 않습니다. (0) | 2018.12.19 |
[SPRING] JsonIdentityInfo가 포함 된 JavaScript에서 Jackson 객체를 deserialize합니다. (0) | 2018.12.19 |
[SPRING] @ static 클래스에서의 autowired (0) | 2018.12.19 |
[SPRING] 스프링 부트 - jar 파일 만들기 - META-INF / spring.factories에 자동 구성 클래스가 없습니다. (0) | 2018.12.19 |