Java 创建文本/纯泽西响应

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22611105/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 16:51:22  来源:igfitidea点击:

Create a text/plain Jersey response

javaweb-servicesrestjaxbjersey

提问by Jess

I have some code that works, but I am looking for a better way to do it. I have a RESTful web API that I want to support JSON, XML, and TEXT media types. The JSON and XML is easy with a JAXB annotated "bean" class. I just got text/plainto work, but I wish Jersey was a little more intelligent and would be able to convert a list of my beans, List<Machine>to a string using toString.

我有一些有效的代码,但我正在寻找更好的方法来做到这一点。我有一个 RESTful Web API,我希望它支持 JSON、XML 和 TEXT 媒体类型。JSON 和 XML 使用 JAXB 注释的“bean”类很容易。我只是让text/plain工作,但我希望 Jersey 更智能一点,并且能够将我的 bean 列表转换为List<Machine>使用toString.

Here is the Resource class. The JSON and XML media types use a JAXB annotated bean class. The text plain uses a custom string format (basically the stdout representation of a command).

这是资源类。JSON 和 XML 媒体类型使用 JAXB 注释 bean 类。纯文本使用自定义字符串格式(基本上是命令的标准输出表示)。

@Path("/machines")
public class MachineResource {
    private final MachineManager manager;

    @Inject
    public MachineResource(MachineManager manager) {
        this.manager = manager;
    }

    @GET @Path("details/")
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    public List<Machine> details() {
        return manager.details();
    }
    @GET @Path("details/")
    @Produces({ MediaType.TEXT_PLAIN })
    public String detailsText() {
        StringBuilder text = new StringBuilder();       
        for(Machine machine : manager.details()) {
            text.append(machine.toString());
        }
        return text.toString();
    }

Is there a better way to do this with Jersey automatically converting to a string, so I only have to implement one method here?(That can handle all 3 media types)

有没有更好的方法可以让 Jersey 自动转换为字符串,所以我只需要在这里实现一个方法?(可以处理所有 3 种媒体类型)

I see that I can implement a MessageBodyWriter, but that seems like a lot more trouble.

我看到我可以实现MessageBodyWriter,但这似乎更麻烦。

EDIT:

编辑:

If it matters, I am using the embedded Jetty and Jersey options.

如果重要的话,我正在使用嵌入式 Jetty 和 Jersey 选项。

Thanks!

谢谢!

采纳答案by bdoughan

Implementing a MessageBodyReader/Writerwould be what you need to do in order to do the following:

实现MessageBodyReader/Writer将是您需要做的,以便执行以下操作:

@GET @Path("details/")
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN })
public List<Machine> details() {
    return manager.details();
}

It's not very much code to write, and if you are able to write it generic enough you will be able to get some re-use out of it.

要编写的代码并不多,如果您能够编写足够通用的代码,您将能够对其进行重用。

回答by Jess

1. @Provider

1.@提供者

For some reason the documentation does not mention that I need to annotate the MessageBodyWriterclass with @Provider. I have done that...

出于某种原因,文档没有提到我需要MessageBodyWriter@Provider. 我已经这样做了...

@Provider
@Produces(MediaType.TEXT_PLAIN)
public class PlainTextWriter implements MessageBodyWriter<Machine> {

... and now I see this message on start up.* (Good)

...现在我在启动时看到此消息。*(好)

INFO: Provider classes found:
  class com.blah.resources.PlainTextWriter

I still get the exception,

我仍然得到例外,

SEVERE: A message body writer for Java class java.util.ArrayList, 
and Java type java.util.List<com.blah.beans.Machine>, 
and MIME media type text/plain was not found
  • Without @Provider, you get this message on start-up: INFO: No provider classes found.
  • 如果没有@Provider,您会在启动时收到此消息: INFO: No provider classes found.

2. Use the correct type

2.使用正确的类型

The second part is that I was not implementing for the correct type. I had a Listof beans. I assumed Jersey would be smart enough to understand how to serialize a list, but I guess it could do that in different ways. Here was my second change: (Note the addition of List)

第二部分是我没有为正确的类型实现。我有一个List豆子。我认为 Jersey 足够聪明,可以理解如何序列化列表,但我想它可以以不同的方式做到这一点。这是我的第二个更改:(注意添加了List

@Provider
@Produces(MediaType.TEXT_PLAIN)
public class PlainTextWriter implements MessageBodyWriter<List<Machine>>

It is working now. It's pretty cool because now I have a generic plain/text implementation. I only have to implement the toPlainTextmethod of my interface for each Bean. No sweat!

它现在正在工作。这很酷,因为现在我有了一个通用的纯文本/文本实现。我只需要toPlainText为每个 Bean实现我的接口的方法。没有汗!

3. Use the correct package.

3. 使用正确的包装。

It broke again. Looking at the log I see this:

又断了。查看日志我看到了这个:

INFO: Scanning for root resource and provider classes in the packages:
  com.my.project.resources
...
INFO: No provider classes found.

So I refactored my MessageBodyWriter into that package and it works again!

所以我将我的 MessageBodyWriter 重构到那个包中,它又可以工作了!