尝试使用Jersey和Jackson将模型作为JSON返回时出现内部服务器错误

时间:2014-09-13 21:14:34

标签: spring jax-rs hateoas

我是JAX-RS的新手,在使用嵌入式Tomcat时遇到了一些麻烦。

任何人都可以看到我在/ car URI中缺少什么工作?我试图以JSON的形式获得响应。 另外,使用spring-hateoas,任何人都知道如何在下面更新以获取链接? 我在非Tomcat,非泽西岛项目中使用了spring-hateoas链接,但我无法使用此设置。

Gradle项目

buildscript {
    repositories {
        maven { url "http://repo.spring.io/libs-release" }
        mavenLocal()
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.5.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'idea'

repositories {
    mavenLocal()
    mavenCentral()
    maven { url "http://repo.spring.io/libs-release" }
}

dependencies {
    compile "org.apache.tomcat.embed:tomcat-embed-core:7.0.34"
    compile "org.apache.tomcat.embed:tomcat-embed-logging-juli:7.0.34"
    compile "org.apache.tomcat.embed:tomcat-embed-jasper:7.0.34"
    compile "org.apache.tomcat:tomcat-jasper:7.0.34"
    compile "org.apache.tomcat:tomcat-jasper-el:7.0.34"
    compile "org.apache.tomcat:tomcat-jsp-api:7.0.34"

    compile 'javax.ws.rs:javax.ws.rs-api:2.0-m02'

    compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.12'

    compile 'org.codehaus.jackson:jackson-mapper-asl:1.9.13'
    compile 'com.fasterxml.jackson.core:jackson-databind'
    compile 'org.springframework.hateoas:spring-hateoas:0.16.0.RELEASE'
    compile 'org.springframework:spring-web:4.0.3.RELEASE'

    compile 'com.sun.jersey:jersey-json:1.7'
}

Tomcat的web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

    <context-param>
        <param-name>contextClass</param-name>
        <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>REST Servlet</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.sample.resources.ResourceLoader</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>REST Servlet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

</web-app>

Main.java - 运行独立的Tomcat

package com.sample.main;

import org.apache.catalina.Context;
import org.apache.catalina.startup.Tomcat;

import java.io.File;

public class Main {
    public static void main(String[] args) throws Exception {

        String webappDirLocation = "src/main/webapp/";

        Tomcat tomcat = new Tomcat();

        tomcat.setPort(8080);

        Context context = tomcat.addWebapp("/", new File(webappDirLocation).getAbsolutePath());

        File configFile = new File(webappDirLocation + "WEB-INF/web.xml");
        context.setConfigFile(configFile.toURI().toURL());

        tomcat.start();

        tomcat.getServer().await();

    }
}

ResourceLoader.java - 这是我注册资源的地方

package com.sample.resources;

import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.core.Application;

public class ResourceLoader extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        final Set<Class<?>> classes = new HashSet<Class<?>>();

        // register root resource
        classes.add(HelloWorldRestResource.class);
        return classes;
    }
}

HelloWorldRestResource.java - 处理每个URI / hello和/ car的控制器

package com.sample.resources;

import com.sample.model.Car;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("/resource")
@Produces(MediaType.APPLICATION_JSON)
public class HelloWorldRestResource {
    @GET
    @Path("/hello")
    @Produces(MediaType.TEXT_PLAIN)
    public String sayHello() {
        return "Hello World from Tomcat Embedded with Jersey!";
    }

    @GET
    @Path("/car")
    @Produces(MediaType.APPLICATION_JSON)
    public Response showModel() {
        Car mine = new Car(2014);
        return Response.ok().entity(mine).build();
    }
}

Car.java - 使用JAXB注释帮助将其序列化为JSON的POJO

package com.sample.model;

import javax.xml.bind.annotation.XmlRootElement;
import org.springframework.hateoas.ResourceSupport;

@XmlRootElement()
public class Car extends ResourceSupport {
    private int year;

    public Car(int year) {
        this.year = year;
    }
}

2 个答案:

答案 0 :(得分:0)

杰克逊期待您的POJO的默认构造函数。如果没有默认构造函数,您应该得到如下错误:

org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type Car

只需添加默认构造函数,或者如果您不想使用Jacksons @JsonCreator

注意:Jackson不需要JAXB注释。

答案 1 :(得分:0)

找到了解决内部服务器错误的问题之一。 gradle项目需要像这样:

buildscript {
    repositories {
        maven { url "http://repo.spring.io/libs-release" }
        mavenLocal()
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.5.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'idea'

repositories {
    mavenLocal()
    mavenCentral()
    maven { url "http://repo.spring.io/libs-release" }
}

dependencies {
    compile "org.apache.tomcat.embed:tomcat-embed-core:7.0.34"
    compile "org.apache.tomcat.embed:tomcat-embed-logging-juli:7.0.34"
    compile "org.apache.tomcat.embed:tomcat-embed-jasper:7.0.34"
    compile "org.apache.tomcat:tomcat-jasper:7.0.34"
    compile "org.apache.tomcat:tomcat-jasper-el:7.0.34"
    compile "org.apache.tomcat:tomcat-jsp-api:7.0.34"
    compile 'org.slf4j:slf4j-api:1.7.5'
    compile 'org.slf4j:slf4j-jcl:1.7.5'

    compile 'org.glassfish.jersey.media:jersey-media-json-jackson:+'
    compile 'javax.ws.rs:javax.ws.rs-api:+'
    compile 'javax.validation:validation-api:+'

    compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.12'

    compile 'org.springframework.hateoas:spring-hateoas:0.16.0.RELEASE'
    compile 'org.springframework:spring-web:4.0.3.RELEASE'

    compile 'com.owlike:genson:1.0'
}

JacksonFeature需要像这样注册

package com.sample.resources;

import org.glassfish.jersey.jackson.JacksonFeature;
import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.core.Application;

public class ResourceLoader extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        final Set<Class<?>> classes = new HashSet<Class<?>>();

        // register root resource
        classes.add(HelloWorldRestResource.class);
        return classes;
    }

    @Override
    public Set<Object> getSingletons() {
        final Set<Object> instances = new HashSet<Object>();
        instances.add(new JacksonFeature());
        return instances;
    }
}

希望这有助于其他人。