swagger-ui with jersey REST WS
正如 Swagger 的官方网站所说:
扬鞭是定义一个标准,语言无关的接口,REST API 的功能,这使人类和计算机发现和理解服务的能力,而无需访问源代码,文档,或通过网络流量检测。通过 Swagger 正确定义时,使用者可以使用最少量的实现逻辑来理解远程服务并与之交互。与低级编程的接口类似,Swagger 消除了调用服务时的猜测。
假设你使用 Maven 和球衣,你会需要以下依赖加入: Maven 的依赖扬鞭与 JAX-RS 的依赖性一起。现在你必须创建 maven webapp
,在 webapp 下你需要粘贴这个 URL上的内容。在项目中粘贴这些内容后,webapp 的文件夹结构应如下所示:
之后,按照以下步骤操作:
- 创建一个带有任何名称的 java 文件(在我们的例子中是“
ApiOriginFilter.java
”),类似于下面的内容:
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ApiOriginFilter implements javax.servlet.Filter {
/**
* doFilter
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
res.addHeader("Access-Control-Allow-Origin", "*");
res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
res.addHeader("Access-Control-Allow-Headers", "Content-Type, api_key, Authorization");
chain.doFilter(request, response);
}
/**
* destroy
*/
@Override
public void destroy() {
}
/**
* init
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}
此文件将确保过滤类中提供的传入请求。
- 在我们的例子中创建一个任何名称的 java 文件,其名称为“
SwaggerJaxrsConfig.java
”,如下所示:
import org.eclipse.persistence.jaxb.MarshallerProperties;
import org.eclipse.persistence.jaxb.BeanValidationMode;
import org.glassfish.jersey.moxy.json.MoxyJsonConfig;
import org.glassfish.jersey.moxy.json.MoxyJsonFeature;
import org.glassfish.jersey.moxy.xml.MoxyXmlFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.ServerProperties;
import org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature;
import io.swagger.jaxrs.config.BeanConfig;
public class SwaggerJaxrsConfig extends ResourceConfig {
public SwaggerJaxrsConfig() {
BeanConfig beanConfig = new BeanConfig();
beanConfig.setTitle("Swagger API Title");
beanConfig.setVersion("1.0.0");
beanConfig.setSchemes(new String[] { "http" });
beanConfig.setHost("localhost:8080/swagger-ui");
beanConfig.setBasePath("/rest");
beanConfig.setResourcePackage(
"your.restws.package");
beanConfig.setScan(true);
property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, Boolean.TRUE);
packages("your.restws.package");
packages("io.swagger.jaxrs.listing");
register(MoxyJsonFeature.class);
// register(BadRequestExceptionMapper.class);
register(new MoxyJsonConfig().setFormattedOutput(true)
// Turn off BV otherwise the entities on server would be validated by MOXy as well.
.property(MarshallerProperties.BEAN_VALIDATION_MODE, BeanValidationMode.NONE).resolver());
register(MoxyXmlFeature.class);
register(RolesAllowedDynamicFeature.class);
}
}
正如你所看到的,在上面的类中,我们提供了使用 swagger UI 所需的所有详细信息,例如 Host 将托管这个 swagger 项目,以及设置你选择的基本路径以及支持的所有 http 协议,如“http
”或“https
”以及根据你的要求提供的更多细节。还可以让 Swagger 了解你所有 REST WS 的位置,可以使用 setResourcePackage
和包来设置这个类使我们可以使用 Swagger UI 和我们的自定义。
现在在 web.xml 中输入以上 2 个文件,以便在服务器上部署我们的应用程序之后使用它们,如下所示:
<servlet>
<servlet-name>jersey-servlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>your.package.SwaggerJaxrsConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>ApiOriginFilter</filter-name>
<filter-class>your.package.ApiOriginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ApiOriginFilter</filter-name>
<url-pattern>/rest/*</url-pattern>
</filter-mapping>
现在,我们将转到实际代码,我们将使用 Swagger 提供的 Annotations:
创建一个 bean Employee.java,如下所示:
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel("Employee bean")
public class Employee {
private String name;
private String id;
private String dept;
@ApiModelProperty(value = "Name of employee", example = "Test Employee")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@ApiModelProperty(value = "Id of employee", example = "123456")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@ApiModelProperty(value = "Department of employee", example = "IT Division", allowableValues = "IT, Sales, Admin")
public String getDept() {
return dept;
}
public void setDept(String dept) {
this.dept = dept;
}
}
我们在这里使用的 Swagger 的组件是:
@ApiModel("Employee bean")
- 这将决定需要在 Swagger UI 上显示的 Bean 类的名称。@ApiModelProperty(value ="ABC", example="DeptName")
- 这将提供 bean 中使用的每个字段的信息。value 提供字段的描述,example 提供该字段的样本值。
现在我们将按如下方式创建一个 REST 控制器,以创建一个 GET Web 服务,如下所示:
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.swagger.ws.bean.Employee;
import org.swagger.ws.service.EmployeeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
@Path("/employee")
@Api(tags = {"Employee"})
public class EmployeeController {
private static final Logger LOGGER = LoggerFactory.getLogger(EmployeeController.class);
@GET
@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
@ApiOperation(produces="application/json", value = "Fetch employee details", httpMethod="GET", notes = "<br>This service fetches Employee details", response = Employee.class)
@ApiResponses(value = { @ApiResponse(code = 200,response = Employee.class, message = "Successful operation"),@ApiResponse(code = 400, message = "Bad Request", response = Error.class), @ApiResponse(code = 422, message = "Invalid data", response = Error.class), @ApiResponse(code = 500, message = "Internal Server Error", response = Error.class) })
public Response getEmployee() {
EmployeeService employeeService = new EmployeeService();
Employee empDetails = employeeService.getEmployee();
Response response;
LOGGER.debug("Fetching employee");
GenericEntity<Employee> entity = new GenericEntity<Employee>(empDetails){};
response = Response.status(200).entity(entity).build();
return response;
}
}
我们在这里使用的 Swagger 的组件是:
@Api(tags = {"Employee"})
- 这个注释将告诉 Swagger 什么应该是 Web 服务的标题。在这种情况下,标题是“Employee
”。请注意,编写 REST WS 时几乎没有标准,而写标题的 Swagger 文档不应该像“GetEmployee
”或“DeleteEmployee
”等。@ApiOperation(produces="application/json", value = "Fetch employee details", httpMethod="GET", notes = "<br>This service fetches Employee details", response = Employee.class)
- 此注释提供有关你的 Web 服务的简要概念。produces
描述了响应的格式,value
描述了关于 webservice 的简要概念notes
描述了有关此 Web 服务的详细信息。
@ApiResponses(value = { @ApiResponse(code = 200,response = Employee.class, message = "Successful operation"),@ApiResponse(code = 400, message = "Bad Request", response = Error.class), @ApiResponse(code = 422, message = "Invalid data", response = Error.class), @ApiResponse(code = 500, message = "Internal Server Error", response = Error.class) })
- 这个注释为我们提供了一种处理不同类型的HTTP
状态代码的方法,这些代码可以在使用此 Web 服务时作为响应接收。它允许我们设置错误代码,针对它的自定义消息,甚至允许我们在单独的错误类中捕获该错误(如果需要)。
最后,我们必须创建实际的 Service 类,它将在客户端使用 Web 服务时获取员工的详细信息。你可以根据需要实施它。以下是演示目的的示例服务:
public class EmployeeService {
public Employee getEmployee() {
Employee employee = new Employee();
employee.setId("1");
employee.setName("Test");
employee.setDept("IT");
return employee;
}
}
现在你已准备好在 Swagger UI 上查看文档。部署 Swagger 项目并启动服务器。现在转到浏览器并点击项目的 URL。在这种情况下它
如果正确配置了 swagger,那么你应该能够看到以下屏幕:
现在,要查看你的 webservice 文档在文本框( http://exampl.com/api)中提供项目的“base_url / rest / swagger.json”,你可以在上面的图像中看到。在文本框中提供该 URL 后,你可以看到以下屏幕提供 REST Web 服务的文档:
在上面的图像中写入“api key
”的文本框,如果你的项目要求基于用户 ID 等认证,你可以提供特定的标题或键值。为此,你还需要在以 <input placeholder="api_key" ......
开头的标签下的 index.html 中进行更改
Swagger-UI 的另一个好处是,它提供了一个按钮“Try it out!
”。使用此按钮可以查看此 Web 服务的响应。对于这种情况,如果我们点击该按钮,它将在屏幕上给出以下响应:
这是 Swagger UI 的示例演示。在编写 REST 控制器时,你仍然可以发现许多选项,这些选项将通过使用更多注释及其属性来帮助你在文档级别。