【发布时间】:2017-01-29 16:59:09
【问题描述】:
我有一个要求,需要将版本放在请求 URI 中以访问相应的服务。 例如:如果路径类似于:localhost:8080/context-root/rest/v1/company
然后可以使用以下 URL 访问此服务: 本地主机:8080/context-root/rest/v1/company localhost:8080/context-root/rest/company
为了在休息服务过滤器中实现这一点,我添加了 v1,以防第二个 URL 被命中。 当我将 jersey 1.8 与 servlet com.sun.jersey.spi.spring.container.servlet.SpringServlet 一起使用时,它工作正常
但是当我将 jersey 2.4 与 servlet org.glassfish.jersey.servlet.ServletContainer 一起使用时,它无法正常工作,因为没有 /rest/company 的路径,它无法完全命中过滤器。 v1 被添加到过滤器中。
我在想是否可以点击部分 URL(最多 /rest),在过滤器中我将更改请求 url 以获得正确的路径。
工作 web.xml:
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>
com.sun.jersey.spi.spring.container.servlet.SpringServlet
</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.abc.ws.rest</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>com.abc.filters.RestServiceFilter</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
web.xml 不工作
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.abc.ws.rest</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>com.abc.filter.RestServiceFilter</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
即使 /rest/company URL 被击中,工作的一个正在点击过滤器类,而不工作的一个不会为相同的 url 击中过滤器
REST 端点类:
@Path("/v1/company")
public class CompanyRestService {
}
更新 pom.xml
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.4.1</version>
<exclusions>
<exclusion>
<groupId>org.glassfish.hk2.external</groupId>
<artifactId>asm-all-repackaged</artifactId>
</exclusion>
<exclusion>
<groupId>org.glassfish.hk2.external</groupId>
<artifactId>cglib</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.4.1</version>
</dependency>
RestServiceFilter 代码:
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import org.apache.commons.lang.math.NumberUtils;
public class RestServiceFilter implements ContainerRequestFilter {
private static Logger _logger = Logger.getLogger(RestServiceFilter.class.getName());
@Override
public void filter(ContainerRequestContext crc) {
_logger.info("***** REST FILTER*********************");
crc = updateURLForVersion(crc);
}
private ContainerRequestContext updateURLForVersion(ContainerRequestContext cr) {
String baseURI = cr.getUriInfo().getBaseUri().toString();
String requestURI = cr.getUriInfo().getRequestUri().toString();
String pathURI = requestURI.substring(baseURI.length(), requestURI.length());
String version = null;
if (pathURI.startsWith("v") && pathURI.contains("/")) {
String versionInURL = pathURI.substring(1, pathURI.indexOf("/"));
if (NumberUtils.isNumber(versionInURL)) {
version = "v" + versionInURL;
}
}
if (StringUtil.isNullOrEmpty(version)) {
version = ConfigReader.getinstance().get(Constants.REST_LATEST_VERSION);
pathURI = version + "/" + pathURI;
requestURI = baseURI + pathURI;
try {
cr.getUriInfo().getRequestUriBuilder().replacePath(requestURI);
// cr.setRequestUri(new URI(requestURI));
} catch (Exception ex) {
ex.printStackTrace();
Logger.getLogger(RestServiceFilter.class.getName()).log(Level.SEVERE, null, ex);
}
}
return cr;
}
【问题讨论】:
-
我们能看到代码吗?
-
代码请参考原帖
-
如果我记得,你不需要使用带有 jersey 2 的 web.xml,你必须创建一个继承 ResourceConfig 的类
-
您的参数名称错误。请使用 javax.ws.rs.Application 而不是 jersey.config.server.provider.packages