Red Hat Training
A Red Hat training course is available for Red Hat Fuse
第 54 章 使用 Swagger 支持扩展 JAX-RS 端点
摘要
CXF Swagger2Feature (org.apache.cxf.jaxrs.swagger.Swagger2Feature)允许您通过扩展具有简单配置的 JAX-RS 服务端点来生成 Swagger 2.0 文档。
Swagger2Feature 在 Spring Boot 和 Karaf 实现中受到支持。
54.1. Swagger2Feature 选项
您可以在 Swagger2Feature 中使用以下选项:
表 54.1. Swagger2Feature 操作
| 名称 | 描述 | 默认 |
|---|---|---|
|
|
上下文根路径+(请参阅 | null |
|
| 您的联系信息+ | |
|
| description+ | "应用程序" |
|
| 安全过滤器+ | null |
|
| 主机和端口信息+ | null |
|
|
扫描所有资源时排除特定路径(请参阅 | null |
|
| 许可证+ | "Apache 2.0 许可证" |
|
| 许可证 URL+ | |
|
|
当生成 | false |
|
| 以逗号分隔的软件包名称列表,其中资源必须扫描+ | 在端点中配置的服务类列表 |
|
| 作为过滤器运行该功能 | false |
|
| 生成 swagger 文档+ | true |
|
|
扫描包括非注解 JAX-RS 资源的所有资源(请参阅 | false |
|
| 协议方案+ | null |
|
| Swagger UI 配置 | null |
|
| 服务 URL+ 条款. | null |
|
| 标题+ | "sample REST Application" |
|
|
防止 Swagger 缓存 | false |
|
| 版本+ | "1.0.0" |
+ 选项在 Swagger 的 BeanConfig 中定义
++ 选项在 Swagger 的 ReaderConfig 中定义
=== Karaf 实施
这部分论述了如何使用在 JAR 文件中定义 REST 服务的 Swagger2Feature,并部署到 Karaf 容器上的 Fuse。
==== Quickstart 示例
您可以从 Fuse Software Downloads 页面下载 Red Hat Fuse Quickstarts。
Quickstart zip 文件包含快速入门的 /cxf/rest/ 目录,它演示了如何使用 CXF 创建 RESTful (JAX-RS) Web 服务,以及如何启用 Swagger 并注解 JAX-RS 端点。
==== 启用 Swagger
启用 Swagger 包括:
通过将 CXF 类(
org.apache.cxf.jaxrs.swagger.Swagger.Swagger2Feature )添加到 <> 定义,修改定义 CXF 服务的 XML 文件。jaxrs:server例如,请参阅 55.4 示例 XML 文件示例。
在 REST 资源类中:
为服务所需的每个注解导入 Swagger API 注解:
import io.swagger.annotations.*
其中 * =
Api,ApiOperation,ApiResponse, ApiResponse ,ApiResponses等等。详情请参阅
https://github.com/swagger-api/swagger-core/wiki/Annotations。例如,请参阅 55.5 示例资源类。
-
将 Swagger 注释添加到 JAX-RS 注释(
@PATH、@PUT、@POST、@GET、@Produces、@Consumes、@DELETE、@PathParam等等)。
例如,请参阅 55.5 示例资源类。
55.4 示例 XML 文件示例
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
xmlns:cxf="http://cxf.apache.org/blueprint/core"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0
https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://cxf.apache.org/blueprint/jaxrs
http://cxf.apache.org/schemas/blueprint/jaxrs.xsd
http://cxf.apache.org/blueprint/core
http://cxf.apache.org/schemas/blueprint/core.xsd">
<jaxrs:server id="customerService" address="/crm">
<jaxrs:serviceBeans>
<ref component-id="customerSvc"/>
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider"/>
</jaxrs:providers>
<jaxrs:features>
<bean class="org.apache.cxf.jaxrs.swagger.Swagger2Feature">
<property name="title" value="Fuse:CXF:Quickstarts - Customer Service" />
<property name="description" value="Sample REST-based Customer Service" />
<property name="version" value="${project.version}" />
</bean>
</jaxrs:features>
</jaxrs:server>
<cxf:bus>
<cxf:features>
<cxf:logging />
</cxf:features>
<cxf:properties>
<entry key="skip.default.json.provider.registration" value="true" />
</cxf:properties>
</cxf:bus>
<bean id="customerSvc" class="org.jboss.fuse.quickstarts.cxf.rest.CustomerService"/>
</blueprint>
55.5 示例资源类
.
.
.
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
.
.
.
@Path("/customerservice/")
@Api(value = "/customerservice", description = "Operations about customerservice")
public class CustomerService {
private static final Logger LOG =
LoggerFactory.getLogger(CustomerService.class);
private MessageContext jaxrsContext;
private long currentId = 123;
private Map<Long, Customer> customers = new HashMap<>();
private Map<Long, Order> orders = new HashMap<>();
public CustomerService() {
init();
}
@GET
@Path("/customers/{id}/")
@Produces("application/xml")
@ApiOperation(value = "Find Customer by ID", notes = "More notes about this
method", response = Customer.class)
@ApiResponses(value = {
@ApiResponse(code = 500, message = "Invalid ID supplied"),
@ApiResponse(code = 204, message = "Customer not found")
})
public Customer getCustomer(@ApiParam(value = "ID of Customer to fetch",
required = true) @PathParam("id") String id) {
LOG.info("Invoking getCustomer, Customer id is: {}", id);
long idNumber = Long.parseLong(id);
return customers.get(idNumber);
}
@PUT
@Path("/customers/")
@Consumes({ "application/xml", "application/json" })
@ApiOperation(value = "Update an existing Customer")
@ApiResponses(value = {
@ApiResponse(code = 500, message = "Invalid ID supplied"),
@ApiResponse(code = 204, message = "Customer not found")
})
public Response updateCustomer(@ApiParam(value = "Customer object that needs
to be updated", required = true) Customer customer) {
LOG.info("Invoking updateCustomer, Customer name is: {}", customer.getName());
Customer c = customers.get(customer.getId());
Response r;
if (c != null) {
customers.put(customer.getId(), customer);
r = Response.ok().build();
} else {
r = Response.notModified().build();
}
return r;
}
@POST
@Path("/customers/")
@Consumes({ "application/xml", "application/json" })
@ApiOperation(value = "Add a new Customer")
@ApiResponses(value = { @ApiResponse(code = 500, message = "Invalid ID
supplied"), })
public Response addCustomer(@ApiParam(value = "Customer object that needs to
be updated", required = true) Customer customer) {
LOG.info("Invoking addCustomer, Customer name is: {}", customer.getName());
customer.setId(++currentId);
customers.put(customer.getId(), customer);
if (jaxrsContext.getHttpHeaders().getMediaType().getSubtype().equals("json"))
{
return Response.ok().type("application/json").entity(customer).build();
} else {
return Response.ok().type("application/xml").entity(customer).build();
}
}
@DELETE
@Path("/customers/{id}/")
@ApiOperation(value = "Delete Customer")
@ApiResponses(value = {
@ApiResponse(code = 500, message = "Invalid ID supplied"),
@ApiResponse(code = 204, message = "Customer not found")
})
public Response deleteCustomer(@ApiParam(value = "ID of Customer to delete",
required = true) @PathParam("id") String id) {
LOG.info("Invoking deleteCustomer, Customer id is: {}", id);
long idNumber = Long.parseLong(id);
Customer c = customers.get(idNumber);
Response r;
if (c != null) {
r = Response.ok().build();
customers.remove(idNumber);
} else {
r = Response.notModified().build();
}
return r;
}
.
.
.
}
=== Spring Boot 实施
这部分论述了如何在 Spring Boot 中使用 Swagger2Feature。
==== Quickstart 示例
Quickstart 示例(https://github.com/fabric8-quickstarts/spring-boot-cxf-jaxrs)演示了如何在 Spring Boot 中使用 Apache CXF。Quickstart 使用 Spring Boot 配置一个应用程序,这些应用程序包括启用了 Swagger 的 CXF JAX-RS 端点。
==== 启用 Swagger
启用 Swagger 包括:
在 REST 应用程序中:
导入 Swagger2Feature:
import org.apache.cxf.jaxrs.swagger.Swagger2Feature;
在 CXF 端点中添加 Swagger2Feature:
endpoint.setFeatures(Arrays.asList(new Swagger2Feature()));
例如,请参阅 55.1 示例 REST 应用程序。
在 Java 实施文件中,为服务所需的每个注解导入 Swagger API 注解:
import io.swagger.annotations.*
其中 * =
Api,ApiOperation,ApiResponse, ApiResponse ,ApiResponses等等。详情请查看
https://github.com/swagger-api/swagger-core/wiki/Annotations。例如,请参阅 55.2 示例 Java 实施文件。
在 Java 文件中,将 Swagger 注释添加到 JAX-RS 注释(
@PATH、@PUT、@POST、@GET、@Produces、@Consumes、@DELETE、@PathParam等等)。例如,请参阅 55.3 示例 Java 文件。
55.1 示例 REST 应用程序
package io.fabric8.quickstarts.cxf.jaxrs;
import java.util.Arrays;
import org.apache.cxf.Bus;
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.cxf.jaxrs.swagger.Swagger2Feature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class SampleRestApplication {
@Autowired
private Bus bus;
public static void main(String[] args) {
SpringApplication.run(SampleRestApplication.class, args);
}
@Bean
public Server rsServer() {
// setup CXF-RS
JAXRSServerFactoryBean endpoint = new JAXRSServerFactoryBean();
endpoint.setBus(bus);
endpoint.setServiceBeans(Arrays.<Object>asList(new HelloServiceImpl()));
endpoint.setAddress("/");
endpoint.setFeatures(Arrays.asList(new Swagger2Feature()));
return endpoint.create();
}
}
55.2 示例 Java 实施文件
import io.swagger.annotations.Api;
@Api("/sayHello")
public class HelloServiceImpl implements HelloService {
public String welcome() {
return "Welcome to the CXF RS Spring Boot application, append /{name} to call the hello service";
}
public String sayHello(String a) {
return "Hello " + a + ", Welcome to CXF RS Spring Boot World!!!";
}
}
55.3 示例 Java 文件
package io.fabric8.quickstarts.cxf.jaxrs;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.springframework.stereotype.Service;
@Path("/sayHello")
@Service
public interface HelloService {
@GET
@Path("")
@Produces(MediaType.TEXT_PLAIN)
String welcome();
@GET
@Path("/{a}")
@Produces(MediaType.TEXT_PLAIN)
String sayHello(@PathParam("a") String a);
}