java - REST 调用返回空白 XML

标签 java json rest jersey jax-rs

我对 REST 编程还很陌生。

下面是我的类,它旨在返回 XML/JSON,但我在使其返回正确的值时遇到了一些困难。我尝试返回我的 POJO 类的 Response、JsonArray 和对象,但它不起作用。我查看了几个线程,但无法弄清楚到底是什么问题。

资源类:

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

这是我返回 ResponseFriend 对象时得到的结果:

**<?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 类中找不到合适的构造函数。

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

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

我正在使用jaxrs-ri-2.13和 jackson jar :

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

Json jar

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

谢谢

最佳答案

您应该了解的第一件事是 JAX-RS 是一个规范,而您拥有的 jaxrs-ri-2.13 的 jar 是 Jersey 的实现(实际上是引用实现)。了解实现对于帮助解决您的问题非常重要。因此,您应该在帖子中提及这一点(通过标签或明确提及)。

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

enter image description here

Jersey 发行版已经拥有其中一些工件。我不确定它们是否全部包含在捆绑 jar 中,但基于主要(未捆绑)Jersey 发行版,不包含未着色的 jar

enter image description here

您需要寻找这些 jar 并将它们添加到您的项目中。就像我说的,我不知道 Jersey Bundle jar 是否与其他包一起提供,但是您可以获得使用各个 jar 的完整发行版 here。如果使用单个 jar 不起作用,我会考虑使用单独的 jar (所有 jar )。

添加这些 jar 应该会给你 Friend JSON 支持。

<小时/>

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

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

<小时/>

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 构造函数。添加带参数的构造函数,取消隐式无参数构造函数。但即使您创建了一个无参数构造函数其他带参数构造函数,带参数构造函数也永远不会被调用,除非您显式地将资源类的实例创建为单例。

<小时/>

更新

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 ,这将是整个应用程序的单个实例

@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 支持的注入(inject)框架,以便将 UserDBHandler 注入(inject)到 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 发行版(如上所述)包含所有单个 jar,并将所有这些 jar 添加到您的项目中,这样才能正常工作,或者至少包括 hk jar,无论如何 Jackson 提供商也需要这些 jar .

关于java - REST 调用返回空白 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27181507/

相关文章:

c# - 使用 HttpWebRequest 连接 Azure 服务总线中继(WCF 终结点)

web-services - Angular2 如何使用服务类发布数据

python - 如何修改django rest框架发送的响应

java - 如何处理运行时错误: java. lang.NoSuchMethodError

java - SQL 连接异常 - 驱动程序无法使用安全套接字层 (SSL) 加密与 SQL Server 建立安全连接

java - 在 PHP 中接收带有 html 标签的 json 失败

json - 如何使用jq计算中位数?

java - 对于一小段代码来说,延迟初始化值得吗?

java - 模拟器上的背景被拉伸(stretch)

php - 如何使用 Android 客户端将密码散列到 PHP 服务器?