当前位置: 首页 > 知识库问答 >
问题:

如何处理空响应在Spring RestTem板

尹兴生
2023-03-14

我的授权服务在成功时返回http 204,在失败时返回http 401,但没有响应库。我无法使用RestTemplate客户端使用此功能。尝试序列化响应失败。来自Jackson的错误建议我在序列化程序中打开FAIL_on_EMPTY_bean,但是如何在restTemplate中设置它呢

使用RESTAPI的客户端

@SuppressWarnings("rawtypes")
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

    RestTemplate restTemplate = new RestTemplate();
    System.out.println("\n\n\n\n ============API REQUEST INTERCEPTOR=============== \n\n\n\n\n");

    if(StringUtils.isBlank(request.getHeader(AuthenticationKeys.AUTHENTICATIONTOKEN.name().toLowerCase()))){
        //TODO AUTHORIZE TOKEN
        ResponseEntity<AuthenticationResponse> authenticateResponse = restTemplate.getForEntity(authenticateUrl, AuthenticationResponse.class);
        if(authenticateResponse.getStatusCode().is2xxSuccessful()){
            //TODO SET THE TOKEN IN THE CONTEXT
            return true;
        }else{
            //TODO DO SOME ERROR HANDLING
            return false;
        }
    }else{
        AuthorizationRequest authorizationRequest = new AuthorizationRequest();
        authorizationRequest.setToken("TESTNG");
        ResponseEntity<Object> authorizationResponse = restTemplate.postForEntity(authorizeUrl, request, Object.class);
        if(authorizationResponse.getStatusCode().is2xxSuccessful()){
            return true;
        }else{
            //TODO DO SOME ERROR HANDLING
            if(authorizationResponse.getStatusCode().equals(HttpStatus.UNAUTHORIZED)){
                response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Oops! access to this API is not authorized to you.");
            }
            return false;
        }
    }

其余服务

@RequestMapping(value="/authorize", method = RequestMethod.POST)
    void authorize(@RequestBody @Valid AuthorizationRequest request, HttpServletResponse response){
        if(request.getToken().equals("TESTING")){
            response.setStatus(HttpServletResponse.SC_NO_CONTENT);
        }else{
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        }
    }
}

例外

Caused by: com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.apache.catalina.connector.CoyoteInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: org.apache.shiro.web.servlet.ShiroHttpServletRequest["request"]->org.apache.catalina.connector.RequestFacade["inputStream"])
    at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:59) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:26) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:663) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:663) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:129) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java:2238) ~[jackson-databind-2.5.0.jar:2.5.0]
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:231) ~[spring-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    ... 52 more

尝试的修复

RestTemplate restTemplate = new RestTemplate();
        List<HttpMessageConverter<?>> converters = restTemplate.getMessageConverters();
        for(HttpMessageConverter<?> converter : converters){
            if(converter instanceof MappingJackson2HttpMessageConverter){
                ((MappingJackson2HttpMessageConverter) converter).getObjectMapper().configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
            }
        }

下一个错误

org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: getInputStream() has already been called for this request (through reference chain: org.apache.shiro.web.servlet.ShiroHttpServletRequest["request"]->org.apache.catalina.connector.RequestFacade["reader"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: getInputStream() has already been called for this request (through reference chain: org.apache.shiro.web.servlet.ShiroHttpServletRequest["request"]->org.apache.catalina.connector.RequestFacade["reader"])
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:238) ~[spring-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:208) ~[spring-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.web.client.RestTemplate$HttpEntityRequestCallback.doWithRequest(RestTemplate.java:777) ~[spring-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:566) ~[spring-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:529) ~[spring-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:356) ~[spring-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at mordeth.orchestration.interceptor.ApiRequestInterceptor.preHandle(ApiRequestInterceptor.java:120) ~[ApiRequestInterceptor.class:?]
    at org.springframework.web.servlet.HandlerExecutionChain.applyPreHandle(HandlerExecutionChain.java:134) ~[spring-webmvc-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938) [spring-webmvc-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877) [spring-webmvc-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) [spring-webmvc-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868) [spring-webmvc-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:646) [servlet-api.jar:?]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) [spring-webmvc-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) [servlet-api.jar:?]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) [catalina.jar:7.0.57]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.57]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat7-websocket.jar:7.0.57]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.57]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.57]
    at mordeth.orchestration.controller.CorsFilter.doFilterInternal(CorsFilter.java:21) [CorsFilter.class:?]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.57]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.57]
    at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449) [shiro-web-1.2.0.jar:1.2.0]
    at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365) [shiro-web-1.2.0.jar:1.2.0]
    at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90) [shiro-core-1.2.0.jar:1.2.0]
    at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83) [shiro-core-1.2.0.jar:1.2.0]
    at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:380) [shiro-core-1.2.0.jar:1.2.0]
    at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362) [shiro-web-1.2.0.jar:1.2.0]
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125) [shiro-web-1.2.0.jar:1.2.0]
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) [spring-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) [spring-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.57]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.57]
    at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:67) [log4j-web-2.0.jar:2.0]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.57]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.57]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) [catalina.jar:7.0.57]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) [catalina.jar:7.0.57]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503) [catalina.jar:7.0.57]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) [catalina.jar:7.0.57]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) [catalina.jar:7.0.57]
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950) [catalina.jar:7.0.57]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) [catalina.jar:7.0.57]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421) [catalina.jar:7.0.57]
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070) [tomcat-coyote.jar:7.0.57]
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611) [tomcat-coyote.jar:7.0.57]
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314) [tomcat-coyote.jar:7.0.57]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [?:1.7.0_71]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [?:1.7.0_71]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-coyote.jar:7.0.57]
    at java.lang.Thread.run(Thread.java:745) [?:1.7.0_71]
Caused by: com.fasterxml.jackson.databind.JsonMappingException: getInputStream() has already been called for this request (through reference chain: org.apache.shiro.web.servlet.ShiroHttpServletRequest["request"]->org.apache.catalina.connector.RequestFacade["reader"])
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:210) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:177) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:190) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:671) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:663) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:129) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java:2238) ~[jackson-databind-2.5.0.jar:2.5.0]
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:231) ~[spring-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    ... 52 more
Caused by: java.lang.IllegalStateException: getInputStream() has already been called for this request
    at org.apache.catalina.connector.Request.getReader(Request.java:1239) ~[catalina.jar:7.0.57]
    at org.apache.catalina.connector.RequestFacade.getReader(RequestFacade.java:505) ~[catalina.jar:7.0.57]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.7.0_71]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[?:1.7.0_71]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.7.0_71]
    at java.lang.reflect.Method.invoke(Method.java:606) ~[?:1.7.0_71]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:536) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:663) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:575) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:663) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:156) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:129) ~[jackson-databind-2.5.0.jar:2.5.0]
    at com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java:2238) ~[jackson-databind-2.5.0.jar:2.5.0]
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:231) ~[spring-web-4.1.4.RELEASE.jar:4.1.4.RELEASE]
    ... 52 more

共有1个答案

蒋嘉实
2023-03-14

使用字符串而不是AuthenticationResponse。如果得到空响应,字符串值将为空。

ResponseEntity<String> authenticateResponse = restTemplate.getForEntity(authenticateUrl, String.class);

更新:检查此链接。我想这会解决你的问题。

ResponseEntity<Void> response = restTemplate.getForEntity(authenticateUrl,Void.class);
Void body = response.getBody();
 类似资料:
  • 下面是一个json响应的示例。正如您所看到的,像:news、number_likes、number_comment、number_post、user和owner这样的字段总是存在。但是像:place、place_mark、comment、album、photo这样的字段并不总是存在。这取决于新闻的类型。 请帮帮我!为了正确的json反序列化,我需要做什么?也许有人有经验,在编写自定义转炉工厂或可以

  • 问题内容: 由于JavaScript在单个线程中运行,因此在发出AJAX请求后,后台实际发生了什么?我想对此有更深入的了解,有人可以阐明吗? 问题答案: 在幕后,javascript具有事件队列。每次执行javascript线程完成时,它都会检查队列中是否还有其他事件要处理。如果存在,它将退出队列并触发该事件(例如,单击鼠标)。 位于ajax调用下的本机代码网络将知道ajax响应何时完成,并且事件

  • 最近我开始使用reverfit2,我遇到了一个解析空响应体的问题。我有一个服务器,它只响应http代码,没有任何内容在响应体。 我如何只处理关于服务器响应的元信息(报头、状态代码等)?

  • 因此,应用程序流程如下: Spring应用程序接收请求- 这是我正在使用的网络客户端(副本): 现在我不想通过控制器将此Mono对象直接返回到客户端(如Angular应用程序),因为这是一个中间步骤。我想对从 WebClient 收到的响应运行一些验证。 我已经试过<代码>。block()方法来检索函数,但是按照反应式编程,这似乎是一种不好的做法。(阻塞操作)此外,我无法理解如何使用<代码>。su

  • 如何在Android快速网络库中处理一个空的响应体?我知道在改造中我们有空的,但是如何在快速网络中处理。 POST请求,请求内容类型JSON,用Http代码清空响应体。 改造当量: 我的代码在下面

  • 当没有数据avilable时,它返回以下JSON: http://www.omdbapi.com/?t=asdasdas