강의

멘토링

커뮤니티

Cộng đồng Hỏi & Đáp của Inflearn

Hình ảnh hồ sơ của neatinfo3300
neatinfo3300

câu hỏi đã được viết

Triển khai dự án mẫu API dựa trên Spring Boot để cải thiện năng suất

kakao token 발급 시 에러

Viết

·

723

0

안녕하세요 ! 강의 수강 중에 에러난 부분이 해결되지 않아 질문 남깁니다.

지금 '카카오 토큰 발급 구현(2) - 토큰 받기' 강의 마지막까지 코드 작성 후 api 실행 했는데

결과

{"errorCode":"500 INTERNAL_SERVER_ERROR","errorMessage":"Could not extract response: no suitable HttpMessageConverter found for response type [class com.app.web.kakaotoken.dto.KakaoTokenDto$Response] and content type [text/html]"}

로 나오고 있습니다.

콘솔창의 에러는

feign.codec.DecodeException: Could not extract response: no suitable HttpMessageConverter found for response type [class com.app.web.kakaotoken.dto.KakaoTokenDto$Response] and content type [text/html]

at feign.InvocationContext.proceed(InvocationContext.java:40) ~[feign-core-11.10.jar:na]

at feign.AsyncResponseHandler.decode(AsyncResponseHandler.java:116) ~[feign-core-11.10.jar:na]

at feign.AsyncResponseHandler.handleResponse(AsyncResponseHandler.java:89) ~[feign-core-11.10.jar:na]

at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:141) ~[feign-core-11.10.jar:na]

at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:91) ~[feign-core-11.10.jar:na]

at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:100) ~[feign-core-11.10.jar:na]

at com.sun.proxy.$Proxy109.requestKakaoToken(Unknown Source) ~[na:na]

at com.app.web.kakaotoken.controller.KakaoTokenController.loginCallback(KakaoTokenController.java:39) ~[main/:na]

at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]

at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]

at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]

at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]

at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-5.3.20.jar:5.3.20]

at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-5.3.20.jar:5.3.20]

at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) ~[spring-webmvc-5.3.20.jar:5.3.20]

at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.3.20.jar:5.3.20]

at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.20.jar:5.3.20]

at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.20.jar:5.3.20]

at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) ~[spring-webmvc-5.3.20.jar:5.3.20]

at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.20.jar:5.3.20]

at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.20.jar:5.3.20]

at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.20.jar:5.3.20]

at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[tomcat-embed-core-9.0.63.jar:4.0.FR]

at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.20.jar:5.3.20]

at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[tomcat-embed-core-9.0.63.jar:4.0.FR]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.63.jar:9.0.63]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.20.jar:5.3.20]

at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.20.jar:5.3.20]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.20.jar:5.3.20]

at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.20.jar:5.3.20]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.20.jar:5.3.20]

at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.20.jar:5.3.20]

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.63.jar:9.0.63]

at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na]

Caused by: org.springframework.web.client.UnknownContentTypeException: Could not extract response: no suitable HttpMessageConverter found for response type [class com.app.web.kakaotoken.dto.KakaoTokenDto$Response] and content type [text/html]

at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:126) ~[spring-web-5.3.20.jar:5.3.20]

at org.springframework.cloud.openfeign.support.SpringDecoder.decode(SpringDecoder.java:75) ~[spring-cloud-openfeign-core-3.1.8.jar:3.1.8]

at org.springframework.cloud.openfeign.support.ResponseEntityDecoder.decode(ResponseEntityDecoder.java:61) ~[spring-cloud-openfeign-core-3.1.8.jar:3.1.8]

at feign.optionals.OptionalDecoder.decode(OptionalDecoder.java:36) ~[feign-core-11.10.jar:na]

at feign.InvocationContext.proceed(InvocationContext.java:36) ~[feign-core-11.10.jar:na]

... 57 common frames omitted

 

 

코드를 여러 번 봐도 강사님이랑 다른 부분이 없는 거 같아서 여쭤봅니다.

감사합니다 !!

spring-bootjpaweb-api

Câu trả lời 2

0

bgh79465479님의 프로필 이미지
bgh79465479
Người chia sẻ kiến thức

에러를 다시 보니깐 KakaoTokenClient로 카카오 토큰을 받아올 때 변환이 안되서 그렇군요! Response의 contentType을 text/html 로 인식하는거 같네요

혹시 모르니 코드도 복사해서 붙여 넣어보시면 좋을꺼 같습니다.

@GetMapping("/oauth/kakao/callback")
public @ResponseBody String loginCallback(String code) {
    String contentType = "application/x-www-form-urlencoded;charset=utf-8";
    KakaoTokenDto.Request kakaoTokenRequestDto = KakaoTokenDto.Request.builder()
            .client_id(clientId)
            .client_secret(clientSecret)
            .grant_type("authorization_code")
            .code(code)
            .redirect_uri("http://localhost:8080/oauth/kakao/callback")
            .build();
    KakaoTokenDto.Response kakaoToken = kakaoTokenClient.requestKakaoToken(contentType, kakaoTokenRequestDto);
    return "kakao toekn : " + kakaoToken;
}

 

KakaoTokenClient

@FeignClient(url = "https://kauth.kakao.com", name = "kakaoTokenClient")
public interface KakaoTokenClient {

    @PostMapping(value = "/oauth/token", consumes = "application/json")
    KakaoTokenDto.Response requestKakaoToken(@RequestHeader("Content-Type") String contentType,
                                             @SpringQueryMap KakaoTokenDto.Request request
    );

}

KakaoTokenDto의 Response에서 기본생성자가 없을 경우 오류가 발생하시는 분들도 있으셔서

@NoArgsConstructor와 @AllArgsConstructor도 한번 추가해 보시면 좋을꺼 같습니다.

public class KakaoTokenDto {
    
    @ToString
    @Builder @Getter
    @NoArgsConstructor @AllArgsConstructor
    public static class Response {
        private String token_type;
        private String access_token;
        private Integer expires_in;
        private String refresh_token;
        private Integer refresh_token_expires_in;
        private String scope;
    }

}

0

bgh79465479님의 프로필 이미지
bgh79465479
Người chia sẻ kiến thức

안녕하세요! 혹시 @ResponseBody가 빠졌는지 확인해보시면 좋을꺼 같네요.

에러메세지를 보면 text/html을 찾을 수 없다 이런식으로 나오는데 loginCallback에서는 json을 클라이언트로 반환해줘야합니다.

public @ResponseBody String loginCallback(String code) {
Hình ảnh hồ sơ của neatinfo3300
neatinfo3300

câu hỏi đã được viết

Đặt câu hỏi