Jersey - JerseyTest:从输入流中读取实体时出错

Jersey - JerseyTest: Error reading entity from input stream

为了学习 Jersey,我创建了一个测试项目。我创建了以下 类 Book.java(模型)、BookDao.javaBookResource.java,到目前为止一切正常。我的问题是我正在尝试 运行 (BookResourceTest.java) 的 JerseyTest。我正在使用 Jackson 进行 JSON 序列化。

当我 运行 测试时,我得到这个错误:Error reading entity from input stream。 这是控制台输出:

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.example.BookResourceTest
Ιουν 13, 2015 5:25:23 ΜΜ org.glassfish.jersey.test.grizzly.GrizzlyTestContainerFactory$GrizzlyTestContainer <init>
INFO: Creating GrizzlyTestContainer configured at the base URI http://localhost:9998/
Ιουν 13, 2015 5:25:24 ΜΜ org.glassfish.grizzly.http.server.NetworkListener start
INFO: Started listener bound to [localhost:9998]
Ιουν 13, 2015 5:25:24 ΜΜ org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer] Started.
Ιουν 13, 2015 5:25:24 ΜΜ org.glassfish.jersey.filter.LoggingFilter log
INFO: 1 * Sending client request on thread main
1 > GET http://localhost:9998/books
1 > Accept: application/json

Ιουν 13, 2015 5:25:25 ΜΜ org.glassfish.jersey.filter.LoggingFilter log
INFO: 2 * Client response received on thread main
2 < 200
2 < Content-Length: 177
2 < Content-Type: application/json
2 < Date: Sat, 13 Jun 2015 14:25:25 GMT
[{"id":"2","title":"title2","author":"author2","isbn":"12345","published":1434205524749},{"id":"1","title":"title1","author":"author1","isbn":"45678","published":1434205524749}]

Ιουν 13, 2015 5:25:25 ΜΜ org.glassfish.grizzly.http.server.NetworkListener shutdownNow
INFO: Stopped listener bound to [localhost:9998]
Ιουν 13, 2015 5:25:25 ΜΜ org.glassfish.jersey.test.grizzly.GrizzlyTestContainerFactory$GrizzlyTestContainer <init>
INFO: Creating GrizzlyTestContainer configured at the base URI http://localhost:9998/
Ιουν 13, 2015 5:25:25 ΜΜ org.glassfish.grizzly.http.server.NetworkListener start
INFO: Started listener bound to [localhost:9998]
Ιουν 13, 2015 5:25:25 ΜΜ org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer-1] Started.
Ιουν 13, 2015 5:25:25 ΜΜ org.glassfish.jersey.filter.LoggingFilter log
INFO: 1 * Sending client request on thread main
1 > GET http://localhost:9998/books/1
1 > Accept: application/json

Ιουν 13, 2015 5:25:25 ΜΜ org.glassfish.jersey.filter.LoggingFilter log
INFO: 2 * Client response received on thread main
2 < 200
2 < Content-Length: 87
2 < Content-Type: application/json
2 < Date: Sat, 13 Jun 2015 14:25:25 GMT
{"id":"1","title":"title1","author":"author1","isbn":"45678","published":1434205525362}

Ιουν 13, 2015 5:25:25 ΜΜ org.glassfish.grizzly.http.server.NetworkListener shutdownNow
INFO: Stopped listener bound to [localhost:9998]
Tests run: 2, Failures: 0, Errors: 2, Skipped: 0, Time elapsed: 2.393 sec <<< FAILURE!

Results :

Tests in error: 
  testGetBooks(com.example.BookResourceTest): Error reading entity from input stream.
  testGetBook(com.example.BookResourceTest): Error reading entity from input stream.

Tests run: 2, Failures: 0, Errors: 2, Skipped: 0

我做错了什么?

这是我的项目文件:

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>simple-service</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>simple-service</name>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.glassfish.jersey</groupId>
                <artifactId>jersey-bom</artifactId>
                <version>${jersey.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-grizzly2-http</artifactId>
        </dependency>
        <!-- uncomment this to get JSON support:
         <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-moxy</artifactId>
        </dependency>
        -->
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>${jersey.version}</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.9</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
            <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <inherited>true</inherited>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>java</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <mainClass>com.example.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <properties>
        <jersey.version>2.18</jersey.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

</project>

Book.java

public class Book {

    private String id;
    private String title;
    private String author;
    private String isbn;
    private Date published;

    public Book(String id, String title, String author, String isbn, Date published) {
        this.id = id;
        this.title = title;
        this.author = author;
        this.isbn = isbn;
        this.published = published;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getIsbn() {
        return isbn;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }

    public Date getPublished() {
        return published;
    }

    public void setPublished(Date published) {
        this.published = published;
    }

}

BookDao.java

public class BookDao {

    private Map<String, Book> books;


    public BookDao() {
        books = new HashMap<>();
        books.put("1", new Book("1", "title1", "author1", "45678", new Date()));
        books.put("2", new Book("2", "title2", "author2", "12345", new Date()));
    }

    public Collection<Book> getBooks() {
        return (books.values());
    }

    public Book getBook(String id) {
        return books.get(id);
    }
}

BookResource.java

@Path("/books")
public class BookResource {

    BookDao dao = new BookDao();


    @GET
    @Produces({"application/xml", "application/json"})
    public Collection<Book> getBooks() {
        return dao.getBooks();
    }


    @Path("/{id}")
    @GET
    @Produces({"application/xml", "application/json"})
    public Book getBook(@PathParam("id") String id) {
        return dao.getBook(id);
    }
}

BookResourceTest.java

public class BookResourceTest extends JerseyTest {

    @Override
    protected Application configure() {
        enable(TestProperties.LOG_TRAFFIC);
        enable(TestProperties.DUMP_ENTITY);
        return new ResourceConfig().packages("com.example");
    }


    @Test
    public void testGetBook() {
        Book response = target("books").path("1").request().get(Book.class);
        assertNotNull(response);
    }

    @Test
    public void testGetBooks() {
        Collection<Book> response = target("books").request().get(new GenericType<Collection<Book>>() {
        });
        assertEquals(2, response.size());
    }
}

看来原因是 Book.java 没有默认构造函数,所以 Jackson 无法创建它的实例...

public class Book {

    private String id;
    private String title;
    private String author;
    private String isbn;
    private Date published;

    //must have default constructor 
    public Book() {
    }

    public Book(String id, String title, String author, String isbn, Date published) {
        this.id = id;
        this.title = title;
        this.author = author;
        this.isbn = isbn;
        this.published = published;
    }


    ...

}