본문 바로가기
Java/Spring with Error

[해결 방법] org.springframework.web.client.HttpServerErrorException

by HJ0216 2023. 8. 21.

👉 기본 환경

- Language: Java

- DB: MySQL

- IDE: IntelliJ

 

 

⌨️ 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package com.example.demo.controller;
 
import com.example.demo.service.mid.MidFcstInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
 
@RestController
public class ApiController {
 
    String midFcstInfo_url = "https://apis.data.go.kr/1360000/MidFcstInfoService/{fcst}";
    UriComponents uri = UriComponentsBuilder
            .fromHttpUrl(midFcstInfo_url)
            .queryParam("serviceKey""")
            .queryParam("numOfRows"5)
            .queryParam("pageNo"1)
            .queryParam("dataType""XML")
            .queryParam("stnId""108")
            .queryParam("tmFc""202308210600")
            .build();
 
 
    @GetMapping(value = "/getMidFcst")
    public void getMidFcst() {
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
 
        UriComponents modifiedUri = UriComponentsBuilder
                .fromUri(uri.toUri())
                .buildAndExpand("getMidFcst");
 
        ResponseEntity<String> result = restTemplate.exchange(modifiedUri.toUriString(), HttpMethod.GET, new HttpEntity<String>(headers), String.class);
 
    }
 
}
 
 
 

😮 http://localhost:8080/getMidFcst 호출

 

 

🖨️오류

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
There was an unexpected error (type=Internal Server Error, status=500).
500 Internal Server Error: "<?xml version="1.0" encoding="UTF-8"?><EOL><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><EOL> <soapenv:Body><EOL> <soapenv:Fault><EOL> <faultcode>soapenv:Server</faultcode><EOL> <faultstring>Policy Falsified</faultstring><EOL> <faultactor>https://apis.data.go.kr/1360000/MidFcstInfoService/%257Bfcst%257D?serviceKey=&amp;numOfRows=5&amp;pageNo=1&amp;dataType=XML&amp;stnId=108&amp;tmFc=202308210600</faultactor><EOL> <detail><EOL> <l7:policyResult<EOL> status="Service Not Found. The request may have been sent to an invalid URL, or intended for an unsupported operation." xmlns:l7="http://www.layer7tech.com/ws/policy/fault"/><EOL> </detail><EOL> </soapenv:Fault><EOL> </soapenv:Body><EOL></soapenv:Envelope><EOL>"
org.springframework.web.client.HttpServerErrorException$InternalServerError: 500 Internal Server Error: "<?xml version="1.0" encoding="UTF-8"?><EOL><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><EOL>    <soapenv:Body><EOL>        <soapenv:Fault><EOL>            <faultcode>soapenv:Server</faultcode><EOL>            <faultstring>Policy Falsified</faultstring><EOL>            <faultactor>https://apis.data.go.kr/1360000/MidFcstInfoService/%257Bfcst%257D?serviceKey=&amp;numOfRows=5&amp;pageNo=1&amp;dataType=XML&amp;stnId=108&amp;tmFc=202308210600</faultactor><EOL>            <detail><EOL>                <l7:policyResult<EOL>                    status="Service Not Found.  The request may have been sent to an invalid URL, or intended for an unsupported operation." xmlns:l7="http://www.layer7tech.com/ws/policy/fault"/><EOL>            </detail><EOL>        </soapenv:Fault><EOL>    </soapenv:Body><EOL></soapenv:Envelope><EOL>"
    at org.springframework.web.client.HttpServerErrorException.create(HttpServerErrorException.java:100)
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:170)
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:122)
    at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
    at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:825)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:783)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:717)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:608)
    at com.example.demo.controller.ApiController.getMidFcst(ApiController.java:212)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1072)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:965)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:529)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:209)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:926)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1791)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:833)
 
 
 

 

 

 

📡 원인

ServiceKey와 동적 할당을 위한 {fcst} 부분이 인코딩 시 문제 발생

예상 URL: /getMidFcst?serviceKey=...&numOfRows=5&pageNo=1&...

실제 URL: /%257Bfcst%257D?serviceKey=&amp;numOfRows=5&amp;pageNo=1&...

 

    - fcst에 getMidFcst가 대입되지 않음

    - { ▶ %257B, } ▶ %257D는 변수 인식을 위한 기호지만, uri에 입력됨

    - queryParam에서 사용되는 & ▶ &amp;로 인코딩됨

 

 

📰 해결 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.example.demo.controller;
 
import com.example.demo.service.mid.MidFcstInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
 
@RestController
public class ApiController {
 
    public UriComponents buildUriComponents(String type) {
        String midFcstInfo_url = "https://apis.data.go.kr/1360000/MidFcstInfoService/";
 
        return UriComponentsBuilder
                .fromHttpUrl(midFcstInfo_url + type)
                .queryParam("serviceKey""K191VdXCbr8NWPrKcAnq1uzT01WQHRPglu0oJzfYyzYD2sjner2RWLyEB8peuW2v7E46s28axdc9EAYncGUX7A==")
                .queryParam("numOfRows"5)
                .queryParam("pageNo"1)
                .queryParam("dataType""XML")
                .queryParam("stnId""108")
                .queryParam("tmFc""202308210600")
                .build();
    }
 
    @GetMapping(value = "/{type}")
    public Object getMidFcst(@PathVariable String type) {
        UriComponents uriComponents = buildUriComponents(type);
 
        UriComponents modifiedUri = UriComponentsBuilder
                .fromUri(uriComponents.toUri())
                .build();
 
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
 
        ResponseEntity<String> result = restTemplate.exchange(modifiedUri.toUriString(), HttpMethod.GET, new HttpEntity<String>(headers), String.class);
 
        return result;
    }
 
}
 
 
 

1. @GetMapping(value = "/{type}"), @PathVariable String type

    - value를 동적으로 할당받기

 

2. UriComponents uriComponents = buildUriComponents(type);

    - buildUriComponents에 pathVar를 전달하여 UriComponentsBuilder 생성

 

3. UriComponents modifiedUri

    - 새로운 UriComponents 생성