gpt4 book ai didi

java - 如何在子资源 @Path 没有前导斜杠的情况下创建 JAX-RS 服务

转载 作者:搜寻专家 更新时间:2023-10-31 19:31:27 25 4
gpt4 key购买 nike

我创建了一个 JAX-RS 服务 (MyService),它有许多子资源,每个子资源都是 MySubResource 的子类。所选择的子资源类是根据 MyService 路径中给定的参数选择的,例如:

@Path("/") @Provides({"text/html", "text/xml"}) 
public class MyResource {
@Path("people/{id}") public MySubResource getPeople(@PathParam("id") String id) {
return new MyPeopleSubResource(id);
}
@Path("places/{id}") public MySubResource getPlaces(@PathParam("id") String id) {
return new MyPlacesSubResource(id);
}
}

其中 MyPlacesSubResource 和 MyPeopleSubResource 都是 MySubResource 的子类。

MySubResource 定义为:

public abstract class MySubResource {
protected abstract Results getResults();

@GET public Results get() { return getResults(); }

@GET @Path("xml")
public Response getXml() {
return Response.ok(getResults(), MediaType.TEXT_XML_TYPE).build();
}

@GET @Path("html")
public Response getHtml() {
return Response.ok(getResults(), MediaType.TEXT_HTML_TYPE).build();
}
}

结果由相应的 MessageBodyWriters 处理,具体取决于响应的 mimetype。

虽然这行得通,但它会产生像/people/Bob/html 或/people/Bob/xml 这样的路径,而我真正想要的是/people/Bob.html 或/people/Bob.xml

有人知道如何完成我想做的事情吗?

最佳答案

老话题,但这是我最近使用 Jersey 解决的问题;也许它会对其他人有所帮助。

Jersey 支持通过使用请求过滤器将接受的内容类型指定为 URI 中的文件扩展名。 Jersey 用品UriConnegFilter (URI 内容协商过滤器)您扩展以将特定扩展转换为内容类型的对象。然后将该过滤器作为初始参数包含在 Jersey 应用程序中。

因为这听起来很模糊,下面是我项目中的一个具体示例:

我希望能够将 URL 末尾的“.json”和“.xml”解释为客户端分别需要 JSON 格式或 XML 格式的内容。为此,我像这样扩展了 UriConnegFilter:

package my.filter.package;

import com.sun.jersey.api.container.filter.UriConnegFilter;

import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.core.MediaType;


public class MediaTypeFilter extends UriConnegFilter {
private static final Map<String, MediaType> mappedMediaTypes = new HashMap<String, MediaType>(2);

static {
mappedMediaTypes.put("json", MediaType.APPLICATION_JSON_TYPE);
mappedMediaTypes.put("xml", MediaType.APPLICATION_XML_TYPE);
}

public MediaTypeFilter() {
super(mappedMediaTypes);
}
}

然后,因为我将 Jersey 用作 Servlet,所以我将 MediaTypeFilter 添加到我的 web.xml 中:

<servlet>
<servlet-name>My Jersey Servlet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>my.resource.package</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>com.sun.jersey.api.container.filter.LoggingFilter;
my.filter.package.MediaTypeFilter;
com.sun.jersey.api.container.filter.PostReplaceFilter;
com.sun.jersey.api.container.filter.GZIPContentEncodingFilter</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>com.sun.jersey.api.container.filter.GZIPContentEncodingFilter;
com.sun.jersey.api.container.filter.LoggingFilter</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

有了它,Jersey 将 URI 上的扩展名转换为指定的媒体类型,然后删除扩展名。这适用于根资源和子资源,因为它在整个 URI 上运行。对于您的特定示例,/people/Bob.xml 将变为/people/Bob 并且请求中的 Accept header 将更改为“application/xml”(覆盖任何现有的 Accept header )。

第,

-彼得

关于java - 如何在子资源 @Path 没有前导斜杠的情况下创建 JAX-RS 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2644622/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com