带有Jersey JaxRS和不带web.xml的嵌入式Tomcat的Swagger-UI

问题描述 投票:0回答:1

我对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来执行相同的操作。

快速解决方案受到高度赞赏。

rest jersey jax-rs swagger-ui embedded-tomcat-8
1个回答
0
投票

您在这404个代码上取得了成功吗?swagger-ui是一个webjars库,但是看起来Tomcat + Jersey不支持webjars注入。也可能是相同的原因,例如Support WebJars directly in Jersey

© www.soinside.com 2019 - 2024. All rights reserved.