REST调用返回空白XML

时间:2014-11-28 03:36:05

标签: java json rest jersey jax-rs

我是REST编程的新手。

下面是我的类,它旨在返回XML / JSON,但我遇到一些困难,使它返回正确的值。我尝试返回响应,JsonArray和我的POJO类的对象,但它不起作用。我查看了几个主题,但无法确定究竟是什么问题。

资源类:

public class UserService {

    UserDBHandler userDBHandler; 
    Friend f;

    @GET
    @Path("users/{userId}/friends")
//  @Produces(MediaType.TEXT_PLAIN)
    @Produces({ MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})
    public Friend  getFriends(@PathParam("userId") String userId) throws SQLException, ClassNotFoundException
    {
        System.out.println("userId : " +userId);
        userDBHandler =  new UserDBHandler();
        f = new Friend();



        ArrayList<String> userList = userDBHandler.fetchUsers(userId);

        System.out.println("Array size: "+userList.size());
        Iterator<String> iterator = userList.iterator();

        while(iterator.hasNext())
        {
            f.setUri(iterator.next());
            System.out.println(f.getUri());
        }

        //JsonObject  object = Json.createObjectBuilder().add("frienduri",f.getUri()).build();
        //ResponseBuilder response = Response.ok(f);

        //return Json.createArrayBuilder().add(object).build()
        //return response.build();
        return f;
    }
}

POJO课程:

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;

@XmlRootElement
public class Friend{

    private String friendURI;
    private String event;
    private String uri;

    String getUri() {
        return uri;
    }
    void setUri(String uri) {
        this.uri = uri;
    }
    String getFriendURI() {
        return friendURI;
    }
    void setFriendURI(String friendURI) {
        this.friendURI = friendURI;
    }
    String getEvent() {
        return event;
    }
    void setEvent(String event) {
        this.event = event;
    }
}

这是我在返回响应朋友对象时得到的结果:

**<?xml version="1.0" encoding="UTF-8" standalone="yes"?><friend/>**

返回JsonArray时,这就是我得到的:

[{"frienduri":{"string":"b@b.com","chars":"b@b.com","valueType":"STRING"}}]

我面临的另一个问题是:如果我创建一个构造函数,我会得到以下错误:

MultiException有1个例外。他们是: 1. java.lang.NoSuchMethodException:无法在repository.resources.UserService class中找到合适的构造函数。

我的开发环境是Tomcat 8,JDK 1.8,Eclipse Luna。

我没有使用Maven或web.xml,而是使用了Application类。

我正在使用 jaxrs-ri-2.13 和杰克逊罐子:

  • 杰克逊核-ASL-1.9.2
  • 杰克逊 - JAXRS-1.9.2
  • 杰克逊映射器-ASL-1.9.2
  • 杰克逊-XC-1.9.2

Json jars

  • javax.json-api-1.0
  • javax.json-1.0.4

由于

1 个答案:

答案 0 :(得分:1)

您应该首先理解的是JAX-RS是一个规范,而您拥有jaxrs-ri-2.13的jar是来自Jersey的实现(实际上是参考实现)。了解实施对于帮助解决您的问题非常重要。所以你应该在你的帖子中提到这一点(通过标签或明确)。

其次,对于序列化,JAX-RS需要MessageBodyReaderMessageBodyWriter s。 Jersey发行版支持xml开箱即用,但对于JSON,我们需要添加一个模块以获得支持。杰克逊本身为此提供支持。我们需要一个像jersey-media-jason-jackson这样的提供者模块。使用Maven是获取此模块的最简单方法,因为它依赖于其他jar。如果我创建一个新的Maven项目,只有这个依赖项,这是模块所依赖的工件的完整列表

enter image description here

泽西岛分布已经有一些这些文物。我不确定它们是否都包含在捆绑罐中,但是基于主要(未捆绑的)泽西分布,不包括未着色的罐子

enter image description here

您需要去寻找那些罐子并将它们添加到您的项目中。就像我说的那样,我不知道Jersey Bundle罐子是否附带其他包装,你可以获得使用单个罐子的完整分发here。如果使用单个罐子不起作用,我会考虑使用单独的罐子(所有罐子)。

添加这些jar应该为您提供Friend JSON支持。


<?xml version="1.0" encoding="UTF-8" standalone="yes"?><friend/>

您需要制作Friend访问者方法public。作者找不到getXxx方法,因为它不在同一个包中。您还应该将setXxx方法设为公开。


  

我面临的另一个问题是:如果我创建一个构造函数,我会得到以下错误:

     

A MultiException has 1 exceptions. They are: 1. java.lang.NoSuchMethodException: Could not find a suitable constructor in repository.resources.UserService class

烨。资源类由Jersey创建,它处理我们的请求范围资源类的生命周期,并且需要no-arg构造函数。添加带参数的构造函数,取消隐式的无参数构造函数。但即使您创建了一个无参数构造函数其他arg构造函数,也不会调用arg构造函数,除非您将资源类的实例显式创建为单例。


更新

  

关于singelton实例,我在教程中找不到相同的内容。你能告诉我这样做的方法吗?

扩展Application时,您可以覆盖getClasses()(这将是容器管理的请求范围资源类)和getSingletons,它将是整个应用程序的单个实例

@ApplicationPath("..")
public class MyApplication extends Application {
    private Set<Class<?>> classes = new HashSet<>();
    private Set<Object> singletons = new HashSet<>();

    public MyApplication() {
        singletons.add(new UserResource(new UserDBHandler()));
    }

    @Override
    public Set<Class<?>> getClasses() {
        return classes;
    }

    @Override
    public Set<Object> getSingletons() {
        return singletons;
    }
}

但我不确定你是否真的希望UserResource成为单身人士。这意味着您希望此资源对整个应用程序都是有状态的,这可能是不可取的。相反,您可以使用Jersey支持的注入框架,以便将UserDBHandler注入UserResource类。像

这样的东西
@Path("...")
public class UserResource {
    @Inject
    private UserDBHandler handler;
}

@ApplicationPath("..")
public class MyApplication extends Application {
    private Set<Class<?>> classes = new HashSet<>();

    public MyApplication() {
        classes.add(UserResource.class);
        singletons.add(new AppBinder());
    }

    @Override
    public Set<Class<?>> getClasses() {
        return classes;
    }

    class AppBinder extends org.glassfish.hk2.utilities.binding.AbstractBinder {
        @Override
        public void configure() {
            bind(UserDBHandler.class).to(UserDBHandler.class);
        }
    }
}

点击Custom Injection了解详情。另外,我刚用单jaxrs-rs jar对它进行了测试,并没有提供所需的类。您将需要下载所有单个罐子的单独的Jersey分销(如上所述),并将所有这些罐子添加到您的项目中,以使其工作,或者至少包括hk罐子,这些也是杰克逊提供者无论如何。