rest
在某些情况下,您可能想快速验证部署在开发,测试或生产环境中的REST API是否完全可以访问。 一种常见的实现方法是构建通用资源,该资源可提供例如已部署API的版本。 您可以手动触发对此资源的请求,或者更好的是,拥有一个Jenkings / Hudson作业,该作业在部署后运行检查作业。 在本文中,我将介绍如何实现从应用程序清单文件中读取实现细节的服务。 经过验证的API是本教程中开发的API –借助Jersey和Spring在Java中进行REST API设计和实现
使用的软件
- 泽西岛JAX-RS实现2.14
- Spring4.1.4
- Maven 3.1.1
- JDK 7
REST资源
我开发了两个从清单文件读取的REST资源:
- / manifest –将清单的主要属性作为键,值对返回
- / manifest / implementation-details –仅返回清单文件中的实现详细信息
清单REST资源
@Path("/manifest")
public class ManifestResource {
@Autowired
ManifestService manifestService;
@GET
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response getManifestAttributes() throws FileNotFoundException, IOException{
Attributes manifestAttributes = manifestService.getManifestAttributes();
return Response.status(Response.Status.OK)
.entity(manifestAttributes)
.build();
}
@Path("/implementation-details")
@GET
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response getVersion() throws FileNotFoundException, IOException{
ImplementationDetails implementationVersion = manifestService.getImplementationVersion();
return Response.status(Response.Status.OK)
.entity(implementationVersion)
.build();
}
}
请求
GET请求示例–实施细节
GET http://localhost:8888/demo-rest-jersey-spring/manifest HTTP/1.1
Accept-Encoding: gzip,deflate
Accept: application/json
Host: localhost:8888
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
回应– 200 OK
JSON格式的回应
{
"Implementation-Title": "DemoRestWS",
"Implementation-Version": "0.0.1-SNAPSHOT",
"Implementation-Vendor-Id": "org.codingpedia",
"Built-By": "ama",
"Build-Jdk": "1.7.0_40",
"Manifest-Version": "1.0",
"Created-By": "Apache Maven 3.1.1",
"Specification-Title": "DemoRestWS",
"Specification-Version": "0.0.1-SNAPSHOT"
}
如果成功返回的值(HTTP状态200 OK)包含与实现和规范详细信息有关的不同默认数据。 这些是使用Maven插件自动生成的清单文件,我将在下一部分中介绍。
用Maven生成清单文件
由于该演示应用程序是一个Web应用程序,因此我正在使用Apache Maven Archiver支持的Apache maven war插件来生成清单文件:
maven-war-plugin配置
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.5</version>
<configuration>
<warName>${project.artifactId}</warName>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>manifest</goal>
</goals>
<inherited>true</inherited>
</execution>
</executions>
</plugin>
从pom.xml文件中定义的项目属性中,addDefaultImplementationEntries和addDefaultSpecificationEntries将分别生成默认实现和规范详细信息:
默认实施细节
Implementation-Title: ${project.name}
Implementation-Version: ${project.version}
Implementation-Vendor-Id: ${project.groupId}
Implementation-Vendor: ${project.organization.name}
Implementation-URL: ${project.url}
, 分别:
默认规格详细信息
Specification-Title: ${project.name}
Specification-Version: ${project.version}
Specification-Vendor: ${project.organization.name}
有关更多详细信息,请参见Apache Maven Archiver 。
请注意,为了也在文件系统中的webapp / META-INF下生成Manifest.mf文件,您需要将清单目标绑定到执行阶段(例如,包):
将清单目标绑定到打包阶段
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>manifest</goal>
</goals>
<inherited>true</inherited>
</execution>
</executions>
从清单文件读取
从清单文件读取发生在注入的ManifestService类中:
ManifestService.java
public class ManifestService {
@Autowired
ServletContext context;
Attributes getManifestAttributes() throws FileNotFoundException, IOException{
InputStream resourceAsStream = context.getResourceAsStream("/META-INF/MANIFEST.MF");
Manifest mf = new Manifest();
mf.read(resourceAsStream);
Attributes atts = mf.getMainAttributes();
return atts;
}
ImplementationDetails getImplementationVersion() throws FileNotFoundException, IOException{
String appServerHome = context.getRealPath("/");
File manifestFile = new File(appServerHome, "META-INF/MANIFEST.MF");
Manifest mf = new Manifest();
mf.read(new FileInputStream(manifestFile));
Attributes atts = mf.getMainAttributes();
ImplementationDetails response = new ImplementationDetails();
response.setImplementationTitle(atts.getValue("Implementation-Title"));
response.setImplementationVersion(atts.getValue("Implementation-Version"));
response.setImplementationVendorId(atts.getValue("Implementation-Vendor-Id"));
return response;
}
}
要访问MANIFEST.MF文件,您需要注入ServletContext并调用其方法之一。
- SerlvetContext#getResourceAsStream() –(首选方式)
- ServletContext#getRealPath() –获取与给定虚拟路径相对应的真实路径。 返回的实际路径将采用适合运行servlet容器的计算机和操作系统的形式,包括适当的路径分隔符。 在这种情况下,最大的问题是,如果不部署.war爆炸,则将无法访问清单文件。
Java EE版本
在JavaEE环境中,您可以通过@Context批注注入ServletContext:
Java EE实施版本
public class ManifestResource {
@Context
ServletContext context;
@GET
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response getManifestAttributes() throws FileNotFoundException, IOException{
InputStream resourceAsStream = context.getResourceAsStream("/META-INF/MANIFEST.MF");
Manifest mf = new Manifest();
mf.read(resourceAsStream);
Attributes atts = mf.getMainAttributes();
return Response.status(Response.Status.OK)
.entity(atts)
.build();
}
...
}
在这里,您可以找到一种快速的方法来验证REST api是否可以访问。
资源资源
- 阿帕奇Maven
- Oracle文档– 处理清单文件:基础知识
- 堆栈溢出
rest