Swagger 2.0 Implementation in spring MVC rest api - java

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#/

Related

Getting "The constructor CorsFilter(UrlBasedCorsConfigurationSource) is undefined" error

While creating the object of FilterRegistrationBean in Spring Noot, I am facing the error
The constructor CorsFilter(UrlBasedCorsConfigurationSource) is undefined.
Below is the code snippet for the same.
#Bean
public FilterRegistrationBean coresFilter()
{
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowCredentials(true);
corsConfiguration.addAllowedOriginPattern("*");
corsConfiguration.addAllowedHeader("Authorization");
corsConfiguration.addAllowedHeader("Content-Type");
corsConfiguration.addAllowedHeader("Accept");
corsConfiguration.addAllowedMethod("POST");
corsConfiguration.addAllowedMethod("GET");
corsConfiguration.addAllowedMethod("DELETE");
corsConfiguration.addAllowedMethod("PUT");
corsConfiguration.addAllowedMethod("OPTIONS");
corsConfiguration.setMaxAge(3600L);
source.registerCorsConfiguration("/**", corsConfiguration);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); //getting error in this line
return bean;
}
I don't know what is going wrong here, need help.
The entire class is pasted below:
#Configuration
#EnableWebSecurity
#EnableWebMvc
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
public static final String[] PUBLIC_URLS = {
"/api/v1/auth/**",
"/v3/api-docs",
"/v2/api-docs",
"/swagger-resources/**",
"/swagger-ui/**",
"/webjars/**"
};
#Autowired
private CustomUserDetailService customUserDetailService;
#Autowired
private JwtAuthenticationEntryPoint authenticationEntryPoint;
#Autowired
private JwtAuthenticationFilter authenticationFilter;
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeHttpRequests()
.antMatchers(PUBLIC_URLS).permitAll()
.antMatchers(HttpMethod.GET).permitAll()
.anyRequest()
.authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(this.authenticationEntryPoint)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(this.authenticationFilter, UsernamePasswordAuthenticationFilter.class);
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(this.customUserDetailService).passwordEncoder(passwordEncoder());
}
#Bean
public PasswordEncoder passwordEncoder()
{
return new BCryptPasswordEncoder();
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
// TODO Auto-generated method stub
return super.authenticationManagerBean();
}
#Bean
public FilterRegistrationBean coresFilter()
{
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowCredentials(true);
corsConfiguration.addAllowedOriginPattern("*");
corsConfiguration.addAllowedHeader("Authorization");
corsConfiguration.addAllowedHeader("Content-Type");
corsConfiguration.addAllowedHeader("Accept");
corsConfiguration.addAllowedMethod("POST");
corsConfiguration.addAllowedMethod("GET");
corsConfiguration.addAllowedMethod("DELETE");
corsConfiguration.addAllowedMethod("PUT");
corsConfiguration.addAllowedMethod("OPTIONS");
corsConfiguration.setMaxAge(3600L);
source.registerCorsConfiguration("/**", corsConfiguration);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
return bean;
}
}
Here are all the import packages:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import com.springboot.blog.security.CustomUserDetailService;
import com.springboot.blog.security.JwtAuthenticationEntryPoint;
import com.springboot.blog.security.JwtAuthenticationFilter;
Because Required type is CorsConfigurationSource , but you provided UrlBasedCorsConfigurationSource . You also cannot cast in this case (I tried).
If you want create your own Filter, use like this
package com.example.security;
import org.springframework.web.filter.GenericFilterBean;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
public class CustomFilter extends GenericFilterBean {
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
chain.doFilter(request, response);
}
}
then use like this
package com.example.security;
import com.example.security.jwt.AuthEntryPointJwt;
import com.example.security.jwt.AuthTokenFilter;
import com.example.security.services.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.server.SecurityWebFilterChain;
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(
// securedEnabled = true,
// jsr250Enabled = true,
prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
UserDetailsServiceImpl userDetailsService;
#Autowired
private AuthEntryPointJwt unauthorizedHandler;
#Bean
public AuthTokenFilter authenticationJwtTokenFilter() {
return new AuthTokenFilter();
}
#Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.antMatchers("/api/test/**").permitAll()
.anyRequest().authenticated();
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
//;
// .addFilterAfter(new CustomFilter(), BasicAuthenticationFilter.class); // <-- Add filter.
}
}
Resolved:
package should be org.springframework.web.cors.UrlBasedCorsConfigurationSource and not org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource

Swagger is not showing any controllers or endpoints

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.

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("/.*").

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

Spring MVC can not find proper jsp in WEB-INF/views/ package

I am learning Spring MVC from a book called "Spring in Action". However. I am getting 404 error when I hit the correct controller. I am using annotations rather than xml configurations, so it is hard to find from web. You can see the very simple classes and configs I am using
SpittrWebInitializer.java
package spittr.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] {RootConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] {WebConfig.class};
}
#Override
protected String[] getServletMappings() {
return new String[] {"/"};
}
}
RootConfig.java
package spittr.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
#Configuration
#ComponentScan(basePackages = "spittr",
excludeFilters = #ComponentScan.Filter(type = FilterType.ANNOTATION,
value = EnableWebMvc.class))
public class RootConfig {
}
WebConfig.java
package spittr.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.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {"spittr.web"})
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
HomeController.java
package spittr.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
public class HomeController {
#RequestMapping(value = "/home", method = RequestMethod.GET)
private String home() {
return "home";
}
}
and finally under resources/WEB-INF/views/ package I have one jsp called home.jsp which is like;
<html>
<body>
<h1>Spring 4.0.2 MVC web service</h1>
<h3>Welcome!!!</h3>
</body>
</html>
The can hit the controller, so I know they are initialized without any problem, however, context is not able to find the proper jsp. I appreciate for your help. Thanks
JSP location is not correct WEB-INF location is under src/main/webapp not under resources

Categories