我对swagger并不陌生,我正尝试将swagger-ui与我的Jersey实现的JaxRS Web服务与嵌入式Tomcat集成。
根据我的代码,我不确定使用哪个URL可以访问swagger-ui。
我尝试使用URL http://localhost:8085/ws_webservice_with_embedded_tomcat/api,但收到“ HTTP状态404 –找不到”错误。
这是我完整的代码。
pom.xml依赖项
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>8.5.53</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>2.28</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<!-- swagger dependency-->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jaxrs</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-core</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>swagger-ui</artifactId>
<version>3.25.0</version>
</dependency>
<!-- logging dependency-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>webservice.embedded.tomcat.App</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Customer.java
package webservice.embedded.tomcat.model;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "customer")
public class Customer
{
private int id;
private String firstName;
private String lastName;
private String street;
private String city;
private String state;
private String zip;
private String country;
@XmlAttribute
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
@XmlElement
public String getFirstName()
{
return firstName;
}
public void setFirstName(String firstName)
{
this.firstName = firstName;
}
@XmlElement
public String getLastName()
{
return lastName;
}
public void setLastName(String lastName)
{
this.lastName = lastName;
}
@XmlElement
public String getStreet()
{
return street;
}
public void setStreet(String street)
{
this.street = street;
}
@XmlElement
public String getCity()
{
return city;
}
public void setCity(String city)
{
this.city = city;
}
@XmlElement
public String getState()
{
return state;
}
public void setState(String state)
{
this.state = state;
}
@XmlElement
public String getZip()
{
return zip;
}
public void setZip(String zip)
{
this.zip = zip;
}
@XmlElement
public String getCountry()
{
return country;
}
public void setCountry(String country)
{
this.country = country;
}
@Override
public String toString()
{
return "Customer{" +
"id=" + id +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", street='" + street + '\'' +
", city='" + city + '\'' +
", state='" + state + '\'' +
", zip='" + zip + '\'' +
", country='" + country + '\'' +
'}';
}
}
CustomerService.java
package webservice.embedded.tomcat.services;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import webservice.embedded.tomcat.model.Customer;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
@Path("/customers")
@Api(value = "/customers", tags = "Services for Customer management")
public class CustomerService {
Logger logger = LoggerFactory.getLogger(CustomerService.class);
private static Map<Integer, Customer> customerDB = new ConcurrentHashMap<>();
private static AtomicInteger idCounter = new AtomicInteger();
public CustomerService() {
}
@GET
@Produces(MediaType.TEXT_PLAIN)
@ApiOperation(
value = "Hello World",
response = String.class,
produces = "application/text",
httpMethod = "GET"
)
@ApiResponses(value =
{
@ApiResponse(code = 200, message = "Hello World Success", response = Customer.class),
@ApiResponse(code = 400, message = "Hello World Failure", response = WebApplicationException.class)
})
public String sayHello() {
return "Hello World ! Welcome to webservices using embedded tomcat.";
}
@GET
@Path("{id}")
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@ApiOperation(
value = "Get customer with specific id",
response = Response.class
)
@ApiResponses(value =
{
@ApiResponse(code = 200, message = "Customer request success", response = Customer.class),
@ApiResponse(code = 400, message = "Bad Request for customer", response = WebApplicationException.class)
})
public Response getCustomer(@PathParam("id") int id) {
Response response;
ResponseBuilder responseBuilder = Response.ok();
Customer customer = customerDB.get(id);
if (customer == null) {
response = responseBuilder.status(Status.NOT_FOUND).build();
} else {
response = responseBuilder.status(Status.FOUND).entity(customer).build();
}
return response;
}
@POST
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@ApiOperation(
value = "Create customers",
response = Response.class
)
@ApiResponses(value =
{
@ApiResponse(code = 200, message = "Customer created successfully", response = Customer.class),
@ApiResponse(code = 400, message = "Bad Request for customer create", response = WebApplicationException.class)
})
public Response createCustomer(List<Customer> customers) {
try {
for (Customer customer : customers) {
customer.setId(idCounter.incrementAndGet());
customerDB.put(customer.getId(), customer);
logger.info("Created customer with id : {}", customer.getId());
}
} catch (Exception ex) {
throw new WebApplicationException(Status.BAD_REQUEST);
}
return Response.ok().status(Status.CREATED).build();
}
@PUT
@Path("{id}")
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
@ApiOperation(
value = "Update Customer",
response = Response.class
)
@ApiResponses(value =
{
@ApiResponse(code = 200, message = "Customer updated successfully", response = Customer.class),
@ApiResponse(code = 400, message = "Bad Request for customer update", response = WebApplicationException.class)
})
public Response updateCustomer(@PathParam("id") int id, Customer customer) {
Customer current = customerDB.get(id);
if (current == null) {
throw new WebApplicationException(Status.NOT_FOUND);
}
current.setFirstName(customer.getFirstName());
current.setLastName(customer.getLastName());
current.setStreet(customer.getStreet());
current.setCity(customer.getCity());
current.setState(customer.getState());
current.setZip(customer.getZip());
current.setCountry(customer.getCountry());
URI uri = URI.create("/customers/" + id);
ResponseBuilder responseBuilder = Response.created(uri);
return responseBuilder.build();
}
@DELETE
@Path("{id}")
@ApiOperation(
value = "Delete Customer",
response = Response.class
)
@ApiResponses(value =
{
@ApiResponse(code = 200, message = "Customer deleted successfully", response = Customer.class),
@ApiResponse(code = 400, message = "Bad Request for customer delete", response = WebApplicationException.class)
})
public Response deleteCustomer(@PathParam("id") int id) {
Response response;
ResponseBuilder responseBuilder = Response.ok();
Customer deletedCustomer = customerDB.remove(id);
if (deletedCustomer == null) {
responseBuilder.status(Status.BAD_REQUEST);
} else {
logger.info("Deleted customer with id : {}", id);
responseBuilder.status(Status.CREATED);
}
response = responseBuilder.build();
return response;
}
}
SwaggerJaxRSConfig.java
package webservice.embedded.tomcat.config;
import io.swagger.jaxrs.config.BeanConfig;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
public class SwaggerJaxRSConfig extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
BeanConfig beanConfig = new BeanConfig();
beanConfig.setTitle("Customer Management Service");
beanConfig.setVersion("1.0.0");
beanConfig.setSchemes(new String[]{"http"});
beanConfig.setHost("localhost:8085");
beanConfig.setBasePath(config.getServletContext().getContextPath() + "/api");
beanConfig.setResourcePackage("webservice.embedded.tomcat.services");
beanConfig.setScan(true);
}
}
App.java
package webservice.embedded.tomcat;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Wrapper;
import org.apache.catalina.startup.Tomcat;
import java.io.File;
public class App {
public static void main(String[] args) throws LifecycleException {
Tomcat tomcat = new Tomcat();
int port = 8085;
tomcat.setPort(port);
Context ctx = tomcat.addContext("/ws_webservice_with_embedded_tomcat", new File(".").getAbsolutePath());
Wrapper tomcatServletWrapper = Tomcat.addServlet(ctx, "Jersey_WebService_Servlet", "org.glassfish.jersey.servlet.ServletContainer");
ctx.addServletMappingDecoded("/*", "Jersey_WebService_Servlet");
tomcatServletWrapper.addInitParameter("jersey.config.server.provider.packages", "webservice.embedded.tomcat.services,io.swagger.jaxrs.listing");
Wrapper swaggerServletWrapper = Tomcat.addServlet(ctx, "Swagger_Servlet", "webservice.embedded.tomcat.config.SwaggerJaxRSConfig");
swaggerServletWrapper.setLoadOnStartup(1);
tomcat.start();
tomcat.getServer().await();
}
}
注意:如果我通过邮递员发送任何GET / POST / PUT / DELETE请求,我的Web服务(CustomerService.java)可以正常工作。
但是我无法启动swagger UI来执行相同的操作。
快速解决方案受到高度赞赏。
您在这404个代码上取得了成功吗?swagger-ui是一个webjars库,但是看起来Tomcat + Jersey不支持webjars注入。也可能是相同的原因,例如Support WebJars directly in Jersey