Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否存在全局基Uri工厂?_Java_Jakarta Ee_Jax Rs_Wildfly_Hateoas - Fatal编程技术网

Java 是否存在全局基Uri工厂?

Java 是否存在全局基Uri工厂?,java,jakarta-ee,jax-rs,wildfly,hateoas,Java,Jakarta Ee,Jax Rs,Wildfly,Hateoas,我需要去baseUri,我很熟悉这个 @Context UriInfo uriInfo; 我的问题是我需要一段不能注入的代码中的baseUri(实体的子对象)。我可以传递uriInfo或生成器,但这似乎并不理想,因为大多数对象都不需要知道它。最终目标是JSON响应中的HATEOAS URI,但我不需要它是JAX-RS特定的解决方案,我想如果我可以在jackson转换器或实体中获得基本URI,我可以从那里创建URIBuilder。UriInfo由JAX-RS实现和AFAIK管理,实际上,您不能将

我需要去baseUri,我很熟悉这个

@Context
UriInfo uriInfo;

我的问题是我需要一段不能注入的代码中的baseUri(实体的子对象)。我可以传递
uriInfo
或生成器,但这似乎并不理想,因为大多数对象都不需要知道它。最终目标是JSON响应中的HATEOAS URI,但我不需要它是JAX-RS特定的解决方案,我想如果我可以在jackson转换器或实体中获得基本URI,我可以从那里创建
URIBuilder

UriInfo由JAX-RS实现和AFAIK管理,实际上,您不能将它注入代码的其他地方(它不是CDIBean)。如果您的目标是实现HATEOAS,您可能会编写自己的MessageBodyWriter,它将负责将实体对象图解组到JSON响应中,并在其中插入此
UriInfo


HTH.

更新:在我写了所有这些之后的几分钟,我找到了第12章。Jersey 2.13规范中的声明性超链接。它仍在“开发和实验中”,但看起来它更优雅地解决了这个问题。原来帖子中的所有代码都可以替换为

public class Pie {

  private String name;

  Pie(String name) {
    this.name = name;
  }

  @JsonIgnore
  public String getName() {
    return name;
  }

  @InjectLink(value="pies/{name}", style=Style.ABSOLUTE)
  public URI url;
}
如果您需要向Jackson序列化程序发送任意数据,那么下面的解决方案仍然有效

原创我也有同样的问题。具体地说,我希望我的资源只包含它们的id(URI末尾的内容),并找到一种方法,仅在Jackson生成JSON时使用UriInfo生成完整的URI。我希望避免这样的解决方案,即必须为每个请求在资源上创建新的cover对象,或者在序列化每个资源之前将UriInfo插入其中

事实证明,从Jackson 2.3开始,有一种非常好的方法可以做到这一点。Jackson支持一个名为ObjectWriterInputor的类。使用其静态集合方法,您可以为每个请求提供自己的ObjectWriterModifier实例一次。该实例可以在您的Jersey资源方法中创建和设置,其中UriInfo可用。在Jackson写出JSON之前,它会调用ObjectWriterModifier,让您有机会调整它将使用的ObjectWriter。在这种情况下,可以使用withAttribute方法将UriInfo附加到ObjectWriter

那么ObjectWriter上的属性有什么好处呢?事实证明,这些属性可以通过JsonSerializer实现的serialize方法中的SerializerProvider参数获得。在我的例子中,我只想修改一个字段,所以在getter上使用@JsonSerialize。在serialize方法中,我然后调用SerializerProvider参数的getAttribute方法来检索UriInfo,然后使用它来构造完整的URI

这种方法应该适用于您希望将信息下推到Jackson序列化程序的任何情况

简单球衣资源

@Path("/pies")
public class Pies {

    static List<Pie> pies;

    static 
    {
        pies = new ArrayList<Pie>();
        pies.add(new Pie("apple"));
        pies.add(new Pie("pumpkin"));
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<Pie> getPies(@Context UriInfo uriInfo) {

        // This is the good stuff!!!!
        ObjectWriterInjector.set(new ObjectWriterPlusUriInfo(uriInfo));

        // Notice I don't have to anything to the objects in the Pies list 
        return pies;
    }
}
序列化程序

public class JacksonIdToUrlSerializer extends JsonSerializer<String>{

@Override
public void serialize(String value, JsonGenerator jgen,
        SerializerProvider provider) throws IOException,
        JsonProcessingException {

    UriInfo uriInfo = (UriInfo)provider.getAttribute("JerseyUriInfo");
    jgen.writeString(uriInfo.getRequestUriBuilder().path(value).build().toString());
    }
}
生产

[
  {
  url: "http://localhost:8080/service/api/pies/apple"
  },
  {
  url: "http://localhost:8080/service/api/pies/pumpkin"
  }
]
[
  {
  url: "http://127.0.0.1:8080/service/api/pies/apple"
  },
  {
  url: "http://127.0.0.1:8080/service/api/pies/pumpkin"
  }
]
得到

http://localhost:8080/service/api/pies...
http://127.0.0.1:8080/service/api/pies...
生产

[
  {
  url: "http://localhost:8080/service/api/pies/apple"
  },
  {
  url: "http://localhost:8080/service/api/pies/pumpkin"
  }
]
[
  {
  url: "http://127.0.0.1:8080/service/api/pies/apple"
  },
  {
  url: "http://127.0.0.1:8080/service/api/pies/pumpkin"
  }
]

请注意,ObjectWriterInjector在内部使用线程局部变量,因此使用更通用的方法在每个请求的基础上向下传递数据似乎同样有效。

MessageBodyWriter不是Jackson所做的吗?手动序列化我所有对象的每个部分听起来很不愉快,而且容易出错。即使它是一个CDIBean,也不会有帮助,因为你不能注入实体。。。我不确定是否有jax-rs级别的解决方案。。。