Swagger is not showing any controllers or endpoints - java

Swagger Api Docs Image
I am working on adding / integrating swagger in my springboot project. I have tried different things but its not got fixed. All that is showing now is white page without any endpoints or controllers and just an empty page with swagger logo.
Swagger URL is : http://localhost:8080/swagger-ui.html
My swagger configurations are given below:
package com.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
#SpringBootApplication(scanBasePackages = {"com.app.controller"})
public class StoreApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
try {
SpringApplication.run(StoreApplication.class, args);
}catch (Throwable throwable){
System.out.println(throwable.toString());
throwable.printStackTrace();
}
}
}
Here is my controller code.
My Controller
package com.app.controller;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
#CrossOrigin
#RestController
public class CustomersController {
#RequestMapping(value = "/customers", method = RequestMethod.GET)
ResponseEntity<?> getAllCustomers(){
return ResponseEntity.status(HttpStatus.OK).body(null);
}
#RequestMapping(value = "/customer", method = RequestMethod.POST)
ResponseEntity<?> createCustomer(){
return ResponseEntity.status(HttpStatus.OK).body(null);
}
}
Here is the main class
Main Class
package com.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
#SpringBootApplication(scanBasePackages = {"com.app.controller"})
public class StoreApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
try {
SpringApplication.run(StoreApplication.class, args);
}catch (Throwable throwable){
System.out.println(throwable.toString());
throwable.printStackTrace();
}
}
}
This is my app config file
AppConfig
package com.app.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#Configuration
public class AppConfig implements WebMvcConfigurer {
#Override
public void addViewControllers(ViewControllerRegistry registry){
// registry.addRedirectViewController("/docApi/v2/api-docs","/v2/api-docs");
registry.addViewController("/welcome").setViewName("Welcome");
}
}

First, try to add swagger config like this:
#EnableSwagger2
#Configuration
public class SwaggerConfig {
#Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.app"))
.paths(PathSelectors.any())
.build();
}
}
then add some annotation in your controller like this:
package com.app.controller;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
#CrossOrigin
#RestController
#Api
public class CustomersController {
#RequestMapping(value = "/customers", method = RequestMethod.GET)
#ApiOperation(value = "get all", tags = "customer")
ResponseEntity<?> getAllCustomers(){
return ResponseEntity.status(HttpStatus.OK).body(null);
}
#RequestMapping(value = "/customer", method = RequestMethod.POST)
#ApiOperation(value = "create", tags = "customer")
ResponseEntity<?> createCustomer(){
return ResponseEntity.status(HttpStatus.OK).body(null);
}
}
hope this would fix your problem. Then try to access the url: http://127.0.0.1:8080/swagger-ui/index.html, pay attention not the url http://localhost:8080/swagger-ui.html.

Related

One controller can be reached but others cannot

Main Application Class: (It was going to be using JSP but realized the trouble with Spring Boot):
package com.MBS.Consulting.jsp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Configuration;
#Configuration
#SpringBootApplication(scanBasePackages="com.MBS.Consulting.jsp")
public class SampleWebJspApplication extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(SampleWebJspApplication.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(SampleWebJspApplication.class, args);
}
}
WelcomeController - In sub folder of main class (this controller is accessible):
package com.MBS.Consulting.jsp.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
#Controller
public class WelcomeController {
#GetMapping("/")
public String index() {
return "static/index";
}
#GetMapping("/Home")
public String welcome() {
return "Welcome/welcome";
}
#GetMapping("/ContactUs")
public String contactUs() {
return"Welcome/contact_Us";
}
#GetMapping("/AboutUs")
public String aboutUs() {
return "Welcome/about_us";
}
}
CustomerController - Does not even show that it is called with AOP. The package name is the same as the last controller. I do need to login using Spring Security to reach this page. It allows me to login and then gives me 404.
package com.MBS.Consulting.jsp.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import com.MBS.Consulting.jsp.entity.Customers;
import com.MBS.Consulting.jsp.entity.Users;
import com.MBS.Consulting.jsp.services.CustomersService;
#Controller
#RequestMapping("/Customer")
public class CustomerController {
#Autowired
private CustomersService customerService;
#GetMapping("/Home")
public String customerHome() {
return "Customer/Customer_Home";
}
}
Security config:
Not sure if I really need this or not but added it just to make sure that it couldn't be causing the problem.
package com.MBS.Consulting.jsp.config;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
#Configuration
#EnableWebSecurity
public class DemoSecurityConfig {
// add a reference to our security data source
#Autowired
#Qualifier("securityDataSource")
private DataSource securityDataSource;
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((auth) -> {
try {
auth
.antMatchers("/Admin/**").hasRole("ADMIN")
.antMatchers("/Billing/**").hasAnyRole("ADMIN", "CUSTOMER", "EMPLOYEE")
.antMatchers("/Contacts/**").hasAnyRole("ADMIN", "EMPLOYEE")
.antMatchers("/Customer/**").hasAnyRole("ADMIN", "CUSTOMER")
.antMatchers("/Order/**").hasAnyRole("ADMIN", "CUSTOMER", "EMPLOYEE")
.antMatchers("/Plan/**").hasAnyRole("ADMIN", "CUSTOMER", "EMPLOYEE")
.antMatchers("/Services/**").hasAnyRole("ADMIN", "CUSTOMER", "EMPLOYEE")
.antMatchers("/Welcome", "/Login").permitAll()
.and()
.formLogin()
.and()
.logout()
.permitAll()
.and()
.exceptionHandling()
.accessDeniedPage("/access-denied");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
)
.httpBasic();
return http.build();
}
}
Project structure:
I hope the image shows up due just to show the project structure and that I believe the controllers are in the correct location to not be a problem for Spring Boot.
In the logs for console I get no information at all when visit CustomerController, but I do get a 404 Error. The web address I visit is http://localhost:8080/Customer/Home to try to call CustomerController. I am unsure what will cause this and if someone could explain what I did wrong.
I did search on it and I was going to try and configure the dispatcher servlet but it should of been auto configured. I believe if it reaching one it should be able to reach the other if it is the same folder. Also I understand the it needs to be in the sub folder of the main class. Finally I checked to see if it was the mapped right since I used folders in the template folder.
While mappings were correct and the project structure is correct it was unable to reach controllers due to spring security. The security FilterChain in the screen shot is missing two asterisks on the permit all controllers.
this:
.antMatchers("/","/Welcome", "/Login").permitAll()
should be:
.antMatchers("/**","/Welcome/**", "/Login/**").permitAll()

Swagger + Spring boot doesn't show API end points in http://localhost:8080/home/swagger-ui.html

I have a spring boot application runs on jetty + swagger
and I don't see any end point specification when i go to http://localhost:8080/home/swagger-ui.html (see attachment) even do I wrote a controller and have an endpoint there.
my Application code is:
package com.MyService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
#SpringBootApplication
#EnableSwagger2
public class MyServiceApplication {
public static void main(String[] args) {
SpringApplication.run(GcmAuthenticationServiceApplication.class, args);
}
}
in pom.xml I use:
<!-- Swagger 2.0 support -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
my controller:
package com.MyService.controller;
import com.MyService.model.RegistrationData;
import io.swagger.annotations.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.validation.Valid;
#Api(value = "register", description = "the registration API")
public interface RegistrationApi {
#ApiOperation(value = "Register user", nickname = "register", notes = "", authorizations = {
#Authorization(value = "petstore_auth", scopes = {
#AuthorizationScope(scope = "write:pets", description = "modify pets in your account"),
#AuthorizationScope(scope = "read:pets", description = "read your pets")
})
}, tags={ "register", })
#ApiResponses(value = {
#ApiResponse(code = 405, message = "Invalid input") })
#RequestMapping(value = "/register",
produces = { "application/json", "application/xml" },
consumes = { "application/json", "application/xml" },
method = RequestMethod.POST)
default ResponseEntity<Void> registerUser(#ApiParam(value = "Pet object that needs to be added to the store" ,required=true )
#Valid #RequestBody RegistrationData body) {
return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
}
}
------
package com.MyService.controller;
import com.MyService.model.RegistrationData;
import com.MyService.service.RegistrationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping("/api/v1")
public class RegistrationController implements RegistrationApi{
private RegistrationService registrationService;
#Autowired
public void setProductService(RegistrationService registrationService) {
this.registrationService = registrationService;
}
#RequestMapping(value = "/register", method = RequestMethod.POST)
public ResponseEntity registerUser(#RequestBody RegistrationData registrationData){
//todo call service to rgeister
return new ResponseEntity("user register successfully", HttpStatus.OK);
}
}
my SwaggerConfig:
package com.MyService.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import static springfox.documentation.builders.PathSelectors.regex;
#Configuration
#EnableSwagger2
public class Swagger2Config extends WebMvcConfigurationSupport {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select().apis(RequestHandlerSelectors.basePackage("guru.springframework.controllers"))
.paths(regex("/product.*")).build();
}
#Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
my swagger documentation look as the following:
You can use the below with a change to your existing code. The base package must point to your controller base package and the URL context should be among the one's which you have added in the controller.
Modified base package to "com.MyService.controller" and added "/api/v1" & "/register" to the paths regex,
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.basePackage("com.MyService.controller"))
.paths(regex("(/api/v1.*)|(/register.*)")).build();
}
You are allowed to show /product.* URLs but In your endpoint, there don't have any URL match with /product.*. that's why it doesn't show any endpoint.
change your code like below
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select().apis(RequestHandlerSelectors.basePackage("guru.springframework.controllers"))
.paths(or(regex("/register.*"),regex("/api/v1.*"))).build();
}
you can allow all endpoints using regex("/.*").

Resolved [org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present]

I am getting the error
"Resolved[org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present]"
I tried all the options provided on previous posts it didn't work please tell me what I am doing wrong this is my first spring-boot application.
My controller
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import java.io.File;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
#RestController
public class SpringBootJdbcController {
#Autowired
JdbcTemplate jdbc;
#Autowired
private SpringBootJdbcService springBootJdbcService;
#RequestMapping("/insert")
public String index() {
jdbc.execute("insert into user(name,email)values('javatpoint','java#javatpoint.com')");
return "data inserted Successfully";
}
#CrossOrigin(origins = "http://localhost:4200")
#ResponseStatus(HttpStatus.OK)
#RequestMapping(value = "/uploadFile", method = RequestMethod.POST, consumes = "multipart/form-data")
public void uploadFiles(#RequestParam("file") MultipartFile file) throws Exception {
System.out.println("hello hello hello");
System.out.println("file---------" + file);
springBootJdbcService.readConfigData(file);
}
}
My Application.properties
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=11MB
api call postman image :-
I don't understand what is the problem. Its my first spring-boot application please help.

Issue with responseEntity . MockMvc.Perform() gives 200 status code even if the ResponseEntity.HttpStatus is 201

Im trying to mock a controller's post method. I want it to return status code 201(CREATED) . But it gives Status Code 200.
Given below is the code
This is my controller Class
package com.example.demo;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
public #RestController
class SomeController{
#PostMapping("/insertString")
public ResponseEntity<String> insertString(String str) {
return new ResponseEntity<>(new String("monster"),HttpStatus.CREATED);
}
}
This is my junit test Suit
package com.example.demo;
import static org.junit.Assert.*;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.mockito.Mockito.anyString;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
#RunWith(SpringRunner.class)
#WebMvcTest(SomeController.class)
public class TestClass {
#Autowired
private MockMvc mockMvc;
#MockBean
private SomeController someController;
#Test
public void test() throws Exception {
ResponseEntity<String> entity = new ResponseEntity<>(HttpStatus.CREATED);
when(someController.insertString(anyString())).thenReturn(entity);
RequestBuilder requestBuilder = MockMvcRequestBuilders
.post("/insertString")
.accept(MediaType.APPLICATION_JSON)
.content("monkey")
.contentType(MediaType.APPLICATION_JSON);
MvcResult result = mockMvc.perform(requestBuilder)
.andExpect(status().isCreated())
.andReturn();
System.out.println(result.getResponse().getContentAsString());
}
}
The errorim getting is
java.lang.AssertionErrror:Status expected:<201> but was:<200>
Though i have mentioned the status as HttpStatus.CREATED in the RequestEntity object, Why am i getting 200.
Please if someone can help
Try to change
public ResponseEntity<String> insertString(String str)
to
public ResponseEntity<String> insertString(#RequestBody String str)
I've run the test with above code and it passed.

Spring MVC - HTTP Status 404

When I try to go to link http://localhost:8080/ I get "HTTP Status 404", I use Tomcat 7.0.47, and I get the following error : The requested resource is not available.
WebConfig.Java
package 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;
#EnableWebMvc
#Configuration
#ComponentScan
public class WebConfig extends WebMvcConfigurerAdapter{
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/static/js/**")
.addResourceLocations("/resources/static/js/");
registry.addResourceHandler("/resources/static/css/**")
.addResourceLocations("/resources/static/css/");
registry.addResourceHandler("/resources/static/views/**")
.addResourceLocations("/resources/static/views/");
registry.addResourceHandler("/resources/static/**")
.addResourceLocations("/resources/static/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("/webjars/");
}
#Bean
public ViewResolver getViewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
return resolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
WebAppInitalizer.Java
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
public class WebAppInitializer implements WebApplicationInitializer {
private static final String CONFIG_LOCATION = "config";
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
System.out.println("***** Initializing Application for " + servletContext.getServerInfo() + " *****");
// Create ApplicationContext
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
applicationContext.setConfigLocation(CONFIG_LOCATION);
// Add the servlet mapping manually and make it initialize automatically
DispatcherServlet dispatcherServlet = new DispatcherServlet(applicationContext);
ServletRegistration.Dynamic servlet = servletContext.addServlet("mvc-dispatcher", dispatcherServlet);
servlet.addMapping("/");
servlet.setAsyncSupported(true);
servlet.setLoadOnStartup(1);
}
}
MainController.Java
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
public class MainController {
#RequestMapping("/")
public String homepage(){
return "homepage";
}
}
My project has the following structure :
try to add this #AnnotationDrivenConfig on top of WebConfig and change this #ComponentScan with this #ComponentScan("controller")
Try to add some text into your requestMapping example:
#RequestMapping("/homePage")
and then go to http://localhost:8080/homePage

Categories