JaeWon's Devlog
article thumbnail
반응형

스프링부트로 프로젝트 진행 중 다음과 같은 에러가 발생하였다.

 Note: further occurrences of HTTP request parsing errors will be logged at DEBUG level.

java.lang.IllegalArgumentException: Invalid character found in the request target [/json/list?member[0].name=%ED%99%A9%EC%9E%AC%EC%9B%90&member[0].age=29&member[1].name=%EA%B0%9C%EB%B0%9C%EC%9E%90&member[1].age=25]. The valid characters are defined in RFC 7230 and RFC 3986
	at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:490) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:261) ~[tomcat-embed-core-9.0.44.jar:9.0.44]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.44.jar:9.0.44]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) [tomcat-embed-core-9.0.44.jar:9.0.44]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707) [tomcat-embed-core-9.0.44.jar:9.0.44]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.44.jar:9.0.44]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_201]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_201]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.44.jar:9.0.44]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_201]

1. 에러 발생 상황

get 방식으로 parameter를 보낼때 list 형식으로 직접 보내고자 하였다.

  • 요청 URL
    • http://localhost:8081/json/list?member[0].name=황재원&member[0].age=29&member[1].name=개발자&member[1].age=25
  • 요청 받는 Controller
@RestController
@RequestMapping("/json")
public class JsonRestcontroller {

    @GetMapping("/list")
    public void test(@ModelAttribute JsonModelList jsonModelList){
        // 로직 처리
    }
}
  • 요청 받는 Model
@Getter
@Setter
public class JsonModelList {

    private List<JsonModel> member;
    
}
@Getter
@Setter
@ToString
public class JsonModel {

    private String name;
    private int age;
}

2. 원인

특수문자('[ ]')로 인해 위와 같은 에러가 발생하였다.

3. 에러 발생 해결

SpringBoot는 내장 Tomcat(톰캣)을 사용하고 있으며, 이 Tomcat 의 특정 버전 이상에서 RFC 3986 규격이 적용되었다고 한다.
RFC 3986에는 영어 문자(a-zA-Z), 숫자(0-9), -. ~4 특수 문자 및 모든 예약 문자만 허용된다.

해당 에러를 발생시키지 않으려면, 아래와 같이 relaxQueryChars 옵션에 허용할 문자를 추가하거나 톰캣 버전을 다운그레이드 해야한다.

  • 스프링부트 TomcatConfig Custom(커스텀)하기
@Configuration
public class TomcatWebCustomConfig implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        factory.addConnectorCustomizers((TomcatConnectorCustomizer)
                connector -> connector.setAttribute("relaxedQueryChars", "<>[\\]^`{|}"));
    }
}
  • 확인

참고!!!
javascript에서 서버로 데이터를 보낼 때 위와 같은 에러가 발생한다면 javascript에서 encodeURI 함수를 통해 문자를 인코딩하여 보내면 발생하지 않는다.

참고

- http://jmlim.github.io/java/2019/10/14/characters-are-defined-in-rfc-7230-and-rfc-3986/

반응형
profile

JaeWon's Devlog

@Wonol

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!