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 控制器時,你仍然可以發現許多選項,這些選項將通過使用更多註釋及其屬性來幫助你在文件級別。