I have made the below pom.xml entry:
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jaxrs</artifactId>
<version>1.5.0</version>
</dependency>
and created a servlet:
public class SwaggerJaxrsConfig extends HttpServlet {
#Override
public void init(ServletConfig servletConfig) {
try {
super.init(servletConfig);
BeanConfig beanConfig = new BeanConfig();
beanConfig.setVersion("1.0.2");
beanConfig.setSchemes(new String[]{"http"});
beanConfig.setHost("localhost:8080");
beanConfig.setBasePath("/api");
beanConfig.setResourcePackage("com.mypackage.resource");
beanConfig.setScan(true);
} catch (ServletException e) {
System.out.println(e.getMessage());
}
}
}
and added this in web.xml: (I could have skipped web.xml by adding it but I am still usign sevlet 2.5 for some reason
#WebServlet(name = "SwaggerJaxrsConfig", loadOnStartup = 1)
<servlet>
<servlet-name>SwaggerJaxrsConfig</servlet-name>
<servlet-class>com.SwaggerJaxrsConfig</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
I can see the below lines in the log: [org.reflections.Reflections] Reflections took 332 ms to scan 2 urls, producing 250 keys and 1186 values
but then I am getting 404 on http://localhost:8080/api
Do you know what am I doing wrong?
It did not work for me either. So I used following in stead of httpservlet and then it started working
<servlet>
<servlet-name>Jersey2Config</servlet-name>
<servlet-class>io.swagger.jersey.config.JerseyJaxrsConfig</servlet-class>
<init-param>
<param-name>api.version</param-name>
<param-value>1.0.0</param-value>
</init-param>
<init-param>
<param-name>swagger.api.basepath</param-name>
<param-value>http://localhost:8080/api</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
Refer to following link for more details on how i implemented
https://github.com/sanketsw/jax_rs_REST_Example
Related
Is there any way to configure Jackson (ConfiguredObjectMapper) which is used for serializing servlet responses?
#Api(name = "rates",
version = "v1",
title = "Rates API")
public class RatesApi {
static Logger LOG = Logger.getLogger(RatesApi.class.getSimpleName());
#ApiMethod(name = "getLatestRates",
path = "latest",
httpMethod = HttpMethod.GET)
public RatesEnvelope getLatestRates(#Named("base") String base) throws BadRequestException,
InternalServerErrorException {
try {
RatesInfo ratesInfo = DatabaseUtils.getLatestRates(base);
return new RatesEnvelope(ratesInfo.getDate(), base, ratesInfo.getTimestamp(), ratesInfo.getRates());
} catch (IllegalArgumentException e) {
throw new BadRequestException(e.getMessage());
} catch (com.googlecode.objectify.NotFoundException e) {
throw new InternalServerErrorException("no available rates");
}
}
}
My problem is RatesEnvelope class contains BigDecimal fields which should be configured with mapper.enable(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN); to avoid E notation.
web.xml
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<servlet>
<servlet-name>CurrencyWebserviceServlet</servlet-name>
<servlet-class>PACKAGE_NAME.backend.servlet.OpenExchangeRatesWebserviceServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet>
<servlet-name>SystemServiceServlet</servlet-name>
<servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class>
<init-param>
<param-name>services</param-name>
<param-value>PACKAGE_NAME.backend.spi.RatesApi</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>CurrencyWebserviceServlet</servlet-name>
<url-pattern>/cron/fetchlatest</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>SystemServiceServlet</servlet-name>
<url-pattern>/_ah/spi/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<security-constraint>
<web-resource-collection>
<web-resource-name>all</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<filter>
<filter-name>ObjectifyFilter</filter-name>
<filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ObjectifyFilter</filter-name>
<url-pattern>/*</url-pattern>
<!-- Next three lines are for request dispatcher actions -->
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
</web-app>
Create an instance of Jackson ObjectMapper. Configure as needed by enabling or disabling features you need. Modify your Spring configuration to use it instead of default one. Java configuration would look something like this:
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN);
converter.setObjectMapper(objectMapper);
converters.add(converter);
super.configureMessageConverters(converters);
}
It looks like you're using Cloud Endpoints Frameworks, which doesn't use Jackson annotations. In your case, you'd use an ApiTransformer to achieve what you want. As an example:
#ApiTransformer(RatesEnvelopeTransformer.class)
public class RatesEnvelope {
private BigDecimal someBigDecimalField;
// ...
}
public class RatesEnvelopeTransformer implements Transformer<BigDecimal, String> {
public String transformTo(BigDecimal in) {
return in.toPlainString();
}
public BigDecimal transformFrom(String in) {
return new BigDecimal(in);
}
}
I am following the swagger tutorial to swaggerize my web application.
. I am using package scanning and Swagger's BeanConfig for swagger initialization. Is there a way to disable swagger in specific environment (e.g. production)? There are some discussion talking about disabling swagger with SpringMVC
Here is my web.xml
<servlet>
<servlet-name>jersey</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>
io.swagger.jaxrs.listing,
com.expedia.ord.ops.rest
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Hooking up Swagger-Core in your application -->
<servlet>
<servlet-name>SwaggerServlet</servlet-name>
<servlet-class>com.expedia.ord.ops.util.SwaggerServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>SwaggerUI</servlet-name>
<jsp-file>/SwaggerUI/index.html</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>SwaggerUI</servlet-name>
<url-pattern>/api/docs/*</url-pattern>
</servlet-mapping>
Here is my Swagger servlet:
public class SwaggerServlet extends HttpServlet
{
static private final String[] SCHEMES = {"http"};
#Value("${swagger.enable}")
private boolean enableSwagger;
#Value("${swagger.resource.package}")
private String resourcePackage;
#Value("${swagger.host}")
private String host;
#Value("${swagger.basePath}")
private String basePath;
#Value("${swagger.api.version}")
private String version;
#Override
public void init(final ServletConfig config) throws ServletException
{
super.init(config);
SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, config.getServletContext());
final BeanConfig beanConfig = new BeanConfig();
beanConfig.setVersion(version);
beanConfig.setSchemes(SCHEMES);
beanConfig.setHost(host);
beanConfig.setBasePath(basePath);
beanConfig.setResourcePackage(resourcePackage);
beanConfig.setScan(enableSwagger);
}
}
I'm trying to use API documentation using Swagger for my 'org.jboss.resteasy' Rest service. After configuration I can access 'http://localhost:8080/myrestswagger/rest/swagger.json' correctly.
it returns following:
{
"swagger": "2.0",
"info": {
"version": "3.0.0",
"title": ""
},
"host": "localhost:8080",
"basePath": "/myrestswagger/rest",
"schemes": [
"http"
]
}
But I cannot access or generate any data on 'http://localhost:8080/myrestswagger/rest/api-docs', please see my classes.
Rest Service Class :
#Path("/countryDetails")
#Api( value = "/countryDetails", description = "countryDetails" )
public class CountryController {
#Path("/countries")
#GET
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
#ApiOperation(value = "GetCountries", httpMethod = "GET", notes = "Get Countries against Specific URL", response = Country.class)
public List<Country> getCountries() {
List<Country> listOfCountries = new ArrayList<Country>();
listOfCountries = createCountryList();
return listOfCountries;
}
#Path("/country/{id}")
#GET
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Country getCountryById(#PathParam("id") int id) {
List<Country> listOfCountries = new ArrayList<Country>();
listOfCountries = createCountryList();
for (Country country : listOfCountries) {
if (country.getId() == id) return country;
}
return null;
}
private List<Country> createCountryList() {
Country indiaCountry = new Country(1, "India");
Country chinaCountry = new Country(4, "China");
Country nepalCountry = new Country(3, "Nepal");
Country bhutanCountry = new Country(2, "Bhutan");
List<Country> listOfCountries = new ArrayList<Country>();
listOfCountries.add(indiaCountry);
listOfCountries.add(chinaCountry);
listOfCountries.add(nepalCountry);
listOfCountries.add(bhutanCountry);
return listOfCountries;
}
}
This is the web.xml
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<listener>
<listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>
<servlet>
<servlet-name>Resteasy</servlet-name>
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Resteasy</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>io.undertow.servlet.handlers.DefaultServlet</servlet-class>
<init-param>
<param-name>allowed-extensions</param-name>
<param-value>js, css, png, jpg, gif, html, htm, txt, pdf, jpeg, xml, zip, jar</param-value>
</init-param>
<init-param>
<param-name>disallowed-extensions</param-name>
<param-value>class, war</param-value>
</init-param>
</servlet>
<context-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>/rest</param-value>
</context-param>
<!--While using Spring integration set resteasy.scan to false or don't configure resteasy.scan parameter at all -->
<context-param>
<param-name>resteasy.scan</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>resteasy.providers</param-name>
<param-value>
io.swagger.jaxrs.listing.ApiListingResource,
io.swagger.jaxrs.listing.SwaggerSerializers
</param-value>
</context-param>
<servlet>
<servlet-name>Jersey2Config</servlet-name>
<servlet-class>io.swagger.jaxrs.config.DefaultJaxrsConfig</servlet-class>
<init-param>
<param-name>api.version</param-name>
<param-value>3.0.0</param-value>
</init-param>
<init-param>
<param-name>swagger.api.basepath</param-name>
<param-value>http://localhost:8080/myrestswagger/rest</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
This is my pom.xml dependancy (maven.project)
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jaxrs</artifactId>
<version>1.5.9</version>
</dependency>
You don't need both swagger.json and api-docs. Both are common names to describe the Swagger definition from your server, which can be used--as a URL--by Swagger UI to render an interactive view of the API.
From looking at the output of your swagger.json, it looks like you're not scanning your resources. Please see about adding your CountryController to the scanning path for the API.
I am trying to create and Rest API with Spring MVC that consumes JSON:
Controller:
#RestController public class CrawlerController {
#RequestMapping(value = "/checkForMarfeelizableSite", method = RequestMethod.POST)
public ResponseR checkForMarfeelizableSites(#RequestBody List<Entry> list) {
// Response
ResponseR responseR = new ResponseR();
responseR.setOperationResult(OperationResult.OK);
for (Entry entry : list) {
System.out.println("Entry: " + entry);
}
return responseR;
} }
Entry.class
public class Entry {
String url;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}}
web.xml:
<web-app>
<display-name>Marfeel Marfeelizable Checker</display-name>
<!-- Spring Context -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/marfeel-context.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!-- Servlet -->
<servlet>
<servlet-name>marfeel-crawler-api</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Mapping -->
<servlet-mapping>
<servlet-name>marfeel-crawler-api</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- Welcome file List -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
I've added the Jackson lib (jackson-mapper-asl) in my pom.xml, but I'm receiving a HTTP 415 Error
This is a sample of json that I'm sending:
[{"url": "canda.com"},{"url": "toshiba.es"}]
could you check the followings?
Change
public ResponseR checkForMarfeelizableSites(#RequestBody List
list)
to
public ResponseR checkForMarfeelizableSites(#RequestBody
ArrayList list)
(since List is an interface and therefore cannot create an instance).
Entry.class: add #XmlRootElement above the class name,and an empty contractor (required for web exportable classes)
I am studying springmvc. When I use #RequestMapping(value="/helloWorld", headers = "content-type=text/*") and connect to http://localhost:8080/SpringMVC_10100/helloWorld, the following is output in the console:
WARN
org.springframework.web.servlet.PageNotFound
- No matching handler method found for servlet request: path '/helloWorld',
method 'GET', parameters
map[[empty]]
My code is:
#Controller
public class HelloWordController {
private Logger logger = LoggerFactory.getLogger(HelloWordController.class);
#RequestMapping(value="/helloWorld", headers = "content-type=text/*")
public ModelAndView helloWorld() {
logger.debug("jin ru le");
logger.info("The helloWorld() method is use");
ModelAndView view = new ModelAndView();
view.setViewName("/helloworld");
return view;
}
}
web.xml is
<servlet>
<description>This is Spring MVC DispatcherServlet</description>
<servlet-name>SpringMVC DispatchServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<description>SpringContext</description>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC DispatchServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Why?
Its most likely the case that /helloworld is not inside the path configured for your dispatcher servlet
e.g. If i have a servlet configured like so:
<servlet>
<servlet-name>BMA</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>BMA</servlet-name>
<url-pattern>/bma/*</url-pattern>
</servlet-mapping>
And i have a controller configured like so:
#RequestMapping(value = "/planner/plan/{planId}/delete", method = RequestMethod.GET)
public ModelAndView deletePlanConfirm(HttpServletRequest request,
#PathVariable("planId") Long planId) {}
Then the request in browsder would be:
http://localhost:8080/bma/planner/plan/1223/delete
Edit:
Also if you have content-type header narrowing on your handler, make sure that content-type haeder is sent in your request.
In the below annotation remove the headers:
#RequestMapping(value="/helloWorld", headers = "content-type=text/*")
to:
#RequestMapping(value="/helloWorld", method = RequestMethod.GET)
or to:
#RequestMapping(value="/helloWorld")
should make it work.