I have a Spring Boot 3 project which has both web pages and an API. The REST API should be open (and use API keys) and the rest of the application will be authenticated. I have a separate filter which handles the key checking.
For example, if I do not supply an API key, and I use this security config, it does not return the correct JSON error and instead forward me to the login page.
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests()
.requestMatchers("/api/**").permitAll()
.requestMatchers(EndpointRequest.to(HealthEndpoint.class)).permitAll()
.requestMatchers("/actuator/*").hasAuthority("ADMIN")
.anyRequest().authenticated()
.and().csrf().ignoringRequestMatchers("/api/**");
http.oauth2Login(withDefaults())
.logout()
.logoutUrl("/logout")
.addLogoutHandler(keycloakLogoutHandler)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout", HttpMethod.GET.name()))
.logoutSuccessUrl("/");
return http.build();
}
Here is the debug:
2023-01-23T16:47:29.600 INFO 20700 --- [2)-172.22.34.73] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-01-23T16:47:29.600 INFO 20700 --- [2)-172.22.34.73] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2023-01-23T16:47:29.600 DEBUG 20700 --- [2)-172.22.34.73] o.s.web.servlet.DispatcherServlet : Detected StandardServletMultipartResolver
2023-01-23T16:47:29.600 DEBUG 20700 --- [2)-172.22.34.73] o.s.web.servlet.DispatcherServlet : Detected AcceptHeaderLocaleResolver
2023-01-23T16:47:29.600 DEBUG 20700 --- [2)-172.22.34.73] o.s.web.servlet.DispatcherServlet : Detected FixedThemeResolver
2023-01-23T16:47:29.601 DEBUG 20700 --- [2)-172.22.34.73] o.s.web.servlet.DispatcherServlet : Detected org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator#72c0080a
2023-01-23T16:47:29.601 DEBUG 20700 --- [2)-172.22.34.73] o.s.web.servlet.DispatcherServlet : Detected org.springframework.web.servlet.support.SessionFlashMapManager#7586194b
2023-01-23T16:47:29.601 DEBUG 20700 --- [2)-172.22.34.73] o.s.web.servlet.DispatcherServlet : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
2023-01-23T16:47:29.601 INFO 20700 --- [2)-172.22.34.73] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
2023-01-23T16:47:32.136 DEBUG 20700 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.imsweb.seertransfer.controller.ApiController#processImport()
2023-01-23T16:47:32.138 DEBUG 20700 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.imsweb.seertransfer.controller.ApiController#processImport()
2023-01-23T16:47:32.145 DEBUG 20700 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
2023-01-23T16:47:32.147 DEBUG 20700 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
However if I switch the requestMatchers to "/**":
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests()
.requestMatchers("/**").permitAll()
.requestMatchers(EndpointRequest.to(HealthEndpoint.class)).permitAll()
.requestMatchers("/actuator/*").hasAuthority("ADMIN")
.anyRequest().authenticated()
.and().csrf().ignoringRequestMatchers("/api/**");
http.oauth2Login(withDefaults())
.logout()
.logoutUrl("/logout")
.addLogoutHandler(keycloakLogoutHandler)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout", HttpMethod.GET.name()))
.logoutSuccessUrl("/");
return http.build();
}
I now get the correct results back:
{
"timestamp": "2023-01-23T21:55:39.115Z",
"status": 401,
"error": "Unauthorized",
"message": "You must supply an access token",
"path": "/api/import"
}
and the log looks different:
2023-01-23T16:48:47.791 INFO 10824 --- [2)-172.22.34.73] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-01-23T16:48:47.792 INFO 10824 --- [2)-172.22.34.73] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2023-01-23T16:48:47.792 DEBUG 10824 --- [2)-172.22.34.73] o.s.web.servlet.DispatcherServlet : Detected StandardServletMultipartResolver
2023-01-23T16:48:47.792 DEBUG 10824 --- [2)-172.22.34.73] o.s.web.servlet.DispatcherServlet : Detected AcceptHeaderLocaleResolver
2023-01-23T16:48:47.792 DEBUG 10824 --- [2)-172.22.34.73] o.s.web.servlet.DispatcherServlet : Detected FixedThemeResolver
2023-01-23T16:48:47.793 DEBUG 10824 --- [2)-172.22.34.73] o.s.web.servlet.DispatcherServlet : Detected org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator#1910b7
2023-01-23T16:48:47.793 DEBUG 10824 --- [2)-172.22.34.73] o.s.web.servlet.DispatcherServlet : Detected org.springframework.web.servlet.support.SessionFlashMapManager#6ee194ac
2023-01-23T16:48:47.793 DEBUG 10824 --- [2)-172.22.34.73] o.s.web.servlet.DispatcherServlet : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
2023-01-23T16:48:47.793 INFO 10824 --- [2)-172.22.34.73] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
2023-01-23T16:48:51.362 DEBUG 10824 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.imsweb.seertransfer.controller.ApiController#processImport()
2023-01-23T16:48:51.365 DEBUG 10824 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.imsweb.seertransfer.controller.ApiController#processImport()
2023-01-23T16:48:51.372 DEBUG 10824 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
2023-01-23T16:48:51.374 DEBUG 10824 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : "ERROR" dispatch for POST "/error", parameters={}
2023-01-23T16:48:51.376 DEBUG 10824 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
2023-01-23T16:48:51.388 DEBUG 10824 --- [nio-8080-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/json', given [application/json] and supported [application/json, application/*+json]
2023-01-23T16:48:51.389 DEBUG 10824 --- [nio-8080-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [{timestamp=Mon Jan 23 16:48:51 EST 2023, status=401, error=Unauthorized, message=You must supply an (truncated)...]
2023-01-23T16:48:51.399 DEBUG 10824 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Exiting from "ERROR" dispatch, status 401
Is there something different that needs to be done with the matchers?
Create two separate SecurityFilterChain beans: one for REST configuration and one for the default configuration. Use http.securityMatcher(...) before authorizeHttpRequests() so that the REST filter chain only handles requests to API endpoints. In addition, ensure that the /error path is publicly accessible as it handles returning the JSON for errors.
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.oauth2Login(Customizer.withDefaults()).logout().logoutUrl("/logout")
.addLogoutHandler(keycloakLogoutHandler)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout", HttpMethod.GET.name()))
.logoutSuccessUrl("/");
http.authorizeHttpRequests().requestMatchers("/error").permitAll().anyRequest().authenticated();
return http.build();
}
#Bean
#Order(1)
public SecurityFilterChain restSecurityFilterChain(HttpSecurity http) throws Exception {
http.securityMatcher("/api/**", "/actuator/*").authorizeHttpRequests().requestMatchers("/api/**").permitAll().requestMatchers("/actuator/*")
.hasAuthority("ADMIN").and().csrf().ignoringRequestMatchers("/api/**");
return http.build();
}
In my case, I was having every endpoint be authenticated except "/api/**". The problem turned out that when there is an error, the call is forwarded to "/error" even though it is only going to return JSON.
My solution was to change
.requestMatchers("/api/**").permitAll()
to
.requestMatchers("/api/**", "/error").permitAll()
Now the REST API is accessible and returns correct JSON errors, while the rest of the application is still authenticated. It seems strange to have to have the error page outside of auth, but it does work.
My computer restarted and my app no longer works today. It was working yesterday. Nothing changed except Maven downloading new libraries (mostly Amazon). Now I can't even access the /admin/login page. How do I debug the request?
2019-09-13 17:26:16.924 INFO 2056 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/admin/login],methods=[GET]}" onto public java.lang.String com.s.s.controller.Controller.login()
2019-09-13 17:26:21.465 ERROR 2056 --- [nio-8080-exec-1] c.s.s.c.Controller : invalidRequest(): invalid request: /admin/login
#RequestMapping(value="/admin/login", method=RequestMethod.GET)
public String login() {
return "login";
}
#RequestMapping("/error")
public void invalidRequest(HttpServletRequest request, HttpServletResponse response){
Logger.error(TAG, "invalidRequest()", "invalid request: " + request.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI));
try {
response.setStatus(HttpStatus.OK.value());
response.getWriter().write("This is not a valid request");
} catch (IOException e) {
Logger.error(TAG, "invalidRequest: ", "Exception in invalidRequest() method "+e.getMessage());
}
}
#Override
public String getErrorPath() {
return "/error";
}
I set this line in application.properties but it didn't print anything extra.
logging.level.com.s.s.controller.Controller=DEBUG
I ran mvn clean and restarted server, but it didn't help.
I set this line in application.properties but it didn't print anything useful.
debug=true
Log:
2019-09-13 17:40:25.459 DEBUG 2056 --- [nio-8080-exec-1] o.s.b.w.f.OrderedRequestContextFilter : Bound request context to thread: org.apache.catalina.connector.RequestFacade#4d3e8c3a
2019-09-13 17:40:25.460 DEBUG 2056 --- [nio-8080-exec-1] o.s.b.w.f.OrderedRequestContextFilter : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade#4d3e8c3a
2019-09-13 17:40:25.463 ERROR 2056 --- [nio-8080-exec-1] c.s.s.c.Controller : invalidRequest(): invalid request: /admin/login
2019-09-13 17:40:25.477 DEBUG 2056 --- [nio-8080-exec-2] o.s.b.w.f.OrderedRequestContextFilter : Bound request context to thread: org.apache.catalina.connector.RequestFacade#4d3e8c3a
2019-09-13 17:40:25.484 DEBUG 2056 --- [nio-8080-exec-2] o.s.b.w.f.OrderedRequestContextFilter : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade#4d3e8c3a
$ git status
modified: src/main/resources/application.properties
modified: src/main/resources/static/js/home.js
I compared libraries to what was last deployed and the only changes were
aws-java-sdk-core-1.11.631.jar
aws-java-sdk-kms-1.11.631.jar
aws-java-sdk-s3-1.11.631.jar
aws-java-sdk-ses-1.11.631.jar
jmespath-java-1.11.631.jar
I commented public String getErrorPath() and public void invalidRequest() and now it gives me
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Fri Sep 13 18:59:03 UTC 2019
There was an unexpected error (type=Forbidden, status=403).
No message available
But with curl it gives
$ curl localhost:8080/admin/login
{"timestamp":1568401131164,"status":403,"error":"Forbidden","message":"No message available","path":"/admin/login"}
I found the following searching for spring-sleuth in Makgigrahul's answer and added it to application.properties producing this log.
logging.level.org.springframework.web.servlet.DispatcherServlet=DEBUG
Log:
2019-09-13 16:10:11.329 DEBUG 15356 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing servlet 'dispatcherServlet'
2019-09-13 16:10:11.330 INFO 15356 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2019-09-13 16:10:11.331 INFO 15356 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2019-09-13 16:10:11.332 DEBUG 15356 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Using MultipartResolver [org.springframework.web.multipart.support.StandardServletMultipartResolver#6481dcd8]
2019-09-13 16:10:11.332 DEBUG 15356 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Using LocaleResolver [org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver#50cc90f2]
2019-09-13 16:10:11.339 DEBUG 15356 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Unable to locate ThemeResolver with name 'themeResolver': using default [org.springframework.web.servlet.theme.FixedThemeResolver#135fd762]
2019-09-13 16:10:11.345 DEBUG 15356 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Unable to locate RequestToViewNameTranslator with name 'viewNameTranslator': using default [org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator#61cc4a6b]
2019-09-13 16:10:11.352 DEBUG 15356 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Unable to locate FlashMapManager with name 'flashMapManager': using default [org.springframework.web.servlet.support.SessionFlashMapManager#766c1f26]
2019-09-13 16:10:11.353 DEBUG 15356 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Published WebApplicationContext of servlet 'dispatcherServlet' as ServletContext attribute with name [org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcherServlet]
2019-09-13 16:10:11.355 INFO 15356 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 23 ms
2019-09-13 16:10:11.356 DEBUG 15356 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Servlet 'dispatcherServlet' configured successfully
2019-09-13 16:10:11.376 DEBUG 15356 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/error]
2019-09-13 16:10:11.383 DEBUG 15356 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/error] is: -1
2019-09-13 16:10:11.408 DEBUG 15356 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Rendering view [org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$SpelView#53191939] in DispatcherServlet with name 'dispatcherServlet'
2019-09-13 16:10:11.415 DEBUG 15356 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Successfully completed request
You can try to set a breakpoint in org.apache.catalina.core.ApplicationFilterChain#doFilter. Thats pretty at the beginning of the request processing. Or you can have a look in org.springframework.web.servlet.DispatcherServlet#doDispatch
I was able to debug using Andreas' answer and saw the values for request.request.filterChain.filters[] and saw my filter remoteAddressFilter() and saw remoteAddress = 0:0:0:0:0:0:0:1. I have an IP filter (RemoteAddrFilter) and one of the allowed values is 127.0.0.1. I was accessing the server with http://localhost:8080/admin/home, which apparently uses the IP6 address. Probably a Windows update which restarted the computer changed the networking behavior. When I use http://127.0.0.1:8080/admin/home it works. I would like to add logging to the filter to notify when blocked, but there is no apparent way. Amazing Spring doesn't log the filters in debug mode.
I'm trying to write a simple SpringBoot Web Application to get started with the framework.
This is my structure:
src
`-main
`-java
`-resources
`-static
`-templates
`-webapp
`-WEB-INF
`-jsp
`-login.jsp
I have a Controller like
#Controller
public class LoginController {
#RequestMapping("/login")
public String loginMessage(){
return "login";
}
}
I've configurated the path where views has to be looked for in the application.properties like:
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
logging.level.org.springframework.web=DEBUG
I've also included the next dependency in pom.xml:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
But when I go to http://localhost:8080/login I'm still having a 404 error.
What am I missing?
EDIT:
Here is the log from the IntelliJ Idea console. It seems like it finds the login.jsp, but for some reason return an error page.
2018-07-06 11:17:20.488 DEBUG 53340 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/login]
2018-07-06 11:17:20.488 DEBUG 53340 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /login
2018-07-06 11:17:20.488 DEBUG 53340 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public java.lang.String com.albertocastano.apringboot.web.springbootfirstwebapplication.controller.LoginController.loginMessage()]
2018-07-06 11:17:20.488 DEBUG 53340 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/login] is: -1
2018-07-06 11:17:20.489 DEBUG 53340 --- [nio-8080-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Requested media types are [text/html, application/xhtml+xml, image/webp, image/apng, application/xml;q=0.9, */*;q=0.8] based on Accept header types and producible media types [*/*])
2018-07-06 11:17:20.489 DEBUG 53340 --- [nio-8080-exec-1] o.s.w.servlet.view.BeanNameViewResolver : No matching bean found for view name 'login'
2018-07-06 11:17:20.489 DEBUG 53340 --- [nio-8080-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Returning [org.springframework.web.servlet.view.InternalResourceView: name 'login'; URL [/WEB-INF/jsp/login.jsp]] based on requested media type 'text/html'
2018-07-06 11:17:20.489 DEBUG 53340 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Rendering view [org.springframework.web.servlet.view.InternalResourceView: name 'login'; URL [/WEB-INF/jsp/login.jsp]] in DispatcherServlet with name 'dispatcherServlet'
2018-07-06 11:17:20.492 DEBUG 53340 --- [nio-8080-exec-1] o.s.w.servlet.view.InternalResourceView : Forwarding to resource [/WEB-INF/jsp/login.jsp] in InternalResourceView 'login'
2018-07-06 11:17:20.492 DEBUG 53340 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/WEB-INF/jsp/login.jsp]
2018-07-06 11:17:20.492 DEBUG 53340 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /WEB-INF/jsp/login.jsp
2018-07-06 11:17:20.493 DEBUG 53340 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/WEB-INF/jsp/login.jsp]
2018-07-06 11:17:20.495 DEBUG 53340 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/WEB-INF/jsp/login.jsp] are [/**]
2018-07-06 11:17:20.496 DEBUG 53340 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/WEB-INF/jsp/login.jsp] are {}
2018-07-06 11:17:20.497 DEBUG 53340 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/WEB-INF/jsp/login.jsp] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/], ServletContext resource [/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#3f0408]]] and 1 interceptor
2018-07-06 11:17:20.498 DEBUG 53340 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/WEB-INF/jsp/login.jsp] is: -1
2018-07-06 11:17:20.499 DEBUG 53340 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2018-07-06 11:17:20.499 DEBUG 53340 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Successfully completed request
2018-07-06 11:17:20.500 DEBUG 53340 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Successfully completed request
2018-07-06 11:17:20.501 DEBUG 53340 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/error]
2018-07-06 11:17:20.502 DEBUG 53340 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error
2018-07-06 11:17:20.502 DEBUG 53340 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)]
2018-07-06 11:17:20.502 DEBUG 53340 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/error] is: -1
2018-07-06 11:17:20.522 DEBUG 53340 --- [nio-8080-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Requested media types are [text/html, text/html;q=0.8] based on Accept header types and producible media types [text/html])
2018-07-06 11:17:20.522 DEBUG 53340 --- [nio-8080-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Returning [org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration$SpelView#bd7588] based on requested media type 'text/html'
2018-07-06 11:17:20.522 DEBUG 53340 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Rendering view [org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration$SpelView#bd7588] in DispatcherServlet with name 'dispatcherServlet'
2018-07-06 11:17:20.522 DEBUG 53340 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Successfully completed request
You're missing dependancy in your pom.xml file.
Add jstl :
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
And remove the scope provided of tomcat-embed-jasper, because it's not provided by default by any spring-boot-starter.
I have been using Spring Boot ReST APIs for quite some time; I thought of experimenting with web-MVC. However, I have got stuck on the first part itself.
I have uploaded the project on GitHub
What I have done so far:
Defined POM.xml with spring-boot-starter-web + tomcat-embed-jasper mainly.
Defined a #Controller with #GetMapping("/greeting"), which returns the name of a view - hello
Defined following properties:
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
Created a very basic view hello.jsp at src/main/web/WEB-INF/views/hello.jsp
Created a main Application to run as SpringBootApplication.
Error:
Whitelabel Error Page
This application has no explicit mapping for
/error, so you are seeing this as a fallback.
Mon Mar 26 22:55:03 IST 2018
There was an unexpected error (type=Not Found, status=404). No message available
Logs:
2018-03-26 22:55:02.998 DEBUG 7132 --- [nio-8080-exec-1] o.a.coyote.http11.Http11InputBuffer : Received [GET /greeting HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
DNT: 1
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,hi;q=0.8
]
2018-03-26 22:55:03.043 DEBUG 7132 --- [nio-8080-exec-1] org.apache.tomcat.util.http.Parameters : Set query string encoding to UTF-8
2018-03-26 22:55:03.054 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.authenticator.AuthenticatorBase : Security checking request GET /greeting
2018-03-26 22:55:03.054 DEBUG 7132 --- [nio-8080-exec-1] org.apache.catalina.realm.RealmBase : No applicable constraints defined
2018-03-26 22:55:03.063 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.a.jaspic.AuthConfigFactoryImpl : Loading persistent provider registrations from [C:\Users\NirMit\AppData\Local\Temp\tomcat.3836668232954126555.8080\conf\jaspic-providers.xml]
2018-03-26 22:55:03.064 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.authenticator.AuthenticatorBase : Not subject to any constraint
2018-03-26 22:55:03.067 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing servlet 'dispatcherServlet'
2018-03-26 22:55:03.068 INFO 7132 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2018-03-26 22:55:03.069 INFO 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2018-03-26 22:55:03.069 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'multipartResolver'
2018-03-26 22:55:03.069 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Using MultipartResolver [org.springframework.web.multipart.support.StandardServletMultipartResolver#a8d0be]
2018-03-26 22:55:03.070 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Creating instance of bean 'org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver'
2018-03-26 22:55:03.074 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : findClass(java.lang.ObjectCustomizer)
2018-03-26 22:55:03.074 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : --> Returning ClassNotFoundException
2018-03-26 22:55:03.077 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : findClass(org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolverCustomizer)
2018-03-26 22:55:03.079 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : --> Returning ClassNotFoundException
2018-03-26 22:55:03.082 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : findClass(org.springframework.web.servlet.LocaleResolverCustomizer)
2018-03-26 22:55:03.084 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : --> Returning ClassNotFoundException
2018-03-26 22:55:03.084 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Finished creating instance of bean 'org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver'
2018-03-26 22:55:03.085 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Unable to locate LocaleResolver with name 'localeResolver': using default [org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver#1c2a3a2]
2018-03-26 22:55:03.086 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Creating instance of bean 'org.springframework.web.servlet.theme.FixedThemeResolver'
2018-03-26 22:55:03.091 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : findClass(java.lang.ObjectCustomizer)
2018-03-26 22:55:03.091 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : --> Returning ClassNotFoundException
2018-03-26 22:55:03.093 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : findClass(org.springframework.web.servlet.theme.AbstractThemeResolverCustomizer)
2018-03-26 22:55:03.095 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : --> Returning ClassNotFoundException
2018-03-26 22:55:03.097 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : findClass(org.springframework.web.servlet.theme.FixedThemeResolverCustomizer)
2018-03-26 22:55:03.098 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : --> Returning ClassNotFoundException
2018-03-26 22:55:03.101 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : findClass(org.springframework.web.servlet.ThemeResolverCustomizer)
2018-03-26 22:55:03.108 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : --> Returning ClassNotFoundException
2018-03-26 22:55:03.109 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Finished creating instance of bean 'org.springframework.web.servlet.theme.FixedThemeResolver'
2018-03-26 22:55:03.115 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Unable to locate ThemeResolver with name 'themeResolver': using default [org.springframework.web.servlet.theme.FixedThemeResolver#1855c21]
2018-03-26 22:55:03.116 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'requestMappingHandlerMapping'
2018-03-26 22:55:03.116 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'viewControllerHandlerMapping'
2018-03-26 22:55:03.116 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'beanNameHandlerMapping'
2018-03-26 22:55:03.116 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'resourceHandlerMapping'
2018-03-26 22:55:03.116 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'defaultServletHandlerMapping'
2018-03-26 22:55:03.116 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'faviconHandlerMapping'
2018-03-26 22:55:03.116 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'welcomePageHandlerMapping'
2018-03-26 22:55:03.117 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'requestMappingHandlerAdapter'
2018-03-26 22:55:03.117 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'httpRequestHandlerAdapter'
2018-03-26 22:55:03.117 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'simpleControllerHandlerAdapter'
2018-03-26 22:55:03.117 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'errorAttributes'
2018-03-26 22:55:03.117 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'handlerExceptionResolver'
2018-03-26 22:55:03.121 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Creating instance of bean 'org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator'
2018-03-26 22:55:03.124 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : findClass(java.lang.ObjectCustomizer)
2018-03-26 22:55:03.124 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : --> Returning ClassNotFoundException
2018-03-26 22:55:03.126 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : findClass(org.springframework.web.servlet.view.DefaultRequestToViewNameTranslatorCustomizer)
2018-03-26 22:55:03.128 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : --> Returning ClassNotFoundException
2018-03-26 22:55:03.130 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : findClass(org.springframework.web.servlet.RequestToViewNameTranslatorCustomizer)
2018-03-26 22:55:03.132 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : --> Returning ClassNotFoundException
2018-03-26 22:55:03.133 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Finished creating instance of bean 'org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator'
2018-03-26 22:55:03.133 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Unable to locate RequestToViewNameTranslator with name 'viewNameTranslator': using default [org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator#99d4c6]
2018-03-26 22:55:03.133 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'beanNameViewResolver'
2018-03-26 22:55:03.134 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'mvcViewResolver'
2018-03-26 22:55:03.134 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'defaultViewResolver'
2018-03-26 22:55:03.134 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'viewResolver'
2018-03-26 22:55:03.137 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Creating instance of bean 'org.springframework.web.servlet.support.SessionFlashMapManager'
2018-03-26 22:55:03.141 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : findClass(java.lang.ObjectCustomizer)
2018-03-26 22:55:03.142 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : --> Returning ClassNotFoundException
2018-03-26 22:55:03.143 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : findClass(org.springframework.web.servlet.support.AbstractFlashMapManagerCustomizer)
2018-03-26 22:55:03.146 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : --> Returning ClassNotFoundException
2018-03-26 22:55:03.153 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : findClass(org.springframework.web.servlet.support.SessionFlashMapManagerCustomizer)
2018-03-26 22:55:03.156 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : --> Returning ClassNotFoundException
2018-03-26 22:55:03.158 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : findClass(org.springframework.web.servlet.FlashMapManagerCustomizer)
2018-03-26 22:55:03.160 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.loader.WebappClassLoaderBase : --> Returning ClassNotFoundException
2018-03-26 22:55:03.161 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Finished creating instance of bean 'org.springframework.web.servlet.support.SessionFlashMapManager'
2018-03-26 22:55:03.161 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Unable to locate FlashMapManager with name 'flashMapManager': using default [org.springframework.web.servlet.support.SessionFlashMapManager#3d023d]
2018-03-26 22:55:03.161 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Published WebApplicationContext of servlet 'dispatcherServlet' as ServletContext attribute with name [org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcherServlet]
2018-03-26 22:55:03.161 INFO 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 92 ms
2018-03-26 22:55:03.161 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Servlet 'dispatcherServlet' configured successfully
2018-03-26 22:55:03.177 DEBUG 7132 --- [169.254.165.176] sun.rmi.transport.tcp : RMI TCP Connection(3)-169.254.165.176: (port 51150) connection closed
2018-03-26 22:55:03.177 DEBUG 7132 --- [169.254.165.176] sun.rmi.transport.tcp : RMI TCP Connection(3)-169.254.165.176: close connection
2018-03-26 22:55:03.200 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.w.s.f.OrderedRequestContextFilter : Bound request context to thread: org.apache.catalina.connector.RequestFacade#1cc2c8
2018-03-26 22:55:03.211 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/greeting]
2018-03-26 22:55:03.217 DEBUG 7132 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /greeting
2018-03-26 22:55:03.223 DEBUG 7132 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public java.lang.String com.khandhedia.sprinboot.mvc.demo1.controller.GreetingController.greetingForm(org.springframework.ui.Model)]
2018-03-26 22:55:03.223 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'greetingController'
2018-03-26 22:55:03.224 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/greeting] is: -1
2018-03-26 22:55:03.285 DEBUG 7132 --- [nio-8080-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Requested media types are [text/html, application/xhtml+xml, image/webp, image/apng, application/xml;q=0.9, */*;q=0.8] based on Accept header types and producible media types [*/*])
2018-03-26 22:55:03.285 DEBUG 7132 --- [nio-8080-exec-1] o.s.w.servlet.view.BeanNameViewResolver : No matching bean found for view name 'hello'
2018-03-26 22:55:03.293 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Invoking afterPropertiesSet() on bean with name 'hello'
2018-03-26 22:55:03.295 DEBUG 7132 --- [nio-8080-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Returning [org.springframework.web.servlet.view.JstlView: name 'hello'; URL [/WEB-INF/views/hello.jsp]] based on requested media type 'text/html'
2018-03-26 22:55:03.295 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Rendering view [org.springframework.web.servlet.view.JstlView: name 'hello'; URL [/WEB-INF/views/hello.jsp]] in DispatcherServlet with name 'dispatcherServlet'
2018-03-26 22:55:03.296 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.view.JstlView : Added model object 'name' of type [java.lang.String] to request in view with name 'hello'
2018-03-26 22:55:03.307 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.view.JstlView : Forwarding to resource [/WEB-INF/views/hello.jsp] in InternalResourceView 'hello'
2018-03-26 22:55:03.318 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/WEB-INF/views/hello.jsp]
2018-03-26 22:55:03.318 DEBUG 7132 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /WEB-INF/views/hello.jsp
2018-03-26 22:55:03.340 DEBUG 7132 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/WEB-INF/views/hello.jsp]
2018-03-26 22:55:03.340 DEBUG 7132 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/WEB-INF/views/hello.jsp] are [/**]
2018-03-26 22:55:03.342 DEBUG 7132 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/WEB-INF/views/hello.jsp] are {}
2018-03-26 22:55:03.343 DEBUG 7132 --- [nio-8080-exec-1] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/WEB-INF/views/hello.jsp] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/], ServletContext resource [/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#1113a37]]] and 1 interceptor
2018-03-26 22:55:03.344 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/WEB-INF/views/hello.jsp] is: -1
2018-03-26 22:55:03.344 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2018-03-26 22:55:03.344 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Successfully completed request
2018-03-26 22:55:03.347 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Disabling the response for further output
2018-03-26 22:55:03.347 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Successfully completed request
2018-03-26 22:55:03.347 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.w.s.f.OrderedRequestContextFilter : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade#1cc2c8
2018-03-26 22:55:03.348 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost] : Processing ErrorPage[errorCode=0, location=/error]
2018-03-26 22:55:03.349 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/error]
2018-03-26 22:55:03.350 DEBUG 7132 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error
2018-03-26 22:55:03.351 DEBUG 7132 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)]
2018-03-26 22:55:03.351 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'basicErrorController'
2018-03-26 22:55:03.352 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/error] is: -1
2018-03-26 22:55:03.354 DEBUG 7132 --- [nio-8080-exec-1] o.s.c.e.PropertySourcesPropertyResolver : Could not find key 'spring.template.provider.cache' in any property source
2018-03-26 22:55:03.358 DEBUG 7132 --- [nio-8080-exec-1] o.s.c.e.PropertySourcesPropertyResolver : Could not find key 'spring.template.provider.cache' in any property source
2018-03-26 22:55:03.383 DEBUG 7132 --- [nio-8080-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Requested media types are [text/html, text/html;q=0.8] based on Accept header types and producible media types [text/html])
2018-03-26 22:55:03.383 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'error'
2018-03-26 22:55:03.383 DEBUG 7132 --- [nio-8080-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Invoking afterPropertiesSet() on bean with name 'error'
2018-03-26 22:55:03.383 DEBUG 7132 --- [nio-8080-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Returning [org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration$SpelView#1943f03] based on requested media type 'text/html'
2018-03-26 22:55:03.383 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Rendering view [org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration$SpelView#1943f03] in DispatcherServlet with name 'dispatcherServlet'
2018-03-26 22:55:03.420 DEBUG 7132 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Successfully completed request
2018-03-26 22:55:03.420 DEBUG 7132 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Disabling the response for further output
2018-03-26 22:55:03.439 DEBUG 7132 --- [nio-8080-exec-1] o.a.tomcat.util.net.SocketWrapperBase : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper#10910ae:org.apache.tomcat.util.net.NioChannel#4cbd6d:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8080 remote=/0:0:0:0:0:0:0:1:51167]], Read from buffer: [0]
2018-03-26 22:55:03.440 DEBUG 7132 --- [nio-8080-exec-1] o.apache.coyote.http11.Http11Processor : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper#10910ae:org.apache.tomcat.util.net.NioChannel#4cbd6d:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8080 remote=/0:0:0:0:0:0:0:1:51167]], Status in: [OPEN_READ], State out: [OPEN]
2018-03-26 22:55:09.322 DEBUG 7132 --- [nio-8080-exec-5] o.a.tomcat.util.net.SocketWrapperBase : Socket: [org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper#10910ae:org.apache.tomcat.util.net.NioChannel#4cbd6d:java.nio.channels.SocketChannel[connected local=/0:0:0:0:0:0:0:1:8080 remote=/0:0:0:0:0:0:0:1:51167]], Read from buffer: [0]
2018-03-26 22:55:09.322 DEBUG 7132 --- [nio-8080-exec-5] o.apache.coyote.http11.Http11Processor : Error parsing HTTP request header
EDIT:
I tried following changes as per the comments; however, it doesn't seem to help yet.
Putting hello.jsp in src/main/resources/templates/WEB-INF/views
Putting hello.jsp in src/main/resources/static/WEB-INF/views
Putting hello.jsp in src/main/resources/WEB-INF/views
Putting hello.jsp in src/main/webapp/WEB-INF/views
Please advise.
The issue was with the provided scope of Maven Dependency tomcat-embed-jasper which is used to compile the JSPs.
With default scope for this maven dependency, it flies!
<!-- Tomcat for JSP rendering -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
Two cents from my analysis!
What is the use of this dependency when we already have spring-boot-starter-web?
The spring-boot-starter-web includes the spring-boot-starter-tomcat and the spring-boot-starter-tomcat includes the tomcat-embed-core.
But, tomcat-embed-core doesn't include tomcat-embed-jasper.
Now, according to maven docs, if the tomcat-embed-jasper is marked as provided, it means that it expects the JDK or a container to provide the dependency at runtime.
This scope is only available on the compilation and test classpath, and is not transitive.
Hence, effectively this dependency is not available when JSPs are being compiled.
By marking this dependency scope as compile, it is made available in all the classpaths and to all the dependent projects as well.
Summary: The spring-boot-starter-web has tomcat embedded dependency but it doesn't include the jasper embedded dependency. One needs to add this dependency with default compile scope.
Where to place the JSPs/View Components in a Spring Boot Project?
Create a Web Project using Spring Inializr or IntelliJ Spring Plugins.
Add Web framework support using IDE. It may create a directory as src/main/web/WEB-INF
Rename the directory from web to webapp
Create the view components like JSPs at src/main/webapp/WEB-INF/views/
Define following properties in application.properties
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
src/main/web/WEB-INF/views/hello.jsp
will not be found by Spring Boot. As a Spring Boot convention you should put your views under resources folder:
src/main/resources/templates/...
And for your CSS:
src/main/resources/static/...
And if you are using Spring Boot, then it's a good idea to use the project initializer:
https://start.spring.io/
from there choose what view technology you want, and Spring Boot will add its dependencies for you, so you don't need to add them or configure them yourself(step 3).
I have a test like this:
#Test
#Transactional
public void when_EnteredRegisteredProductionOrder_and_RegisteredStaffSignature_then_201_and_ProductionOrderRegistered() {
//language=JSON
String startProductionOrder = "{\n" +
" \"productionOrder\": \"1700281\",\n" +
" \"staffCodeSignature\": \"00000425\"\n" +
"}";
given()
.body(startProductionOrder)
.accept(ContentType.JSON)
.contentType(ContentType.JSON)
.when()
.post(commandPath)
.then().statusCode(201);
ProductionOrder po = productionOrderRepo.findOneByCode("1700281");
assertThat(po.getCode(), is("1700281"));
}
My intention is to test the REST API from start to end using restassured. As you can imagine each command, starting from the controller is annotated with #Transactional. The problem is that test does not rollback automatically. The debug log shows than (I removed many parts because it was too long to post):
DEBUG 14120 --- [ main] tractDirtiesContextTestExecutionListener : Before test method: context [DefaultTestContext#1dd02175 testClass = ProductionOrderStartLT, testInstance = com.demo.logbook.commandValidationLT.ProductionOrderStartLT#25359ed8, testMethod = when_EnteredRegisteredProductionOrder_and_RegisteredStaffSignature_then_201_and_ProductionOrderRegistered#ProductionOrderStartLT, testExcep
DEBUG 14120 --- [ main] t.a.AnnotationTransactionAttributeSource : Adding transactional method 'com.demo.logbook.commandValidationLT.ProductionOrderStartLT.when_EnteredRegisteredProductionOrder_and_RegisteredStaffSignature_then_201_and_ProductionOrderRegistered' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
DEBUG 14120 --- [ main] t.c.t.TransactionalTestExecutionListener : Explicit transaction definition [PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''] found for test context [DefaultTestContext#1dd02175 testClass = ProductionOrderStartLT, testInstance = com.demo.logbook.commandValidationLT.ProductionOrderStartLT#25359ed8, testMethod = when_EnteredRegisteredProductionOrder_and_RegisteredStaffSignature_
DEBUG 14120 --- [ main] t.c.t.TransactionalTestExecutionListener : Retrieved #TransactionConfiguration [null] for test class [com.demo.logbook.commandValidationLT.ProductionOrderStartLT].
DEBUG 14120 --- [ main] t.c.t.TransactionalTestExecutionListener : Using TransactionConfigurationAttributes [TransactionConfigurationAttributes#4a5fab78 transactionManagerName = '', defaultRollback = true] for test class [com.demo.logbook.commandValidationLT.ProductionOrderStartLT].
DEBUG 14120 --- [ main] c.DefaultCacheAwareContextLoaderDelegate : Retrieved ApplicationContext from cache with key [[WebMergedContextConfiguration#31206beb testClass = ProductionOrderStartLT, locations = '{}', classes = '{class com.demo.logbook.ElogbookApplication}', contextInitializerClasses = '[]', activeProfiles = '{test}', propertySourceLocations = '{}', propertySourceProperties = '{org.sp
DEBUG 14120 --- [ main] org.springframework.test.context.cache : Spring test ApplicationContext cache statistics: [DefaultContextCache#c677d7e size = 1, maxSize = 32, parentContextCount = 0, hitCount = 1, missCount = 1]
DEBUG 14120 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'transactionManager'
DEBUG 14120 --- [ main] t.c.t.TransactionalTestExecutionListener : No method-level #Rollback override: using default rollback [true] for test context [DefaultTestContext#1dd02175 testClass = ProductionOrderStartLT, testInstance = com.demo.logbook.commandValidationLT.ProductionOrderStartLT#25359ed8, testMethod = when_EnteredRegisteredProductionOrder_and_RegisteredStaffSignature_then_201_and_Prod
DEBUG 14120 --- [ main] o.s.orm.jpa.JpaTransactionManager : Creating new transaction with name [com.demo.logbook.commandValidationLT.ProductionOrderStartLT.when_EnteredRegisteredProductionOrder_and_RegisteredStaffSignature_then_201_and_ProductionOrderRegistered]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
DEBUG 14120 --- [ main] o.s.orm.jpa.JpaTransactionManager : Opened new EntityManager [org.hibernate.jpa.internal.EntityManagerImpl#505a8582] for JPA transaction
DEBUG 14120 --- [ main] o.s.orm.jpa.JpaTransactionManager : Exposing JPA transaction as JDBC transaction [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle#465d1345]
INFO 14120 --- [ main] o.s.t.c.transaction.TransactionContext : Began transaction (1) for test context [DefaultTestContext#1dd02175 testClass = ProductionOrderStartLT, testInstance = com.demo.logbook.commandValidationLT.ProductionOrderStartLT#25359ed8, testMethod = when_EnteredRegisteredProductionOrder_and_RegisteredStaffSignature_then_201_and_ProductionOrderRegistered#ProductionOrderStartLT
DEBUG 14120 --- [ main] c.DefaultCacheAwareContextLoaderDelegate : Retrieved ApplicationContext from cache with key [[WebMergedContextConfiguration#31206beb testClass = ProductionOrderStartLT, locations = '{}', classes = '{class com.demo.logbook.ElogbookApplication}', contextInitializerClasses = '[]', activeProfiles = '{test}', propertySourceLocations = '{}', propertySourceProperties = '{org.sp
DEBUG 14120 --- [ main] org.springframework.test.context.cache : Spring test ApplicationContext cache statistics: [DefaultContextCache#c677d7e size = 1, maxSize = 32, parentContextCount = 0, hitCount = 2, missCount = 1]
DEBUG 14120 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.boot.test.mock.mockito.MockitoBeans'
DEBUG 14120 --- [nio-9090-exec-1] o.s.web.servlet.DispatcherServlet : Initializing servlet 'dispatcherServlet'
INFO 14120 --- [nio-9090-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
INFO 14120 --- [nio-9090-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'multipartResolver'
DEBUG 14120 --- [nio-9090-exec-1] o.s.web.servlet.DispatcherServlet : Using MultipartResolver [org.springframework.web.multipart.support.StandardServletMultipartResolver#63880be9]
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Creating instance of bean 'org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Finished creating instance of bean 'org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver'
DEBUG 14120 --- [nio-9090-exec-1] o.s.web.servlet.DispatcherServlet : Unable to locate LocaleResolver with name 'localeResolver': using default [org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver#560b484d]
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Creating instance of bean 'org.springframework.web.servlet.theme.FixedThemeResolver'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Finished creating instance of bean 'org.springframework.web.servlet.theme.FixedThemeResolver'
DEBUG 14120 --- [nio-9090-exec-1] o.s.web.servlet.DispatcherServlet : Unable to locate ThemeResolver with name 'themeResolver': using default [org.springframework.web.servlet.theme.FixedThemeResolver#5c57255c]
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'requestMappingHandlerMapping'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'viewControllerHandlerMapping'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'beanNameHandlerMapping'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'resourceHandlerMapping'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'defaultServletHandlerMapping'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'faviconHandlerMapping'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'welcomePageHandlerMapping'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'requestMappingHandlerAdapter'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'httpRequestHandlerAdapter'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'simpleControllerHandlerAdapter'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'errorAttributes'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'handlerExceptionResolver'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Creating instance of bean 'org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Finished creating instance of bean 'org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator'
DEBUG 14120 --- [nio-9090-exec-1] o.s.web.servlet.DispatcherServlet : Unable to locate RequestToViewNameTranslator with name 'viewNameTranslator': using default [org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator#56aa150f]
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'beanNameViewResolver'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'mvcViewResolver'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'defaultViewResolver'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'viewResolver'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Creating instance of bean 'org.springframework.web.servlet.support.SessionFlashMapManager'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Finished creating instance of bean 'org.springframework.web.servlet.support.SessionFlashMapManager'
DEBUG 14120 --- [nio-9090-exec-1] o.s.web.servlet.DispatcherServlet : Unable to locate FlashMapManager with name 'flashMapManager': using default [org.springframework.web.servlet.support.SessionFlashMapManager#2c40b216]
DEBUG 14120 --- [nio-9090-exec-1] o.s.web.servlet.DispatcherServlet : Published WebApplicationContext of servlet 'dispatcherServlet' as ServletContext attribute with name [org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcherServlet]
INFO 14120 --- [nio-9090-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 19 ms
DEBUG 14120 --- [nio-9090-exec-1] o.s.web.servlet.DispatcherServlet : Servlet 'dispatcherServlet' configured successfully
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.w.f.OrderedRequestContextFilter : Bound request context to thread: org.apache.catalina.connector.RequestFacade#17b5f8f0
DEBUG 14120 --- [nio-9090-exec-1] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing POST request for [/commands/production/production-orders]
DEBUG 14120 --- [nio-9090-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /commands/production/production-orders
DEBUG 14120 --- [nio-9090-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public void com.demo.logbook.commands.web.controllers.ProductionController.startProductionOrder(com.demo.logbook.commands.commands.productionOrder.StartProductionOrder)]
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'productionController'
DEBUG 14120 --- [nio-9090-exec-1] o.j.s.OpenEntityManagerInViewInterceptor : Opening JPA EntityManager in OpenEntityManagerInViewInterceptor
DEBUG 14120 --- [nio-9090-exec-1] m.m.a.RequestResponseBodyMethodProcessor : Read [class com.demo.logbook.commands.commands.productionOrder.StartProductionOrder] as "application/json;charset=UTF-8" with [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#ff21443]
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Creating instance of bean 'org.hibernate.validator.internal.constraintvalidators.bv.NotNullValidator'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Finished creating instance of bean 'org.hibernate.validator.internal.constraintvalidators.bv.NotNullValidator'
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'transactionManager'
DEBUG 14120 --- [nio-9090-exec-1] o.s.orm.jpa.JpaTransactionManager : Found thread-bound EntityManager [org.hibernate.jpa.internal.EntityManagerImpl#2aa65d86] for JPA transaction
DEBUG 14120 --- [nio-9090-exec-1] o.s.orm.jpa.JpaTransactionManager : Creating new transaction with name [com.demo.logbook.commands.web.controllers.ProductionController.startProductionOrder]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '',-java.lang.RuntimeException
DEBUG 14120 --- [nio-9090-exec-1] o.s.orm.jpa.JpaTransactionManager : Exposing JPA transaction as JDBC transaction [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle#63fa0a64]
DEBUG 14120 --- [nio-9090-exec-1] c.d.l.c.w.c.ProductionController : Command received : StartProductionOrder{productionOrder='1700281'} SignedCommand{staffCodeSignature='00000425'}
INFO 14120 --- [nio-9090-exec-1] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory
Hibernate: select eventtype0_.id as id1_17_, eventtype0_.name as name2_17_, eventtype0_.type as type3_17_ from events.event_type eventtype0_ where eventtype0_.name=?
Hibernate: select aggregate0_.aggregate_id as aggregat1_15_, aggregate0_.name as name2_15_ from events.aggregate aggregate0_ where aggregate0_.name=?
DEBUG 14120 --- [nio-9090-exec-1] c.d.l.event_store.services.EventStore : Flushing event : Event
DEBUG 14120 --- [nio-9090-exec-1] stomAnnotationTransactionAttributeSource : Adding transactional method 'save' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'transactionManager'
DEBUG 14120 --- [nio-9090-exec-1] o.s.orm.jpa.JpaTransactionManager : Found thread-bound EntityManager [org.hibernate.jpa.internal.EntityManagerImpl#2aa65d86] for JPA transaction
DEBUG 14120 --- [nio-9090-exec-1] o.s.orm.jpa.JpaTransactionManager : Participating in existing transaction
Hibernate: select nextval ('hibernate_sequence')
DEBUG 14120 --- [nio-9090-exec-1] c.d.l.event_store.services.EventStore : Event flushed : Event{event_id=31, correlation_id=e5901e3d-9cbf-4c53-bb8c-1fb1006328f8, data='{"transaction_id":"0c4cb269-32fc-422d-93a8-28d506911861","staffCodeSignature":"00000425","productionOrderCode":"1700281"}', version=1, eventType=com.demo.logbook.event_store.persistance.entities.EventType#34ef5c1b, aggregate=Aggregate{a
DEBUG 14120 --- [nio-9090-exec-1] c.d.l.c.w.c.ProductionController : Publishing eventData : ProductionOrderStarted
DEBUG 14120 --- [nio-9090-exec-1] c.d.l.c.w.c.ProductionController : Command success : StartProductionOrder{productionOrder='1700281'} SignedCommand{staffCodeSignature='00000425'}
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'adminProjection'
DEBUG 14120 --- [nio-9090-exec-1] c.d.l.q.a.projection.AdminProjection : Event received in admin module: ProductionOrderStarted
DEBUG 14120 --- [nio-9090-exec-1] c.d.l.q.a.s.AdminValidationService : Validating event in admin module: ProductionOrderStarted
Hibernate: select count(production0_.product_order_id) as col_0_0_ from admin.production_order production0_ where production0_.code=?
Hibernate: select count(staff0_.reason_type_id) as col_0_0_ from admin.staff staff0_ where staff0_.code=?
DEBUG 14120 --- [nio-9090-exec-1] c.d.l.q.a.s.AdminValidationService : Event validation successful in admin module: ProductionOrderStarted
DEBUG 14120 --- [nio-9090-exec-1] c.d.l.q.a.projection.AdminProjection : Event processed successfully by admin module: ProductionOrderStarted
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'productionProjection'
DEBUG 14120 --- [nio-9090-exec-1] c.d.l.q.p.p.ProductionProjection : Event received in prod module: ProductionOrderStarted
DEBUG 14120 --- [nio-9090-exec-1] c.d.l.q.p.s.ProductionValidationService : Validating event in prod module: ProductionOrderStarted
Hibernate: select production0_.transaction_id as transact1_20_, production0_.last_action_timestamp as last_act2_20_, production0_.code as code3_20_, production0_.product_code as product_4_20_, production0_.product_name as product_5_20_, production0_.work_center_code as work_cen6_20_, production0_.work_center_name as work_cen7_20_ from prod.production_order production0_ where production0_.code=?
2017-01-20 13:50:10.399 DEBUG 14120 --- [nio-9090-exec-1] c.d.l.q.p.s.ProductionValidationService : Event validation successful in prod module: ProductionOrderStarted
Hibernate: select production0_.product_order_id as product_1_5_, production0_.code as code2_5_, production0_.product_id as product_3_5_, production0_.work_center_id as work_cen4_5_ from admin.production_order production0_ where production0_.code=?
Hibernate: select product0_.product_id as product_1_3_0_, product0_.box_size as box_size2_3_0_, product0_.code as code3_3_0_, product0_.container_size as containe4_3_0_, product0_.container_type as containe5_3_0_, product0_.description as descript6_3_0_, product0_.markezini_capacity as markezin7_3_0_, product0_.partena_capacity as partena_8_3_0_, product0_.product_category_id as product_9_3_0_, productca
Hibernate: select workcenter0_.work_center_id as work_cen1_13_0_, workcenter0_.code as code2_13_0_, workcenter0_.is_active as is_activ3_13_0_, workcenter0_.name as name4_13_0_, workcenter0_.wing_id as wing_id5_13_0_, wing1_.wing_id as wing_id1_12_1_, wing1_.name as name2_12_1_ from admin.work_center workcenter0_ left outer join admin.wing wing1_ on workcenter0_.wing_id=wing1_.wing_id where workcenter0_.w
DEBUG 14120 --- [nio-9090-exec-1] c.d.l.q.p.s.ProductionEventsService : Flushing production order: ProductionOrder(super=TransactionalEntity(transaction_id=0c4cb269-32fc-422d-93a8-28d506911861, lastActionTimestamp=2017-01-20T13:50:10.425), code=1700281, workCenterCode=0032, workCenterName=SYFPAC A, productCode=0100100, productName=AMINOPHYLLINE 250MG PPAMP 10ML, reasonCodesList=null, inProcessContro
DEBUG 14120 --- [nio-9090-exec-1] stomAnnotationTransactionAttributeSource : Adding transactional method 'save' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'transactionManager'
DEBUG 14120 --- [nio-9090-exec-1] o.s.orm.jpa.JpaTransactionManager : Found thread-bound EntityManager [org.hibernate.jpa.internal.EntityManagerImpl#2aa65d86] for JPA transaction
DEBUG 14120 --- [nio-9090-exec-1] o.s.orm.jpa.JpaTransactionManager : Participating in existing transaction
Hibernate: select production0_.transaction_id as transact1_20_1_, production0_.last_action_timestamp as last_act2_20_1_, production0_.code as code3_20_1_, production0_.product_code as product_4_20_1_, production0_.product_name as product_5_20_1_, production0_.work_center_code as work_cen6_20_1_, production0_.work_center_name as work_cen7_20_1_, inprocessc1_.production_order_transaction_id as producti5_18
DEBUG 14120 --- [nio-9090-exec-1] c.d.l.q.p.s.ProductionEventsService : Flushed production order: ProductionOrder(super=TransactionalEntity(transaction_id=0c4cb269-32fc-422d-93a8-28d506911861, lastActionTimestamp=2017-01-20T13:50:10.425), code=1700281, workCenterCode=0032, workCenterName=SYFPAC A, productCode=0100100, productName=AMINOPHYLLINE 250MG PPAMP 10ML, reasonCodesList=null, inProcessControl
DEBUG 14120 --- [nio-9090-exec-1] c.d.l.q.p.p.ProductionProjection : Event processed successfully by prod module: ProductionOrderStarted
DEBUG 14120 --- [nio-9090-exec-1] o.s.orm.jpa.JpaTransactionManager : Initiating transaction commit
DEBUG 14120 --- [nio-9090-exec-1] o.s.orm.jpa.JpaTransactionManager : Committing JPA transaction on EntityManager [org.hibernate.jpa.internal.EntityManagerImpl#2aa65d86]
Hibernate: insert into events.event (aggregate_id, correlation_id, data, event_type_id, time_created, version, event_id) values (?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into prod.production_order (last_action_timestamp, code, product_code, product_name, work_center_code, work_center_name, transaction_id) values (?, ?, ?, ?, ?, ?, ?)
DEBUG 14120 --- [nio-9090-exec-1] o.s.orm.jpa.JpaTransactionManager : Not closing pre-bound JPA EntityManager after transaction
DEBUG 14120 --- [nio-9090-exec-1] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
DEBUG 14120 --- [nio-9090-exec-1] o.j.s.OpenEntityManagerInViewInterceptor : Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
DEBUG 14120 --- [nio-9090-exec-1] o.s.orm.jpa.EntityManagerFactoryUtils : Closing JPA EntityManager
DEBUG 14120 --- [nio-9090-exec-1] o.s.web.servlet.DispatcherServlet : Successfully completed request
DEBUG 14120 --- [nio-9090-exec-1] o.s.b.w.f.OrderedRequestContextFilter : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade#17b5f8f0
Hibernate: select production0_.transaction_id as transact1_20_, production0_.last_action_timestamp as last_act2_20_, production0_.code as code3_20_, production0_.product_code as product_4_20_, production0_.product_name as product_5_20_, production0_.work_center_code as work_cen6_20_, production0_.work_center_name as work_cen7_20_ from prod.production_order production0_ where production0_.code=?
DEBUG 14120 --- [ main] c.DefaultCacheAwareContextLoaderDelegate : Retrieved ApplicationContext from cache with key [[WebMergedContextConfiguration#31206beb testClass = ProductionOrderStartLT, locations = '{}', classes = '{class com.demo.logbook.ElogbookApplication}', contextInitializerClasses = '[]', activeProfiles = '{test}', propertySourceLocations = '{}', propertySourceProperties = '{org.sp
DEBUG 14120 --- [ main] org.springframework.test.context.cache : Spring test ApplicationContext cache statistics: [DefaultContextCache#c677d7e size = 1, maxSize = 32, parentContextCount = 0, hitCount = 3, missCount = 1]
DEBUG 14120 --- [ main] c.DefaultCacheAwareContextLoaderDelegate : Retrieved ApplicationContext from cache with key [[WebMergedContextConfiguration#31206beb testClass = ProductionOrderStartLT, locations = '{}', classes = '{class com.demo.logbook.ElogbookApplication}', contextInitializerClasses = '[]', activeProfiles = '{test}', propertySourceLocations = '{}', propertySourceProperties = '{org.sp
DEBUG 14120 --- [ main] org.springframework.test.context.cache : Spring test ApplicationContext cache statistics: [DefaultContextCache#c677d7e size = 1, maxSize = 32, parentContextCount = 0, hitCount = 4, missCount = 1]
DEBUG 14120 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.boot.test.mock.mockito.MockitoBeans'
DEBUG 14120 --- [ main] c.DefaultCacheAwareContextLoaderDelegate : Retrieved ApplicationContext from cache with key [[WebMergedContextConfiguration#31206beb testClass = ProductionOrderStartLT, locations = '{}', classes = '{class com.demo.logbook.ElogbookApplication}', contextInitializerClasses = '[]', activeProfiles = '{test}', propertySourceLocations = '{}', propertySourceProperties = '{org.sp
DEBUG 14120 --- [ main] org.springframework.test.context.cache : Spring test ApplicationContext cache statistics: [DefaultContextCache#c677d7e size = 1, maxSize = 32, parentContextCount = 0, hitCount = 5, missCount = 1]
DEBUG 14120 --- [ main] o.s.orm.jpa.JpaTransactionManager : Initiating transaction rollback
DEBUG 14120 --- [ main] o.s.orm.jpa.JpaTransactionManager : Rolling back JPA transaction on EntityManager [org.hibernate.jpa.internal.EntityManagerImpl#505a8582]
DEBUG 14120 --- [ main] o.s.orm.jpa.JpaTransactionManager : Closing JPA EntityManager [org.hibernate.jpa.internal.EntityManagerImpl#505a8582] after transaction
DEBUG 14120 --- [ main] o.s.orm.jpa.EntityManagerFactoryUtils : Closing JPA EntityManager
INFO 14120 --- [ main] o.s.t.c.transaction.TransactionContext : Rolled back transaction for test context [DefaultTestContext#1dd02175 testClass = ProductionOrderStartLT, testInstance = com.demo.logbook.commandValidationLT.ProductionOrderStartLT#25359ed8, testMethod = when_EnteredRegisteredProductionOrder_and_RegisteredStaffSignature_then_201_and_ProductionOrderRegistered#ProductionOrderStart
DEBUG 14120 --- [ main] tractDirtiesContextTestExecutionListener : After test method: context [DefaultTestContext#1dd02175 testClass = ProductionOrderStartLT, testInstance = com.demo.logbook.commandValidationLT.ProductionOrderStartLT#25359ed8, testMethod = when_EnteredRegisteredProductionOrder_and_RegisteredStaffSignature_then_201_and_ProductionOrderRegistered#ProductionOrderStartLT, testExcept
Which seems that a new appplication context (and tread is used). How can I accomplish the above task? Is it the only way to use #AfterTranscation and clean my database for each test?
#Transactional only works within the same thread, and as such the rollback provided by Spring will only work on the objects that were persisted on the thread where the transaction was started.
Your rest-assured test will perform an integration test and will hit your Spring context on another thread. So although your rest-assured test would be able to see the objects persisted in your test setup, Spring will never be able to cleanup resources persisted in your rest-assured test automatically.
The only way to tackle this is to delete the entities yourself in your test (Using an Junit Rule, or cleaning up any state in your test setup).
I've been banging my head against this problem, and have managed to find a workaround for it. The problem is indeed caused by the fact that the JUnit test runs in a different thread as the embedded servlet container. This means that two transactions and database connections are opened, unaware of each other. The fix is to propagate the transaction that was opened in the JUnit test to the servlet container (using a Filter):
#Transactional
public class MyTest {
private static final String[] FIELD_NAMES = {"resources", "synchronizations", "currentTransactionName", "currentTransactionReadOnly", "currentTransactionIsolationLevel", "actualTransactionActive"};
private static final Field[] FIELDS = new Field[FIELD_NAMES.length];
private static final Object[] FIELD_VALUES = new Object[FIELD_NAMES.length];
#Before
public void copyTransactionThreadLocals() {
for (int i=0; i<FIELD_NAMES.length; i++) {
Field field = ReflectionUtils.findField(TransactionSynchronizationManager.class,FIELD_NAMES[i]);
field.setAccessible(true);
FIELD_VALUES[i] = ((ThreadLocal)ReflectionUtils.getField(field,null)).get();
FIELDS[i] = field;
}
}
#Configuration
static class Config {
#Bean
public Filter transactionFilter() {
return new OncePerRequestFilter() {
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
for (int i=0; i<FIELD_NAMES.length; i++) {
((ThreadLocal)ReflectionUtils.getField(FIELDS[i],null)).set(FIELD_VALUES[i]);
}
filterChain.doFilter(request,response);
}
};
}
}
}
Please be aware that the above code is a hack that uses reflection to copy inaccessible static fields.
With these integration tests, Spring is reusing its test context and the old transaction can stick around and cause tests to fail in weird ways due to state from previous tests. If you see tests that pass when run by themselves fail when run together, then annotate the tests with #DirtiesContext. This lets Spring know it should discard the test context instead of reusing it.