【问题标题】:JAX-RS (Reasteasy) Response.readEntity throws: IllegalStateException: RESTEASY003290: Entity is not backed by an input streamJAX-RS (Reasteasy) Response.readEntity 抛出:IllegalStateException:RESTEASY003290:实体不受输入流的支持
【发布时间】:2016-09-16 11:29:59
【问题描述】:

我对发送 JAX-RS POST 调用的方法进行了 JUnit 测试。 为了独立于外部资源,我模拟了 REST 客户端并说应该返回一个虚拟响应。效果很好,没问题。但是:

当调用myResponse.readEntity(String.class) 时,我总是得到以下异常:

java.lang.IllegalStateException: RESTEASY003290: 实体不受输入流的支持

这是我的代码 sn-p 失败:

import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import org.junit.Test;

public class SimpleTest {

    @Test
    public void testReadResponse() {
        final JsonObject responseContent = new JsonObject();
        responseContent.add("field", new JsonPrimitive("This is a JSON for testing."));
        final String expected = responseContent.toString();
        final Response.ResponseBuilder builder = Response.ok()
            .entity(responseContent.toString())
            .header("Content-Type", MediaType.APPLICATION_JSON);
        final Response dummyResponse = builder.build();
        final String result = dummyResponse.readEntity(String.class); // <-- Exception is thrown here!
        assertThat("JSON Strings are not identical.", result, is(expected));
    }
}

和 Stacktrace:

   java.lang.IllegalStateException: RESTEASY003290: Entity is not backed by an input stream
    at org.jboss.resteasy.specimpl.BuiltResponse.readEntity(BuiltResponse.java:230)
    at org.jboss.resteasy.specimpl.BuiltResponse.readEntity(BuiltResponse.java:219)
    at de.me.myproject.SimpleTest.testReadResponse(SimpleTest.java:43)

在调用未模拟的 REST API 的生产代码中,它返回自动构建响应,其中 .readEntity(String.class) 方法工作正常。

【问题讨论】:

    标签: java rest junit mocking jax-rs


    【解决方案1】:

    Response 是一个抽象类,RESTEasy 有不同的客户端和服务器子类,参见BuiltResponseClientResponse。并非每个子类都支持所有方法。

    Response#readEntity 需要有输入流支持:

    如果消息的内容无法映射到所请求类型的实体,则方法抛出ProcessingException,如果实体没有输入流支持或原始实体输入流已经被映射,则方法抛出IllegalStateException在没有 buffering 之前消费的实体数据的情况下消费。

    BuiltResponse 永远不会由输入流支持,因此您会得到一个IllegalStateException

    你可以使用Response#getEntity,它不需要输入流。

    【讨论】:

    • getEntity() 确实解决了这个问题。添加到 getEntity(),可以将 getEntity() 响应类型转换为自定义 POJO,然后使用通常的 getXXX() 执行assertEquals(typecastedResponse.getXXX(), expected)
    【解决方案2】:

    今天我也遇到了同样的情况。最后我有以下解决方案。只需模拟 BuiltResponse 中的 readEntity 方法即可返回您需要的任何响应。它对我有用。

    【讨论】:

    • edit您的帖子并将实际代码显示为文本而不是屏幕截图。其他人无法从您的图像中复制和粘贴。 See here 了解详情。谢谢。
    【解决方案3】:

    感谢您的提示。

    我最终得到了对我有用的以下内容。只需返回以下类的新实例。

    class MockResponse extends BuiltResponse {
        private Object entity;
    
        public MockResponse() {
        }
        public MockResponse(Object entity) {
            this.entity = entity;
        }
        @Override
        public <T> T readEntity(Class<T> type) {
            return (T) entity;
        }
    
        @Override
        public <T> T readEntity(Class<T> type, Type genericType, Annotation[] anns) {
            return (T) entity;
        }
    }
    

    【讨论】:

    • 像上面那样创建一个 mockResponse 对我没有帮助。不知道我哪里错了:(
    猜你喜欢
    • 1970-01-01
    • 2011-03-19
    • 1970-01-01
    • 2015-07-22
    • 1970-01-01
    • 2017-07-18
    • 2014-08-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多