I have followed the steps mentioned in https://www.baeldung.com/swagger-2-documentation-for-spring-rest-api to add swagger to a plain spring application -
I added the maven dependencies -
<!-- for swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!-- end of swagger dependency -->
I created 2 classes for configuration -
package com.luv2code.springdemo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
#Configuration
#EnableSwagger2
#EnableWebMvc
public class SpringFoxConfig {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
}
and
package com.luv2code.springdemo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
#Configuration
#EnableWebMvc
public class SpringFoxUIConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
but It is not working
I had this problem too. Add a / at the end of your url.
Like this:
http://localhost:8080/spring-rest-demo/swagger-ui/
Related
package com.crudoperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
#Controller
public class EmployeeController {
#Autowired
private EmployeeService employeeService;
#RequestMapping("/")
public String helloGfg() {
return "hii";
}
#PostMapping("/saveEmployee")
public String saveEmployee(#ModelAttribute("employee") Employee employee) {
employeeService.saveEmployee(employee);
return "redirect:/showEmployee";
}
}
debugger comes in helloGfg method but then it still showing 404 error..i think there will be some other dependency or annotaion based issues......how could i find the issue?below is my pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.crudoperation</groupId>
<artifactId>crudoperation</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>crudoperation Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring.version>5.1.0.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>javax.servlet.jsp.jstl-api</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.11.RELEASE</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper</artifactId>
<version>8.5.51</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.17.Final</version>
</dependency>
</dependencies>
<build>
<finalName>crudoperation</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
how to find from where the error is coming..in maven project in webapp directory when i seperately run as run on server then it did not even find seprate file..how to solve it?
this is my project structure..which thing i need to remove.i cannot understand.
here is the code for viewResolver
package com.crudoperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Description;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.crudoperation")
public class EmployeeAppConfig implements WebMvcConfigurer {
#Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setViewClass(JstlView.class);
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
#Bean
public SpringResourceTemplateResolver templateResolver() {
// SpringResourceTemplateResolver automatically integrates with Spring's own
// resource resolution infrastructure, which is highly recommended.
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(this.applicationContext);
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
// HTML is the default value, added here for the sake of clarity.
templateResolver.setTemplateMode(TemplateMode.HTML);
// Template cache is true by default. Set to false if you want
// templates to be automatically updated when modified.
templateResolver.setCacheable(true);
return templateResolver;
}
public void addResourceHandlers(ResourceHandlerRegistry resourceHandlerRegistry) {
resourceHandlerRegistry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
}
Try to define in webapp folder a hii.html file. helloGfg is returning hii but the resource with such name is missing.
Now that you have both the ViewResolver in place, you can add/set Order to them. Try,
templateResolver.setOrder(0); //or lower value
first I have to add
package com.crudoperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Description;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.thymeleaf.spring3.SpringTemplateEngine;
import org.thymeleaf.spring3.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring3.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = "com.crudoperation")
#Qualifier(value = "EmployeeAppConfig")
public class EmployeeAppConfig implements WebMvcConfigurer {
#Autowired
ApplicationContext applicationContext;
#Override
public void addResourceHandlers(ResourceHandlerRegistry resourceHandlerRegistry) {
resourceHandlerRegistry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
#Bean
public ClassLoaderTemplateResolver yourTemplateResolver() {
ClassLoaderTemplateResolver configurer = new ClassLoaderTemplateResolver();
configurer.setPrefix("/WEB-INF/views/");
configurer.setSuffix(".html");
configurer.setCharacterEncoding("UTF-8");
configurer.setOrder(0); // this is important. This way spring //boot will listen to both places 0 and 1
configurer.setCacheable(false);
return configurer;
}
#Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver srtr = new SpringResourceTemplateResolver();
srtr.setApplicationContext(applicationContext);
srtr.setPrefix("/WEB-INF/views/");
srtr.setSuffix(".html");
return srtr;
}
#Bean
#Description("Thymeleaf template engine with Spring integration")
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
return templateEngine;
}
#Bean
#Description("Thymeleaf view resolver")
public ViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
viewResolver.setCharacterEncoding("UTF-8");
return viewResolver;
}
}
so that path can be found
When trying to access the Swagger documentation, I face this error:
Whitelabel Error Page This application has no explicit mapping for
/error, so you are seeing this as a fallback.
Wed Sep 23 09:38:17 BRT 2020 There was an unexpected error (type=Not
Found, status=404). No message available
I don't know what can be...
pom.xml:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
</dependency>
Class configuration:
package com.simulacao.api.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket bancoApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.simulacao.api"))
.paths(PathSelectors.regex("/*.*"))
.build()
.apiInfo(metaInfo());
}
private ApiInfo metaInfo() {
return new ApiInfoBuilder()
.title("API Rest")
.description("\"API Rest\"")
.version("1.0.0")
.license("Apache License Version 2.0")
.licenseUrl("https://www.apache.org/licenses/LICENSE-2.0\"")
.build();
}
}
Controller:
#RestController
#RequestMapping(value = "/api/customer")
#Api(value = "API Rest Customer")
#CrossOrigin(origins = "*")
public class CustomerController {
#Autowired
private CustomerService customerService;
#Autowired
private AccountService accountService;
#Autowired
private CustomerRepository customerRepository;
#GetMapping
#ApiOperation(value = "Returns a list of customers")
public ResponseEntity<List<Customer>> showAll() {
return ResponseEntity.ok(this.customerService.findAll());
}
Please add those configs
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//Swagger UI property
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
This must be declareted in the config of implementation with "WebMvcConfigurer".
More information here : https://springfox.github.io/springfox/docs/current/
For Spring Boot with SpringFox 3 all you need is following:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
and /swagger-ui.html is now /swagger-ui/index.html or /swagger-ui. From doc
swagger-ui location has moved from http://host/context-path/swagger-ui.html to http://host/context-path/swagger-ui/index.html OR http://host/context-path/swagger-ui/ for short
I am trying to add custom information about the API. I added custom information but its not working. I am getting old information. can any one please tell me why I am not getting custom information? http://localhost:8086/swagger-ui.html
Here I added my dependency and swagger configuration file
Dependency
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
<scope>compile</scope>
</dependency>
SwaggerConfig.java
package com.spacestudy.config;
import static springfox.documentation.builders.PathSelectors.regex;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
#Configuration
#EnableSwagger2
public class SwaggerConfig {
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(metaData())
.select()
.apis(RequestHandlerSelectors.basePackage("com.spacestudy.controller"))
.paths(regex("/api.spacestudy.com"))
.build();
}
private ApiInfo metaData() {
Contact contact = new Contact("XYZ", "XYZ.com", XYZ#gmail.com);
return new ApiInfoBuilder()
.title("Spring Boot REST API")
.description("Spring Boot REST API for Space Study")
.version("1.0.0")
.license("Apache 2.0")
.contact(contact)
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0")
.build();
}
}
I am looking for help on implementing swagger in my spring MVC rest api. I tried googling but so much confusion that I am not able to understand. I am not using spring boot.
Changes to Configuration class
package com.sample.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
/**
* #author EOV537 -
* #since 1.0
*/
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {"com.sample"})
public class ApplicationConfig extends WebMvcConfigurerAdapter {
private static final String VIEW_RESOLVER_PREFIX = "/WEB-INF/jsp/";
private static final String VIEW_RESOLVER_SUFFIX = ".jsp";
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
// viewResolver.setViewClass(InternalResourceViewResolver.class); // NOSONAR
viewResolver.setPrefix(VIEW_RESOLVER_PREFIX);
viewResolver.setSuffix(VIEW_RESOLVER_SUFFIX);
return viewResolver;
}
}
WebApplint
package com.sample.config;
import javax.annotation.PreDestroy;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextCleanupListener;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
/**
* #author EOV537 -
* #since 1.0
*/
public class WebApplint implements WebApplicationInitializer {
/*
* (non-Javadoc)
*
* #see org.springframework.web.WebApplicationInitializer#onStartup(javax.servlet.ServletContext)
*/
private AnnotationConfigWebApplicationContext rootContext = null;
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
System.setProperty("spring.profiles.active", "web");
// Create the 'root' Spring application context
rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(ApplicationConfig.class, SwaggerConfig.class);
// Manages the lifecycle
servletContext.addListener(new ContextLoaderListener(rootContext));
servletContext.addListener(new ContextCleanupListener());
ServletRegistration.Dynamic springWebMvc = servletContext.addServlet("DispatcherServlet",
new DispatcherServlet(rootContext));
springWebMvc.setLoadOnStartup(1);
springWebMvc.addMapping("/");
springWebMvc.setAsyncSupported(true);
}
#PreDestroy
protected final void cleanup() {
if (rootContext != null) {
rootContext.close();
}
}
}
SwaggerConfig.java
package com.sample.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* #author EOV537 -
* #since 1.0
*/
#Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).select().apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any()).build();
}
private ApiInfo apiInfo() {
ApiInfo apiInfo = new ApiInfo("My REST API", "Some custom description of API.", "API Blog web",
"Terms of service", "myeaddress#company.com", "License of API", "API license URL");
return apiInfo;
}
}
Add following 2 dependencies in pom.xml
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.3.0</version>
</dependency>
Access Swagger using
http://localhost:8082/rest-service/swagger-ui.html#/
I am trying to do a simple cache of data but everytime I test it. It never seems to cache the data.
package app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
#EnableAutoConfiguration
#SpringBootApplication
#EnableCaching
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("getUserInfo");
}
}
package app.cache;
import app.repo.User.User;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
#Service
public class UserService {
private User userInfo;
#CacheEvict("getUserInfo")
public void setUserInfo(User userInfo) {
this.userInfo = userInfo;
}
#Cacheable("getUserInfo")
public User getUserInfo() {
return userInfo;
}
}
package app.controllers;
import app.cache.UserService;
import app.repo.User.Player;
import app.repo.User.User;
import app.repo.User.UserRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
#RestController
public class UserController {
#Autowired
private UserService userCache;
#RequestMapping("/test-user-cache")
#ResponseBody
public User testUserCache() {
if(userCache.getUserInfo() != null) {
return userCache.getUserInfo();
}
User user = new User("joejoe","wordpass");
user.setId(44444444);
userCache.setUserInfo(user);
return userCache.getUserInfo();
}
}
Dependencies
...
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.apache.directory.server</groupId>
<artifactId>apacheds-server-jndi</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
</dependencies>
...
It doesnt seem to save the data when I try to save it. And when I do a request again, no data is never cached.
You get that behavior because the cache works. The data is saved, but null is already cached: if(userCache.getUserInfo()
In order to clear the cache when you set the value you can annotate the setUserInfo Method with #CacheEvict(cacheNames="books", allEntries=true).