REST调用返回空白XML [英] REST call returning blank XML

查看:81
本文介绍了REST调用返回空白XML的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对REST编程还很陌生.

I am pretty new to REST programming.

下面是我的旨在返回XML/JSON的类,但是我在使其返回正确值方面遇到一些困难.我尝试返回POJO类的Response,JsonArray和对象,但无法正常工作.我查看了多个线程,但无法弄清楚到底是什么问题.

Below is my class which is intended to return XML/JSON but I am having some difficulties to make it return proper values. I tried returning Response, JsonArray and Object of my POJO class but its not working. I looked several threads but not able to figure out what exactly is the problem.

资源类别:

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

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

This is what I get when I return the Response or the Friend object:

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

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

And when returning JsonArray this is what I get:

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

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

Another problem I am facing is: if I create a constructor I get below error:

MultiException有1个异常.他们是: 1. java.lang.NoSuchMethodException:在repository.resources.UserService class中找不到合适的构造函数.

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

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

My dev environment is Tomcat 8 , JDK 1.8, Eclipse Luna.

我没有使用Maven或web.xml,而是有一个Application类.

I am not using Maven or web.xml instead I have an Application class.

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

I am using jaxrs-ri-2.13 and jackson jars:

  • jackson-core-asl-1.9.2
  • jackson-jaxrs-1.9.2
  • jackson-mapper-asl-1.9.2
  • jackson-xc-1.9.2

杰森罐子

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

谢谢

推荐答案

您应该了解的第一件事是JAX-RS是一个规范,而您拥有的jaxrs-ri-2.13 jar是来自<的实现(实际上是参考实现). a href ="https://jersey.java.net/download.html" rel ="nofollow noreferrer">泽西岛.了解实现对于帮助您解决问题很重要.因此,您应该在帖子中(通过标签或明确地)提及这一点.

First thing you should understand is that JAX-RS is a specification, and that jar you have jaxrs-ri-2.13 is an implementation (actually the reference implementation) from Jersey. Knowing the implementation is important in helping to solve your problem. So you should mention this in your post (through a tag or explicitly).

第二,对于序列化,JAX-RS需要MessageBodyReaderMessageBodyWriter. Jersey发行版提供了对xml的支持,但是对于JSON,我们需要添加一个具有支持的模块.杰克逊本身没有为此提供支持.我们需要像jersey-media-jason-jackson这样的提供程序模块.使用Maven是获取此模块的最简单方法,因为它依赖于其他jar.如果我创建一个仅具有此依赖项的新Maven项目,则这是该模块所依赖的工件的完整列表

Second, for serialization, JAX-RS requires MessageBodyReaders and MessageBodyWriters. Jersey distribution has support for xml out the box, but for JSON we need to add a module with for support. Jackson by itself does not provide support for this. We need a provider module like jersey-media-jason-jackson. Using Maven is the easiest way to get this module, as it is dependendent on other jars. If I create a new Maven project, with only this dependency, this is the complete list, of artifacts the the module is dependent on

Jersey发行版已经包含了一些工件.我不确定是否所有捆绑罐中都包含这些罐,但是基于主(未捆绑)泽西岛的分布,不包括未着色罐子

The Jersey distribution has some of these artifacts already. I am not sure if all of them are included in the bundle jar, but based on the main (un bundled) Jersey distribution, the un-shaded jars are not included

您将需要查找这些jar,并将其添加到您的项目中.就像我说的,我不知道Jersey Bundle罐子是否与其他包装一起打包,您是否可以获得完整的发行版

You will need to go looking for those jars and add them to your project. Like I said, I don't know if the Jersey Bundle jar comes with the others, packages, bu you can get the complete distribution here that uses individual jars. If using the single jar doesn't work, I would look into using the separate jars (all of them).

添加这些jar会使Friend获得JSON支持.

Adding these jars should give you Friend to JSON support.

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

您需要将您的Friend访问器方法设置为public.编写器找不到getXxx方法,因为它不在同一个程序包中.您还应该公开setXxx方法.

You need to make your Friend accessor methods public. The writer cannot find the getXxx method as it's not in the same package. You should also make the setXxx methods public.

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

Another problem I am facing is: if I create a constructor I get below error:

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构造函数,除非您将资源类的实例显式创建为单例.

Yup. The resource class is created by Jersey, which handles the lifecycle of our request scoped resource classes, and requires a no-arg constructor. Adding a constructor with arguments, cancels the implicit no-arg constructor. But even if you create a no-arg constructor and you other arg constructor, the arg constructor will never be called, unless you explicitly create the instance of your resource class as a singleton.

关于singelton实例,我在教程中没有找到相同的实例.你能告诉我这样做的方法吗?

Regarding the singelton instance, I did not find the same in tutorials. Can you please tell me the way to do that?

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

When you extend Application, you can override getClasses() (which will be container managed request scoped resource class) and getSingletons which will be a single instance for the entire application

@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类中.像

But I am not sure if you really want UserResource to be a singleton. This means that you want this resource to be stateful for the entire application, which may not be desired. Instead you can use an injection framework, supported by Jersey, in order to inject the UserDBHandler into the UserResource class. Something like

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

自定义注入中了解更多信息.另外,我只是用单个jaxrs-rs jar进行了测试,但它没有所需的类.您将需要下载单独的Jersey发行版(如上所述),将所有单个jar都添加到您的项目中,以使其正常工作,或者至少包括hk jar,Jackson也需要提供商.

See more at Custom Injection. Also I just tested this with the single jaxrs-rs jar and it does not come with the needed classes. You will need to download the separate Jersey distribution (mentioned above) will all the single jars, and add all those jars to your project, for this to work, or at least include the hk jars, which are also required by the Jackson provider anyway.

这篇关于REST调用返回空白XML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆