问题
I have generated Apache CXF JAX-RS REST api server side code using Swagger 2.0 specification thus created with CXF version 3.1.8 dependencies. I want to understand what is the next step in order to get a REST application server running(standalone Jetty or Spring Boot or Tomcat). I am specifically looking for maven dependencies involved + configurations I need to add. I found it difficult to gather the correct details from available documentation as is it brief.
I tried following the CXF samples but keep running into issues for eg:
Mar 07, 2017 4:57:53 PM org.apache.cxf.jaxrs.utils.JAXRSUtils readFromMessageBody
WARNING: No message body reader has been found for request class ABC, ContentType : application/json.
Mar 07, 2017 4:57:53 PM org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper toResponse
WARNING: WebApplicationException has been caught : no cause is available
I am finding it difficult to understand the dependencies because of involvement of Swagger. The sample code works fine but not with the one generated with Swagger, when I use it, it gives above exception.
I want to understand the next steps and would appreciate if anyone who has done it with Swagger can help.
Thanks!
回答1:
No message body reader has been found
Generally occurs when you have not registered providers.
@Bean
public JacksonJsonProvider jacksonJsonProvider(){
return new JacksonJsonProvider();
}
Here is complete Spring boot configuration for CXF with Swagger2.
Updated Pom.xml with CXF related dependency
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxrs</artifactId>
<version>3.1.10</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.8.7</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.1.1-1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-service-description</artifactId>
<version>3.1.10</version>
</dependency>
<dependency>
<groupId>org.webjars.bower</groupId>
<artifactId>angular-swagger-ui</artifactId>
<version>0.4.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7</version>
</dependency>
<dependency>
<groupId>org.webjars.bower</groupId>
<artifactId>bootstrap-less-only</artifactId>
<version>3.3.6</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-service-description-swagger</artifactId>
<version>3.1.10</version>
</dependency>
Note: Since I'm using angular-swagger-ui added additional dependency
Configure CXF Beans.
@Configuration
public class CxfConfig {
@Bean
public Swagger2Feature swagger2Feature(){
Swagger2Feature feature = new Swagger2Feature();
feature.setPrettyPrint(true);
feature.setUsePathBasedConfig(true);
feature.setScan(false);
feature.setBasePath("/swagger");
return feature;
}
@Bean
public JacksonJsonProvider jacksonJsonProvider(){
return new JacksonJsonProvider();
}
}
Enable cxf component auto scan in application.properties
cxf.jaxrs.component-scan=true
Create html file apidoc.html
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
<link rel="stylesheet" href="/webjars/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet"
href="/webjars/angular-swagger-ui/dist/css/swagger-ui.min.css">
<script src="/webjars/angular/angular.min.js"></script>
<script src="/webjars/angular-swagger-ui/dist/scripts/swagger-ui.min.js"></script>
<script src="/webjars/angular-sanitize/angular-sanitize.min.js"></script>
<script src="/webjars/jquery/jquery.min.js"></script>
<script src="/webjars/bootstrap/js/bootstrap.min.js"></script>
<script src="js/cxf.js"></script>
</head>
<body ng-app="cxfApp" ng-controller="cxfCtrl" >
<div swagger-ui url="cxfUrl" api-explorer="true" validator-url="false"></div>
</body>
</html>
Enable angular-swggaer in cxf.js
angular.module('cxfApp', ['ngSanitize', 'swaggerUi']).controller("cxfCtrl", function($scope) {
$scope.cxfUrl = '/services/swagger.json';
})
Now on starting spring-boot application. Verify the following.
http://localhost:8080/services?_wadl
For WADL file
http://localhost:8080/services/swagger.json
For Swagger JSON File
http://localhost:8080/.html
For angular-swagger-ui
回答2:
Spring boot application
@ComponentScan("com.example")
@EnableAutoConfiguration(exclude={MongoAutoConfiguration.class})
@SpringBootApplication
public class SpringBootCXFServer {
@Autowired
private Bus bus;
public static void main(String[] args) {
SpringApplication.run(SpringBootCXFServer.class, args);
}
@Bean
public Server rsServer() {
JAXRSServerFactoryBean endpoint = new JAXRSServerFactoryBean();
endpoint.setBus(bus);
endpoint.setServiceBeans(
Arrays.<Object>asList(new DevicesLoggersApiServiceImpl(), new DevicesLoggersEntriesApiServiceImpl()));
endpoint.setAddress("/services/");
endpoint.setFeatures(Arrays.asList(new Swagger2Feature()));
return endpoint.create();
}
@Bean
@ConditionalOnMissingBean
public JacksonJsonProvider jsonProvider(ObjectMapper objectMapper) {
JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider();
provider.setMapper(objectMapper);
return provider;
}
}
And pom.xml:
<!-- Inherit defaults from Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.8.RELEASE</version>
</parent>
<!-- <dependencyManagement> <dependencies> <dependency> Import dependency
management from Spring Boot <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId>
<version>1.5.2.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency>
</dependencies> </dependencyManagement> -->
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.9.1</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>src/gen/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<!-- build WAR file -->
<!-- <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.1.1</version>
<configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration>
</plugin> -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<configuration>
<mainClass>com.example.Main</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>1.3.8.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.all.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/jul-to-slf4j <dependency>
<groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> <version>${slf4j.all.version}</version>
</dependency> -->
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j-impl -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jaxrs</artifactId>
<scope>compile</scope>
<version>${swagger-core-version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit-version}</version>
<scope>test</scope>
</dependency>
<!-- Bean Validation API support -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>${beanvalidation-version}</version>
<scope>provided</scope>
</dependency>
<!-- CXF Client -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-client</artifactId>
<version>${cxf-version}</version>
<scope>test</scope>
</dependency>
<!-- CXF server -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>${cxf-version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-service-description</artifactId>
<version>${cxf-version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-service-description-swagger</artifactId>
<version>${cxf-version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-policy</artifactId>
<version>${cxf-version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-wsdl</artifactId>
<version>${cxf-version}</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider -->
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.8.7</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxrs</artifactId>
<version>3.1.10</version>
</dependency>
</dependencies>
来源:https://stackoverflow.com/questions/42654231/apache-cxf-jax-rs-server-generated-from-api-spec-using-swagger-2-0-what-do-i-ne