java JAX-RS (Reasteasy) Response.readEntity 抛出:IllegalStateException:RESTEASY003290:实体不受输入流支持

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39530407/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 04:26:39  来源:igfitidea点击:

JAX-RS (Reasteasy) Response.readEntity throws: IllegalStateException: RESTEASY003290: Entity is not backed by an input stream

javarestjunitmockingjax-rs

提问by Niels

I have JUnit test of a method which send a JAX-RS POSTcall. To be independent from external resources I have mocked the REST client and said that a dummy response should be returned. Works great, no problem. But:

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

When calling myResponse.readEntity(String.class)I always get the following Exception:

打电话时myResponse.readEntity(String.class)我总是得到以下异常:

java.lang.IllegalStateException: RESTEASY003290: Entity is not backed by an input stream

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

Here is my code snippet which fails:

这是我失败的代码片段:

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));
    }
}

and the 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)

In my production code, which calls a not mocked REST API, it returns a automatically build response, where the .readEntity(String.class)method works fine.

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

回答by dur

Responseis an abstract class and RESTEasy has different sub classes for client and server, see BuiltResponseand ClientResponse. Not all methods are supported in each sub class.

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

Response#readEntityneeds to be backed by an input stream:

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

Method throws an ProcessingExceptionif the content of the message cannot be mapped to an entity of the requested type and IllegalStateExceptionin case the entity is not backed by an input stream or if the original entity input stream has already been consumed without bufferingthe entity data prior consuming.

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

A BuiltResponseis never backed by an input stream and therefore you get a IllegalStateException.

ABuiltResponse永远不会得到输入流的支持,因此您会得到一个IllegalStateException.

You can use Response#getEntity, it doesn't need an input stream.

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

回答by TheCaptain

Thanks for the hint.

谢谢你的提示。

I ended up with the following that worked for me. Simply return a new instance of the class below.

我最终得到了以下对我有用的方法。只需返回下面类的一个新实例。

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;
    }
}

回答by Sreekanth

Today I went through the same situation. Finally I have the below solution. Just mock the readEntity method in BuiltResponse to return whatever response you need. It worked for me.

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