REST调用返回空白XML [英] REST call returning blank 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需要MessageBodyReader
和MessageBodyWriter
. Jersey发行版提供了对xml的支持,但是对于JSON,我们需要添加一个具有支持的模块.杰克逊本身没有为此提供支持.我们需要像jersey-media-jason-jackson
这样的提供程序模块.使用Maven是获取此模块的最简单方法,因为它依赖于其他jar.如果我创建一个仅具有此依赖项的新Maven项目,则这是该模块所依赖的工件的完整列表
Second, for serialization, JAX-RS requires MessageBodyReader
s and MessageBodyWriter
s. 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屋!