Problems with interaction between spring boot and extjs frontend - spring

I set up a project with Spring Boot 2.7 as backend and extjs 7.0.0 GPL as frontend.
I can send requests from extjs store to the backend (via jsonp e.g.), but unfortunately I really don't achieve to send requests from the spring boot backend to the extjs controller, i.e. stores.
I tried some approaches like urlrewrite or the integration of php code in the /webapp folder, but nothing of this was a solution for my problem.
Anyboy could give me some hints in order to solve my problem, please?
Greetings and thanks in advance
UPDATE
Ok, after preparing and facing other issues, I'm back to the above mentioned issue only...
First of all here my project structure in Eclipse
Here the code of Spring Boot application.properties
server.port=8080
spring.application.name=MyBankingApp
server.servlet.context-path=/MyBankingApp
spring.jpa.open-in-view=false
#Database Configrations
spring.datasource.url=jdbc:postgresql://xxx/mybanking
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.username=xxx
spring.datasource.password=xxx
spring.jpa.database-platform = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto = update
#Multipart
spring.servlet.multipart.enabled=true
spring.servlet.multipart.file-size-threshold=2KB
spring.servlet.multipart.max-file-size=200MB
spring.servlet.multipart.max-request-size=215MB
Here Spring Boot Application class with the main method
package com.mybanking;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#SpringBootApplication
public class MyBankingApplication implements ApplicationRunner {
public static void main(String[] args) {
SpringApplication.run(MyBankingApplication.class, args);
}
#Override
public void run(ApplicationArguments arg0) throws Exception {
System.out.println("Hello World from MyBankingApp Runner");
}
}
Here the code of the extjs class of the relevant store
Ext.define('MyBankingApp.store.User', {
extend: 'Ext.data.Store',
xtype: 'userStore',
id:'userStoreID',
requires: [
'MyBankingApp.model.User'
],
autoLoad: false,
model: 'MyBankingApp.model.User',
proxy: {
type: 'jsonp',
url:'http://localhost:8080/MyBankingApp/user',
//scope: this,
callbackKey: 'callback'
},
callback: function(records, operation, success) {
alert(success);
alert(records);
},
scope: this
});
and its corresponding java controller
package com.mybanking.controller;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import com.google.gson.Gson;
import com.mybanking.model.LoginUser;
import com.mybanking.model.User;
import com.mybanking.repository.UserRepository;
import com.mybanking.service.LoginUserService;
import com.mybanking.service.UserService;
#Controller
public class UserController {
#Autowired
private UserService userService;
#RequestMapping(value = "/user", method = RequestMethod.GET)
public String showUser(#RequestParam String _dc,
#RequestParam String callback,
HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) throws IOException {
var user = (List<User>) userService.showUser();
System.out.println("callback:\n");
System.out.println(callback);
String user_json = new Gson().toJson(user);
callback += user_json;
System.out.println(callback + '\n');
return callback;
}
}
Here the extjs view, where the UserStore is explicitely loaded in order to show the data retrieved from backend - what does not function
Ext.define('MyBankingApp.view.user.User', {
extend: 'Ext.container.Viewport',
xtype: 'userView',
renderTo: Ext.getBody(),
controller: 'userController',
layout: 'border',
title: 'User',
autoShow: true,
items: [{
xtype : 'tabpanel',
renderTo: Ext.getBody(),
title : 'MyBankingApp',
region : 'center',
controller: 'userController',
items : [{
title: 'User',
//collapsible: true,
items : [{
//xtype : 'grid',
xtype : 'window',
renderTo: Ext.getBody(),
region : 'center',
title : 'User List',
header : true,
store: 'MyBankingApp.store.User',
columns: [{
text: 'ID',
//width: 100,
sortable: false,
dataIndex: 'id'
},
{
text: 'Name',
//width: 100,
dataIndex: 'name'
},
{
text: 'Created',
flex: 1,
dataIndex: 'created',
renderer: Ext.util.Format.dateRenderer('Y-m-d')
}],
dockedItems: [{
xtype: 'pagingtoolbar',
store: 'MyBankingApp.store.User',
dock: 'bottom',
displayInfo: true
}],
listeners: {
beforerender: function() {
var store = Ext.getStore('MyBankingApp.store.User');
store.load();
console.log(store);
var url = store.getProxy().url;
var params = store.getProxy().extraParams;
console.log(url);
console.log(params);
/*
Ext.data.StoreManager.each( function(store) {
console.log(store.id);
});
*/
}
}
}],
},
{
title: 'User',
html: 'Tab content User'
}],
buttons: [{
text: 'Hello',
listeners: {
click: 'onClickButton'
}
}],
buttons: [{
text: 'Logout',
listeners: {
click: 'onClickButton1'
}
}]
}]
});
Here the error message thrown by the backend when I visit the UserView, where the store should be loaded:
2022-07-07 20:31:19.024 INFO 8272 --- [alina-utility-1] com.mybanking.ServletInitializer : Starting ServletInitializer v0.0.1-SNAPSHOT using Java 11.0.15.1 on WIN-86UTNGFROLK with PID 8272 (C:\Users\Administrator\eclipse-workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\MyBankingApp\WEB-INF\classes started by Administrator in C:\Windows\system32)
2022-07-07 20:31:19.029 INFO 8272 --- [alina-utility-1] com.mybanking.ServletInitializer : No active profile set, falling back to 1 default profile: "default"
2022-07-07 20:31:20.545 INFO 8272 --- [alina-utility-1] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2022-07-07 20:31:20.667 INFO 8272 --- [alina-utility-1] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 98 ms. Found 2 JPA repository interfaces.
2022-07-07 20:31:21.498 INFO 8272 --- [alina-utility-1] o.a.c.c.C.[.[localhost].[/MyBankingApp] : Initializing Spring embedded WebApplicationContext
2022-07-07 20:31:21.498 INFO 8272 --- [alina-utility-1] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2348 ms
2022-07-07 20:31:22.432 INFO 8272 --- [alina-utility-1] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2022-07-07 20:31:22.643 INFO 8272 --- [alina-utility-1] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.6.9.Final
2022-07-07 20:31:23.154 INFO 8272 --- [alina-utility-1] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2022-07-07 20:31:23.399 INFO 8272 --- [alina-utility-1] com.zaxxer.hikari.HikariDataSource : HikariPool-3 - Starting...
2022-07-07 20:31:23.617 INFO 8272 --- [alina-utility-1] com.zaxxer.hikari.HikariDataSource : HikariPool-3 - Start completed.
2022-07-07 20:31:23.659 INFO 8272 --- [alina-utility-1] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
2022-07-07 20:31:24.953 INFO 8272 --- [alina-utility-1] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2022-07-07 20:31:24.974 INFO 8272 --- [alina-utility-1] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2022-07-07 20:31:27.383 INFO 8272 --- [alina-utility-1] com.mybanking.ServletInitializer : Started ServletInitializer in 9.929 seconds (JVM running for 7520.221)
Hello World from MyBankingApp Runner
2022-07-07 20:31:27.436 INFO 8272 --- [alina-utility-1] o.a.c.c.C.[.[localhost].[/MyBankingApp] : Initializing Spring DispatcherServlet 'dispatcher'
2022-07-07 20:31:27.437 INFO 8272 --- [alina-utility-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcher'
2022-07-07 20:31:28.179 INFO 8272 --- [alina-utility-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 742 ms
2022-07-07 20:31:28.229 INFO 8272 --- [alina-utility-1] o.apache.catalina.core.StandardContext : Reloading Context with name [/MyBankingApp] is completed
2022-07-07 20:31:40.935 INFO 8272 --- [io-8080-exec-11] o.a.c.c.C.[.[localhost].[/MyBankingApp] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2022-07-07 20:31:40.936 INFO 8272 --- [io-8080-exec-11] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2022-07-07 20:31:40.937 INFO 8272 --- [io-8080-exec-11] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
callback:
Ext.data.JsonP.callback1
Ext.data.JsonP.callback1[{"id":1,"name":"user1","created":"2022-07-07 22:18:27.561538"},{"id":2,"name":"user2","created":"2022-07-07 22:18:39.292204"}]
2022-07-07 20:31:41.966 ERROR 8272 --- [io-8080-exec-11] org.thymeleaf.TemplateEngine : [THYMELEAF][http-nio-8080-exec-11] Exception processing template "Ext.data.JsonP.callback1[{"id":1,"n[...]2:18:27.561538"},{"id":2,"name":"user2","created":"2022-07-07 22:18:39.292204"}]": Error resolving template [Ext.data.JsonP.callback1[{"id":1,"name":"user1","created":"2022-07-07 22:18:27.561538"},{"id":2,"name":"user2","created":"2022-07-07 22:18:39.292204"}]], template might not exist or might not be accessible by any of the configured Template Resolvers
org.thymeleaf.exceptions.TemplateInputException: Error resolving template [Ext.data.JsonP.callback1[{"id":1,"name":"user1","created":"2022-07-07 22:18:27.561538"},{"id":2,"name":"user2","created":"2022-07-07 22:18:39.292204"}]], template might not exist or might not be accessible by any of the configured Template Resolvers
at org.thymeleaf.engine.TemplateManager.resolveTemplate(TemplateManager.java:869) ~[thymeleaf-3.0.15.RELEASE.jar:3.0.15.RELEASE]
at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:607) ~[thymeleaf-3.0.15.RELEASE.jar:3.0.15.RELEASE]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098) ~[thymeleaf-3.0.15.RELEASE.jar:3.0.15.RELEASE]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072) ~[thymeleaf-3.0.15.RELEASE.jar:3.0.15.RELEASE]
at org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:366) ~[thymeleaf-spring5-3.0.15.RELEASE.jar:3.0.15.RELEASE]
at org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:190) ~[thymeleaf-spring5-3.0.15.RELEASE.jar:3.0.15.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1401) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1145) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1084) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.21.jar:5.3.21]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[servlet-api.jar:4.0.FR]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.21.jar:5.3.21]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[servlet-api.jar:4.0.FR]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[catalina.jar:9.0.63]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.63]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-websocket.jar:9.0.63]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina.jar:9.0.63]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.63]
at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:126) ~[spring-boot-2.7.1.jar:2.7.1]
at org.springframework.boot.web.servlet.support.ErrorPageFilter.access$000(ErrorPageFilter.java:64) ~[spring-boot-2.7.1.jar:2.7.1]
at org.springframework.boot.web.servlet.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:101) ~[spring-boot-2.7.1.jar:2.7.1]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.21.jar:5.3.21]
at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:119) ~[spring-boot-2.7.1.jar:2.7.1]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina.jar:9.0.63]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.63]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.21.jar:5.3.21]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.21.jar:5.3.21]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina.jar:9.0.63]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.63]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[catalina.jar:9.0.63]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[catalina.jar:9.0.63]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[catalina.jar:9.0.63]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[catalina.jar:9.0.63]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[catalina.jar:9.0.63]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687) ~[catalina.jar:9.0.63]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[catalina.jar:9.0.63]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[catalina.jar:9.0.63]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-coyote.jar:9.0.63]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-coyote.jar:9.0.63]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890) ~[tomcat-coyote.jar:9.0.63]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743) ~[tomcat-coyote.jar:9.0.63]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-coyote.jar:9.0.63]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-util.jar:9.0.63]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-util.jar:9.0.63]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-util.jar:9.0.63]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
2022-07-07 20:31:41.969 ERROR 8272 --- [io-8080-exec-11] o.s.b.w.servlet.support.ErrorPageFilter : Forwarding to error page from request [/user] due to exception [Error resolving template [Ext.data.JsonP.callback1[{"id":1,"name":"user1","created":"2022-07-07 22:18:27.561538"},{"id":2,"name":"user2","created":"2022-07-07 22:18:39.292204"}]], template might not exist or might not be accessible by any of the configured Template Resolvers]
org.thymeleaf.exceptions.TemplateInputException: Error resolving template [Ext.data.JsonP.callback1[{"id":1,"name":"user1","created":"2022-07-07 22:18:27.561538"},{"id":2,"name":"user2","created":"2022-07-07 22:18:39.292204"}]], template might not exist or might not be accessible by any of the configured Template Resolvers
at org.thymeleaf.engine.TemplateManager.resolveTemplate(TemplateManager.java:869) ~[thymeleaf-3.0.15.RELEASE.jar:3.0.15.RELEASE]
at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:607) ~[thymeleaf-3.0.15.RELEASE.jar:3.0.15.RELEASE]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098) ~[thymeleaf-3.0.15.RELEASE.jar:3.0.15.RELEASE]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072) ~[thymeleaf-3.0.15.RELEASE.jar:3.0.15.RELEASE]
at org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:366) ~[thymeleaf-spring5-3.0.15.RELEASE.jar:3.0.15.RELEASE]
at org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:190) ~[thymeleaf-spring5-3.0.15.RELEASE.jar:3.0.15.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1401) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1145) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1084) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.21.jar:5.3.21]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.3.21.jar:5.3.21]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) ~[servlet-api.jar:4.0.FR]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.21.jar:5.3.21]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764) ~[servlet-api.jar:4.0.FR]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) ~[catalina.jar:9.0.63]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.63]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-websocket.jar:9.0.63]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina.jar:9.0.63]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.63]
at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:126) ~[spring-boot-2.7.1.jar:2.7.1]
at org.springframework.boot.web.servlet.support.ErrorPageFilter.access$000(ErrorPageFilter.java:64) ~[spring-boot-2.7.1.jar:2.7.1]
at org.springframework.boot.web.servlet.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:101) ~[spring-boot-2.7.1.jar:2.7.1]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.21.jar:5.3.21]
at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:119) ~[spring-boot-2.7.1.jar:2.7.1]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina.jar:9.0.63]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.63]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.21.jar:5.3.21]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) ~[spring-web-5.3.21.jar:5.3.21]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) ~[catalina.jar:9.0.63]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) ~[catalina.jar:9.0.63]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197) ~[catalina.jar:9.0.63]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[catalina.jar:9.0.63]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[catalina.jar:9.0.63]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135) ~[catalina.jar:9.0.63]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[catalina.jar:9.0.63]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687) ~[catalina.jar:9.0.63]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[catalina.jar:9.0.63]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360) ~[catalina.jar:9.0.63]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399) ~[tomcat-coyote.jar:9.0.63]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-coyote.jar:9.0.63]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890) ~[tomcat-coyote.jar:9.0.63]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743) ~[tomcat-coyote.jar:9.0.63]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-coyote.jar:9.0.63]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-util.jar:9.0.63]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-util.jar:9.0.63]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-util.jar:9.0.63]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
So now:
I'm testing on Windows 10 and Windows Server 2022, with same results
I'm developing in Eclipse / Spring Tool Suite 4
I'm testing with sencha app watch (localhost:1841) and Eclipse Tomcat 9 (localhost:8080) and also on a separate Tomcat 9 (localhost:80) instance
The exception shown above clearly says, that Spring tries to return the response to a Spring template and not to the sender (which isn't known by the backend)
But it also says, that the data could be retrieved successfully from the database, as it is shown in the built json string (2 sets)
But there do exist solutions in order to get what I want: Spring returns back its responses to Extjs, but I really don't know how I could achieve it.
Apart from the approaches I tried without success, I had to work with a similar project config like mine some years ago, but I really don't remember the details...

Related

Zuul Forwarding Exception caused by org.apache.http.NoHttpResponseException: The target server failed to respond

Hello Stack Overflow Community,
Been a while since I've asked a question so if I forget some information, just let me know and I will gladly add.
We have recently uncovered some issues occurring in our client-server. We are running a Spring server that handles client requests and renders HTML via Thymeleaf. We are using Zuul as a way to redirect our many client routes to a single Spring endpoint that serves up a single bundle so that no matter where a user refreshes, they will receive the bundle we want them to get. This seems to work most of the time but once every minute or so (out of thousands a minute) we get a zuul forwarding exception like so:
[2m2020-11-30 02:26:51.023[0;39m [33m WARN[0;39m [35m50[0;39m [2m---[0;39m [33m[trace=,span=][0;39m [2m[nio-8080-exec-2][0;39m [36mo.s.c.n.z.filters.post.SendErrorFilter [0;39m
[2m:[0;39m Error during filteringcom.netflix.zuul.exception.ZuulException: Forwarding error
 at
org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter.handleException(SimpleHostRoutingFilter.java:261) ~[spring-cloud-netflix-zuul-2.2.1.RELEASE.jar:2.2.1.RELEASE]
 at
org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter.run(SimpleHostRoutingFilter.java:241) ~[spring-cloud-netflix-zuul-2.2.1.RELEASE.jar:2.2.1.RELEASE]
 at
com.netflix.zuul.ZuulFilter.runFilter(ZuulFilter.java:117) ~[zuul-core-1.3.1.jar:1.3.1]
 at
com.netflix.zuul.FilterProcessor.processZuulFilter(FilterProcessor.java:193) ~[zuul-core-1.3.1.jar:1.3.1]
at com.netflix.zuul.FilterProcessor.runFilters(FilterProcessor.java:157) ~[zuul-core-1.3.1.jar:1.3.1]
 at
com.netflix.zuul.FilterProcessor.route(FilterProcessor.java:118) ~[zuul-core-1.3.1.jar:1.3.1]
 at
com.netflix.zuul.ZuulRunner.route(ZuulRunner.java:96) ~[zuul-core-1.3.1.jar:1.3.1]
 at
com.netflix.zuul.http.ZuulServlet.route(ZuulServlet.java:116) ~[zuul-core-1.3.1.jar:1.3.1]
 at
com.netflix.zuul.http.ZuulServlet.service(ZuulServlet.java:81) ~[zuul-core-1.3.1.jar:1.3.1]
 at
org.springframework.web.servlet.mvc.ServletWrappingController.handleRequestInternal(ServletWrappingController.java:166) [spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.springframework.cloud.netflix.zuul.web.ZuulController.handleRequest(ZuulController.java:45) [spring-cloud-netflix-zuul-2.2.1.RELEASE.jar:2.2.1.RELEASE]
 at
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:52) [spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) [spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) [spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) [spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) [tomcat-embed-core-9.0.37.jar:4.0.FR]
 at
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) [spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) [tomcat-embed-core-9.0.37.jar:4.0.FR]
 at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) [tomcat-embed-websocket-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.springframework.web.servlet.resource.ResourceUrlEncodingFilter.doFilter(ResourceUrlEncodingFilter.java:64) [spring-webmvc-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) [spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) [spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:109) [spring-boot-actuator-2.2.7.RELEASE.jar:2.2.7.RELEASE]
 at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) [spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.2.6.RELEASE.jar:5.2.6.RELEASE]
 at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.cloudfoundry.router.ClientCertificateMapper.doFilter(ClientCertificateMapper.java:79) [client_certificate_mapper-1.11.0_RELEASE.jar:na]
 at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:747) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1589) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_242]
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_242]
 at
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.37.jar:9.0.37]
 at java.lang.Thread.run(Thread.java:748) [na:1.8.0_242]

Caused by: org.apache.http.NoHttpResponseException: The target server failed to respond
 at
org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:141) ~[httpclient-4.5.12.jar:4.5.12]
 at
org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56) ~[httpclient-4.5.12.jar:4.5.12]
 at
org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259) ~[httpcore-4.4.13.jar:4.4.13]
 at
org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163) ~[httpcore-4.4.13.jar:4.4.13]
 at
org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:157) ~[httpclient-4.5.12.jar:4.5.12]
 at
org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273) ~[httpcore-4.4.13.jar:4.4.13]
 at
org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125) ~[httpcore-4.4.13.jar:4.4.13]
 at
org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272) ~[httpclient-4.5.12.jar:4.5.12]
 at
org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186) ~[httpclient-4.5.12.jar:4.5.12]
 at
org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) ~[httpclient-4.5.12.jar:4.5.12]
 at
org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) ~[httpclient-4.5.12.jar:4.5.12]
 at
org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:118) ~[httpclient-4.5.12.jar:4.5.12]
 at
org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter.forwardRequest(SimpleHostRoutingFilter.java:422) ~[spring-cloud-netflix-zuul-2.2.1.RELEASE.jar:2.2.1.RELEASE]
 at
org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter.forward(SimpleHostRoutingFilter.java:341) ~[spring-cloud-netflix-zuul-2.2.1.RELEASE.jar:2.2.1.RELEASE]
 at
org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter.run(SimpleHostRoutingFilter.java:236) ~[spring-cloud-netflix-zuul-2.2.1.RELEASE.jar:2.2.1.RELEASE]
 ... 61 common frames omitted
As you can see, we are using HttpClient 4.5.12. I saw similar issues occurring in 4.4 in this post but we upgraded and the issue persisted. In the same post #daimarom commented that perhaps the PoolingHttpClientConnectionManager could be causing an issue. This is how we configured our pool manager:
#Bean
public PoolingHttpClientConnectionManager connectionManager() {
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setValidateAfterInactivity(5000);
connectionManager.setDefaultMaxPerRoute(40);
connectionManager.setMaxTotal(15);
return connectionManager;
}
#Bean
public CloseableHttpClient httpClient() throws Exception {
return HttpClients.custom()
.disableAutomaticRetries()
.setSSLContext(sslContext())
.setSSLSocketFactory(socketFactory())
.setConnectionManager(connectionManager())
.setSSLHostnameVerifier(new NoopHostnameVerifier())
.build();
}
Playing aroung with the connection manager parameters did not help.
We had a Zuul filter but made our routing completely configuration based to rule out any logical errors. Currently our Zuul configuration looks like such:
zuul:
sensitive-headers:
host.socket-timeout-millis: 60000
routes:
api:
strip-prefix: false
path: /api/**
url: "${validation.urls.piserver}"
extract:
strip-prefix: true
path: /web2/extract/**
url: "${validation.urls.piclient}/validate"
legal:
strip-prefix: true
path: /web2/legal/**
url: "${validation.urls.piclient}/validate"
capture-vin:
strip-prefix: true
path: /web2/capture-instructions/vin/**
url: "${validation.urls.piclient}/validate"
recapture-vin:
strip-prefix: true
path: /web2/recapture-instructions/vin/**
url: "${validation.urls.piclient}/validate"
capture-odometer:
strip-prefix: true
path: /web2/capture-instructions/odometer/**
url: "${validation.urls.piclient}/validate"
recapture-odometer:
strip-prefix: true
path: /web2/recapture-instructions/odometer/**
url: "${validation.urls.piclient}/validate"
capture-rear:
strip-prefix: true
path: /web2/capture-instructions/rear/**
url: "${validation.urls.piclient}/validate"
recapture-rear:
strip-prefix: true
path: /web2/recapture-instructions/rear/**
url: "${validation.urls.piclient}/validate"
capture-rear-passenger:
strip-prefix: true
path: /web2/capture-instructions/rear-passenger/**
url: "${validation.urls.piclient}/validate"
recapture-rear-passenger:
strip-prefix: true
path: /web2/recapture-instructions/rear-passenger/**
url: "${validation.urls.piclient}/validate"
capture-front-passenger:
strip-prefix: true
path: /web2/capture-instructions/front-passenger/**
url: "${validation.urls.piclient}/validate"
recapture-front-passenger:
strip-prefix: true
path: /web2/recapture-instructions/front-passenger/**
url: "${validation.urls.piclient}/validate"
capture-front-driver:
strip-prefix: true
path: /web2/capture-instructions/front-driver/**
url: "${validation.urls.piclient}/validate"
recapture-front-driver:
strip-prefix: true
path: /web2/recapture-instructions/front-driver/**
url: "${validation.urls.piclient}/validate"
capture-rear-driver:
strip-prefix: true
path: /web2/capture-instructions/rear-driver/**
url: "${validation.urls.piclient}/validate"
recapture-rear-driver:
strip-prefix: true
path: /web2/recapture-instructions/rear-driver/**
url: "${validation.urls.piclient}/validate"
capture-damage-left:
strip-prefix: true
path: /web2/capture-instructions/damage-left/**
url: "${validation.urls.piclient}/validate"
recapture-damage-left:
strip-prefix: true
path: /web2/recapture-instructions/damage-left/**
url: "${validation.urls.piclient}/validate"
capture-damage-center:
strip-prefix: true
path: /web2/damage-capture-instructions/damage-center/**
url: "${validation.urls.piclient}/validate"
recapture-damage-center:
strip-prefix: true
path: /web2/damage-recapture-instructions/damage-center/**
url: "${validation.urls.piclient}/validate"
capture-damage-right:
strip-prefix: true
path: /web2/damage-capture-instructions/damage-right/**
url: "${validation.urls.piclient}/validate"
recapture-damage-right:
strip-prefix: true
path: /web2/damage-recapture-instructions/damage-right/**
url: "${validation.urls.piclient}/validate"
capture-damages:
strip-prefix: true
path: /web2/capture-instructions/damages/**
url: "${validation.urls.piclient}/validate"
recapture-damages:
strip-prefix: true
path: /web2/recapture-instructions/damages/**
url: "${validation.urls.piclient}/validate"
uploading:
strip-prefix: true
path: /web2/uploading/**
url: "${validation.urls.piclient}/validate"
submit:
strip-prefix: true
path: /submit/**
url: "${validation.urls.piclient}/validate"
intake-processing:
strip-prefix: true
path: /intake-processing/**
url: "${validation.urls.piclient}/validate"
already-submitted:
strip-prefix: true
path: /already-submitted/**
url: "${validation.urls.piclient}/validate"
submit-v1:
strip-prefix: true
path: /submit
url: "${validation.urls.piclient}/validate"
intake-processing-v1:
strip-prefix: true
path: /intake-processing
url: "${validation.urls.piclient}/validate"
already-submitted-v1:
strip-prefix: true
path: /already-submitted
url: "${validation.urls.piclient}/validate"
This used to be much more succinct in the routing filter when we simply reset the request URI in the current context but as I mentioned before, now this is all configuration based.
All of our dependencies are defined here:
dependencies {
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
implementation 'org.yaml:snakeyaml:1.26'
implementation 'io.github.openfeign:feign-httpclient:10.7.4'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-zuul'
implementation 'org.apache.tomcat.embed:tomcat-embed-core:9.0.37'
implementation 'org.apache.tomcat.embed:tomcat-embed-el:9.0.37'
implementation 'org.apache.tomcat.embed:tomcat-embed-websocket:9.0.37'
implementation 'org.springframework.cloud:spring-cloud-cloudfoundry-connector'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
I feel like I am missing something completely obvious here but our manager who was very experienced with Zuul recently left. Please let me know if there is any additional information I can add here. Thank you in advance for any help.
[UPDATE]
I have recently attempted taking the entire pool manager out of the configuration. The problem has persisted. Now the configuration for the HttpClient looks like the following:
#Bean
public CloseableHttpClient httpClient() throws Exception {
return HttpClients.custom()
.disableAutomaticRetries()
.setSSLContext(sslContext())
.setSSLSocketFactory(socketFactory())
// .setConnectionManager(connectionManager())
.setSSLHostnameVerifier(new NoopHostnameVerifier())
.build();
}
Also, we tried with and without a spring security configuration chain explicitly defined. Nothing helped.
Ok so #brijesh mentioned a potential solution in the comments that I have yet to try but I did end up deploying another "fixing" change. It's more of a recovery from the issue which is mostly likely still occurring. I simply enabled automatic retrying by commenting out the following line:
#Bean
public CloseableHttpClient httpClient() throws Exception {
return HttpClients.custom()
// .disableAutomaticRetries()
.setSSLContext(sslContext())
.setSSLSocketFactory(socketFactory())
.setConnectionManager(connectionManager())
.setSSLHostnameVerifier(new NoopHostnameVerifier())
.build();
}
For anyone who does not explicitly configure their HttpClient settings, this shouldn't be an issue since the default is to retry 3 times.
For people who do configure these settings and are having issues with the connection manager, I will soon attempt #brijesh's approach (with automatic retrying disabled) to see if the solution resolves the root cause. I will update the answer here once I've completed this.

Failed parsing Thymeleaf template when validating form with Spring Bean Validation API

I am following this book "Spring In Action 5th Edition" example, but having this error whenever validation on form input found something invalid.
error:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Sun Oct 27 17:26:07 SGT 2019
There was an unexpected error (type=Internal Server Error, status=500).
An error happened during template parsing (template: "class path resource [templates/design.html]")
org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/design.html]")
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:241)
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parseStandalone(AbstractMarkupTemplateParser.java:100)
at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:666)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1098)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1072)
at org.thymeleaf.spring5.view.ThymeleafView.renderFragment(ThymeleafView.java:362)
at org.thymeleaf.spring5.view.ThymeleafView.render(ThymeleafView.java:189)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1371)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1117)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1056)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:118)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:853)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.attoparser.ParseException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor' (template: "design" - line 59, col 20)
at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:393)
at org.attoparser.MarkupParser.parse(MarkupParser.java:257)
at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:230)
... 52 more
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor' (template: "design" - line 59, col 20)
at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:117)
at org.thymeleaf.processor.element.AbstractElementTagProcessor.process(AbstractElementTagProcessor.java:95)
at org.thymeleaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633)
at org.thymeleaf.engine.ProcessorTemplateHandler.handleStandaloneElement(ProcessorTemplateHandler.java:918)
at org.thymeleaf.engine.TemplateHandlerAdapterMarkupHandler.handleStandaloneElementEnd(TemplateHandlerAdapterMarkupHandler.java:260)
at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler$InlineMarkupAdapterPreProcessorHandler.handleStandaloneElementEnd(InlinedOutputExpressionMarkupHandler.java:256)
at org.thymeleaf.standard.inline.OutputExpressionInlinePreProcessorHandler.handleStandaloneElementEnd(OutputExpressionInlinePreProcessorHandler.java:169)
at org.thymeleaf.templateparser.markup.InlinedOutputExpressionMarkupHandler.handleStandaloneElementEnd(InlinedOutputExpressionMarkupHandler.java:104)
at org.attoparser.HtmlElement.handleStandaloneElementEnd(HtmlElement.java:79)
at org.attoparser.HtmlMarkupHandler.handleStandaloneElementEnd(HtmlMarkupHandler.java:241)
at org.attoparser.MarkupEventProcessorHandler.handleStandaloneElementEnd(MarkupEventProcessorHandler.java:327)
at org.attoparser.ParsingElementMarkupUtil.parseStandaloneElement(ParsingElementMarkupUtil.java:96)
at org.attoparser.MarkupParser.parseBuffer(MarkupParser.java:706)
at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:301)
... 54 more
Caused by: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'design' available as request attribute
at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:153)
at org.springframework.web.servlet.support.RequestContext.getBindStatus(RequestContext.java:903)
at org.thymeleaf.spring5.context.webmvc.SpringWebMvcThymeleafRequestContext.getBindStatus(SpringWebMvcThymeleafRequestContext.java:227)
at org.thymeleaf.spring5.util.FieldUtils.getBindStatusFromParsedExpression(FieldUtils.java:306)
at org.thymeleaf.spring5.util.FieldUtils.getBindStatus(FieldUtils.java:253)
at org.thymeleaf.spring5.util.FieldUtils.getBindStatus(FieldUtils.java:227)
at org.thymeleaf.spring5.processor.AbstractSpringFieldTagProcessor.doProcess(AbstractSpringFieldTagProcessor.java:174)
at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74)
... 67 more
Object been passed to view template:
package tacos;
import java.util.List;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import lombok.Data;
#Data
public class Taco {
#NotNull
#Size(min=5, message="Name must be at least 5 characters long")
private String name;
#NotNull
#Size(min=2, message="You must choose at least 2 ingredient")
private List<String> ingredients;
}
Thymeleaf view template:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Taco Cloud</title>
<link rel="stylesheet" th:href="#{/styles.css}" />
</head>
<body>
<h1>Design your taco!</h1>
<img th:src="#{/images/TacoCloud.png}"/>
<form method="POST" th:object="${design}">
<div class="grid">
<div class="ingredient-group" id="wraps">
<h3>Designate your wrap:</h3>
<div th:each="ingredient : ${wrap}">
<input name="ingredients" type="checkbox" th:value="${ingredient.id}"
/>
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<div class="ingredient-group" id="proteins">
<h3>Pick your protein:</h3>
<div th:each="ingredient : ${protein}">
<input name="ingredients" type="checkbox" th:value="${ingredient.id}"
/>
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<div class="ingredient-group" id="cheeses">
<h3>Choose your cheese:</h3>
<div th:each="ingredient : ${cheese}">
<input name="ingredients" type="checkbox" th:value="${ingredient.id}"
/>
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<div class="ingredient-group" id="veggies">
<h3>Determine your veggies:</h3>
<div th:each="ingredient : ${veggies}">
<input name="ingredients" type="checkbox" th:value="${ingredient.id}"
/>
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
<div class="ingredient-group" id="sauces">
<h3>Select your sauce:</h3>
<div th:each="ingredient : ${sauce}">
<input name="ingredients" type="checkbox" th:value="${ingredient.id}"
/>
<span th:text="${ingredient.name}">INGREDIENT</span><br/>
</div>
</div>
</div>
<div>
<h3>Name your taco creation:</h3>
<input type="text" th:field="*{name}"/>
<span class="validationError"
th:if="${#fields.hasErrors('name')}"
th:errors="*{name}">Name Error</span>
<br/>
<button>Submit your taco</button>
</div>
</form>
</body>
</html>
Controller display form method:
#GetMapping
public String showDesignForm(Model model)
{
List<Ingredient> ingredients = Arrays.asList(
new Ingredient("FLTO", "Flour Tortilla", Type.WRAP),
new Ingredient("COTO", "Corn Tortilla", Type.WRAP),
new Ingredient("GRBF", "Ground Beef", Type.PROTEIN),
new Ingredient("CARN", "Carnitas", Type.PROTEIN),
new Ingredient("TMTO", "Diced Tomatoes", Type.VEGGIES),
new Ingredient("LETC", "Lettuce", Type.VEGGIES),
new Ingredient("CHED", "Cheddar", Type.CHEESE),
new Ingredient("JACK", "Monterrey Jack", Type.CHEESE),
new Ingredient("SLSA", "Salsa", Type.SAUCE),
new Ingredient("SRCR", "Sour Cream", Type.SAUCE)
);
Type[] types = Ingredient.Type.values();
for (Type type : types)
{
model.addAttribute(type.toString().toLowerCase(),
filterByType(ingredients, type));
}
model.addAttribute("design", new Taco());
return "design";
}
Controller process form method:
#PostMapping
public String processDesign(#Valid Taco taco, Errors errors)
{
if (errors.hasErrors())
{
return "design";
}
// Save the taco design...
// We will do this in chapter 3
log.info("Processing design: " + taco);
return "redirect:/orders/current";
}
I have no issue in displaying the form. All input fields are well received and processed. But whenever there is validation errors, and process form method call back to the form page "design", the form failed to parse with above mentioned errors.
I had tried:1. to disable validation on the Taco.name field;2. to remove the <span> which displays the name field errors. But none of them work.
Thanks in advance for your help.
I try change this code
#PostMapping
public String processDesign(#Valid Taco taco, Errors errors)
{
if (errors.hasErrors())
{
return "design";
}
// Save the taco design...
// We will do this in chapter 3
log.info("Processing design: " + taco);
return "redirect:/orders/current";
}
to
#PostMapping
public String processDesign(#Valid Taco taco, Errors errors)
{
if (errors.hasErrors())
{
return "redirect:/design";
}
// Save the taco design...
// We will do this in chapter 3
log.info("Processing design: " + taco);
return "redirect:/orders/current";
}
and it works.
I had a similar problem. This is what I did to fix it.
1st - change the opening header in design.html to the following
<form method="POST" th:object="${design}">
2nd - my processDesign() method looks like this:
public String processDesign(#Valid #ModelAttribute("design") Taco taco, Errors errors) {
if (errors.hasErrors()) {
return "design";
}
// this will save our Taco Design
// log.info("Processing design: " + design);
return "redirect:/orders/current";
}
I hope, that this helps and I'm not too late. In general, there are multiple similar errors in the book, that need to be fixed, but the community around it is great, so no need to worry.
Cheers
The code in book has some error, here is the right code from the github of book:
// tag::head[]
package tacos.web;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import lombok.extern.slf4j.Slf4j;
import tacos.Ingredient;
import tacos.Ingredient.Type;
import tacos.Taco;
#Slf4j
#Controller
#RequestMapping("/design")
public class DesignTacoController {
//end::head[]
#ModelAttribute
public void addIngredientsToModel(Model model) {
List<Ingredient> ingredients = Arrays.asList(
new Ingredient("FLTO", "Flour Tortilla", Type.WRAP),
new Ingredient("COTO", "Corn Tortilla", Type.WRAP),
new Ingredient("GRBF", "Ground Beef", Type.PROTEIN),
new Ingredient("CARN", "Carnitas", Type.PROTEIN),
new Ingredient("TMTO", "Diced Tomatoes", Type.VEGGIES),
new Ingredient("LETC", "Lettuce", Type.VEGGIES),
new Ingredient("CHED", "Cheddar", Type.CHEESE),
new Ingredient("JACK", "Monterrey Jack", Type.CHEESE),
new Ingredient("SLSA", "Salsa", Type.SAUCE),
new Ingredient("SRCR", "Sour Cream", Type.SAUCE)
);
Type[] types = Ingredient.Type.values();
for (Type type : types) {
model.addAttribute(type.toString().toLowerCase(),
filterByType(ingredients, type));
}
}
//tag::showDesignForm[]
#GetMapping
public String showDesignForm(Model model) {
model.addAttribute("design", new Taco());
return "design";
}
//end::showDesignForm[]
/*
//tag::processDesign[]
#PostMapping
public String processDesign(Design design) {
// Save the taco design...
// We'll do this in chapter 3
log.info("Processing design: " + design);
return "redirect:/orders/current";
}
//end::processDesign[]
*/
//tag::processDesignValidated[]
#PostMapping
public String processDesign(#Valid #ModelAttribute("design") Taco design, Errors errors, Model model) {
if (errors.hasErrors()) {
return "design";
}
// Save the taco design...
// We'll do this in chapter 3
log.info("Processing design: " + design);
return "redirect:/orders/current";
}
//end::processDesignValidated[]
//tag::filterByType[]
private List<Ingredient> filterByType(
List<Ingredient> ingredients, Type type) {
return ingredients
.stream()
.filter(x -> x.getType().equals(type))
.collect(Collectors.toList());
}
//end::filterByType[]
// tag::foot[]
}
// end::foot[]
and you can get all the source code from https://github.com/habuma/spring-in-action-5-samples
ps: In my opinion, the possible reason is that #valide Taco will transport a Taco object named taco to the template, while we use the design in the tempalte, so, the template cannot find the design which result in the error. And #ModelAttribute('design') can renamed the Taco object to design. On the other hand, we need the ingredients list to init the template whenever we visit the tacoDesign html, that is the reason that we separate the addIngredientsToModel method and using #ModelAttribute above it.

Can't generate html page into pdf with wkhtmltopdf in spring

In my recent spring project, I need to generate a pdf file from html page. I am trying to do this task with WkhtmlToPdf. But i am unable to generate pdf file from html page. I search many project and tutorial about WkhtmlToPdf but I didn't find any answer. I am posting my code here.
This is my Controller class that redirect to html page with student list
#Controller
public class TestController {
#Autowired
StudentService studentService;
#Autowired
PdfDemo pdfDemo;
#GetMapping("/test")
private String testPage(Model model)
{
List<Student> studentList = studentService.findAll();
System.out.println(studentList);
model.addAttribute(studentList);
return "sample";
}
}
This is my html page that show list of student
<body>
<div class="container" id="pdfDiv">
<h2>HTML Table</h2>
<table class="table table-striped">
<tr>
<th>Id</th>
<th>Name</th>
<th>Session</th>
<th>Department</th>
<th>Roll</th>
<th>Mobile</th>
</tr>
<tr th:each="student : ${studentList}">
<td th:text="${student.id}"></td>
<td th:text="${student.name}"></td>
<td th:text="${student.session}"></td>
<td th:text="${student.department}"></td>
<td th:text="${student.roll}"></td>
<td th:text="${student.mobile}"></td>
</tr>
</table>
</div>
Download PDF
</body>
Here you can see, I have a link to generate pdf. The PdfGenerateController class is
#Controller
public class PdfGenerateController {
#GetMapping("/getStudentsListAsPdf")
public ResponseEntity<Resource> generateReportOfStudent() {
String downloadFilePath = generatePdfListForStudents();
System.out.println("DL File Path: "+downloadFilePath);
if (downloadFilePath == null)
throw new NullPointerException("data missing");
if (downloadFilePath == null)
return ResponseEntity.badRequest()
.contentType(MediaType.parseMediaType("application/pdf"))
.body(null);
File file = new File(downloadFilePath);
Path path = Paths.get(file.getAbsolutePath());
ByteArrayResource resource = null;
try {
resource = new ByteArrayResource(Files.readAllBytes(path));
} catch (IOException e) {
e.printStackTrace();
}
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "attachment; filename=\"student_list" + ".pdf\"");
return ResponseEntity.ok()
.headers(headers)
.contentLength(file.length())
.contentType(MediaType.parseMediaType("application/pdf"))
.body(resource);
}
}
And this is the class where code are written to generate pdf
#Service
public class PdfDemo {
#Value("${file.download.base}")
private String DOWNLOAD_FOLDER;
public static final String DOWNLOAD_PATH = "tmp/downloads/";
public static final String ZIP_PATH = "/tmp/zip_files";
public static final String FILE_NAME = "student_list";
public static final String SERVER_REPORT_URL = "/report/html";
public static final String DOWNLOAD_FILE_PATH = DOWNLOAD_PATH + FILE_NAME;
public static final String ZIPFILE = "/tmp/zip_files/cmed_report.zip";
public static final String ZIPFILE_NAME = "cmed_report.zip";
public static final String SRCDIR = "/tmp/downloads";
public static final String DATE_FORMAT_PATTERN = "yyyy-MM-dd-HH";
public static String getBaseURL() throws MalformedURLException {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
.getRequestAttributes()).getRequest();
String baseUrl = "";
if (request != null) {
// handle proxy forward
String scheme = request.getScheme();
if (request.getHeader("x-forwarded-proto") != null) {
scheme = request.getHeader("x-forwarded-proto");
}
Integer serverPort = request.getServerPort();
if ((serverPort == 80) || (serverPort == 443)) {
// No need to add the server port for standard HTTP and HTTPS ports, the scheme will help determine it.
baseUrl = String.format("%s://%s%s", scheme, request.getServerName(), request.getContextPath());
} else {
baseUrl = String.format("%s://%s:%d%s", scheme, request.getServerName(), serverPort, request.getContextPath());
}
}
return baseUrl;
}
public static String generatePdfListForStudents()
{
WkHtmlToPdf pdf = new WkHtmlToPdf();
try {
pdf.addSources(Source.fromUrl(getServerAbsolutePath(SERVER_REPORT_URL)));
System.out.println("Server absolute path: " + getServerAbsolutePath(SERVER_REPORT_URL));
System.out.println(Source.fromUrl(getServerAbsolutePath(SERVER_REPORT_URL)));
} catch (Exception e) {
e.printStackTrace();
}
String downloadPath = DOWNLOAD_FILE_PATH + ".pdf";
pdf.addArguments(
Argument.from(EnableJavascript));
System.out.println("PDF Location: " + downloadPath);
// Save the PDF
File file = new File(downloadPath);
System.out.println("Directory status: " + file.exists() + " " + file.isDirectory());
try {
System.out.println("Paths.get: " + Paths.get(downloadPath));
pdf.save(Paths.get(downloadPath));
} catch (IOException e) {
e.printStackTrace();
}
return downloadPath;
}
public static String getServerAbsolutePath(String requestPath) throws MalformedURLException {
String URL = getBaseURL() + requestPath;
return URL;
}
}
And this is the Controller class for SERVER_REPORT_URL in PdfDemo class
#Controller
public class HtmlViewReportController {
#Autowired
StudentService studentService;
#GetMapping(value = "/report/html")
public String getPdfReportForStudent(Model model) {
model.addAttribute("studentList", studentService.findAll());
return "sample";
}
}
Now, When I hit on Download PDFin html page I get error. Error stack trace here
java.io.IOException: Cannot run program "wkhtmltopdf": error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at java.lang.Runtime.exec(Runtime.java:620)
at java.lang.Runtime.exec(Runtime.java:528)
at com.ztomic.wkhtmltopdf.WkHtmlToPdf.convert(WkHtmlToPdf.java:84)
at com.ztomic.wkhtmltopdf.WkHtmlToPdf.getPdfBytes(WkHtmlToPdf.java:77)
at com.ztomic.wkhtmltopdf.WkHtmlToPdf.save(WkHtmlToPdf.java:68)
at com.avijit.test.PdfUtil.PdfDemo.generatePdfListForStudents(PdfDemo.java:109)
at com.avijit.test.Controller.PdfGenerateController.generateReportOfStudent(PdfGenerateController.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:90)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:155)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:123)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:108)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.io.IOException: error=2, No such file or directory
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)
at java.lang.ProcessImpl.start(ProcessImpl.java:134)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
... 71 more
DL File Path: tmp/downloads/student_list.pdf
java.nio.file.NoSuchFileException: /home/dracula/IdeaProjects/WkhtmlToPdfGeneratorProject/tmp/downloads/student_list.pdf
at sun.nio.fs.UnixException.translateToIOException(UnixException.java:86)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:214)
at java.nio.file.Files.newByteChannel(Files.java:361)
at java.nio.file.Files.newByteChannel(Files.java:407)
at java.nio.file.Files.readAllBytes(Files.java:3152)
at com.avijit.test.Controller.PdfGenerateController.generateReportOfStudent(PdfGenerateController.java:43)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:866)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:90)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:155)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:123)
at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:108)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Here the github link. It will be very helpful if any one can solve this.
Did you install wkhtmltopdf in your machine ? try it on https://wkhtmltopdf.org/downloads.html
I did it in a simpler way using Pdf Object from
import com.github.jhonnymertz.wkhtmltopdf.wrapper.Pdf;
The generation of pdf looks easier as follows:
#Override
public String save(String url) throws IOException, InterruptedException{
Pdf pdf = new Pdf();
pdf.addPageFromUrl(url);
return mockSaveS3(pdf);
}
private String mockSaveS3(Pdf pdf) throws IOException, InterruptedException{
File fileTemp = File.createTempFile("pdf-", "");
File file = pdf.saveAs("apps/" + fileTemp.getName());
return file.getAbsolutePath();
}
And I returned the Url to the PDF that I stored in apps/ directory.
I solved this problem. It took a long time to solve. I wrote a blog step by step in the medium. Here I am posting that link. You can see all the steps here. I also provided github link of sample project. Look
here

Spring Boot Security Login - "Wrong Credentials" Error

I am trying to implement login and registration. Registering users works fine, but when I attempt to log in I keep getting Wrong Credentials error. Below is my code. I want users to log in with their email and password, so I'm really not sure if I'm missing something or if this is the way to go, because all tutorials out there show login examples using username and password.
I am new to spring and still learning, so any help I get would be much appreciated.
My WebSecurityConfig class:
#Configuration
#EnableWebSecurity
#ComponentScan(basePackageClasses = CustomUserDetailsService.class)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
DataSource dataSource;
#Autowired
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/test").authenticated()
.and()
.formLogin()
.loginPage("/login")
.usernameParameter("email").passwordParameter("password")
.defaultSuccessUrl("/test")
.failureUrl("/login?error")
.and()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/authentication/login")
.permitAll();
}
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl tokenRepo = new JdbcTokenRepositoryImpl();
tokenRepo.setDataSource(dataSource);
return tokenRepo;
}
#Bean
public UserDetailsService userDetailsService() {
return super.userDetailsService();
}
}
CustomUserDetailsService
#Service
public class CustomUserDetailsService implements UserDetailsService{
private final UserRepository userRepository;
private final RoleRepository roleRepository;
#Autowired
public CustomUserDetailsService(UserRepository userRepository, RoleRepository roleRepository) {
this.userRepository = userRepository;
this.roleRepository = roleRepository;
}
#Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
User user = userRepository.findByEmail(email);
if(user == null) {
throw new UsernameNotFoundException("User not found" + email);
}
else {
/*
List<String> userRoles = roleRepository.findRoleByUserId(user.getUserId());
return new CustomUserDetails(user, userRoles);
*/
List<Role> roles = new ArrayList<Role>();
roles.add(user.getRole());
return new CustomUserDetails(user, roles);
}
}
}
login.html
<div th:if="${success}" class="alert alert-success" role="alert" th:text="${success}"></div>
<div th:if="${error}" class="alert alert-danger" role="alert" th:text="${error}"></div>
<form method="post" th:action="#{/login}" th:object="${user}">
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input class="form-control" id="exampleInputEmail1" name="email" type="email" th:field="*{email}" aria-describedby="emailHelp" placeholder="Enter email">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input class="form-control" id="exampleInputPassword1" name="password" type="password" th:field="*{password}" placeholder="Password">
</div>
<div class="form-group">
<div class="form-check">
<label class="form-check-label">
<input class="form-check-input" type="checkbox" name="remember-me"> Remember Password</label>
</div>
</div>
<button class="btn btn-primary btn-block" type="submit">Login</button>
</form>
Stack trace:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.10.RELEASE)
2018-02-06 10:51:09.972 INFO 7116 --- [ main] c.b.app.SpringBootcampApplication : Starting SpringBootcampApplication on localhost.localdomain with PID 7116 (started by cuteowl in /home/cuteowl/Documents/Work/JAVA SPRING PROJECT/SpringBootcamp)
2018-02-06 10:51:09.975 INFO 7116 --- [ main] c.b.app.SpringBootcampApplication : No active profile set, falling back to default profiles: default
2018-02-06 10:51:10.287 INFO 7116 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#646be2c3: startup date [Tue Feb 06 10:51:10 CET 2018]; root of context hierarchy
2018-02-06 10:51:11.704 INFO 7116 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$319d2e5a] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-02-06 10:51:12.285 INFO 7116 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2018-02-06 10:51:12.318 INFO 7116 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2018-02-06 10:51:12.320 INFO 7116 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.27
2018-02-06 10:51:12.502 INFO 7116 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2018-02-06 10:51:12.502 INFO 7116 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2218 ms
2018-02-06 10:51:12.743 INFO 7116 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-02-06 10:51:12.743 INFO 7116 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-02-06 10:51:12.743 INFO 7116 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-02-06 10:51:12.743 INFO 7116 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2018-02-06 10:51:12.745 INFO 7116 --- [ost-startStop-1] .s.DelegatingFilterProxyRegistrationBean : Mapping filter: 'springSecurityFilterChain' to: [/*]
2018-02-06 10:51:12.745 INFO 7116 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2018-02-06 10:51:13.419 INFO 7116 --- [ main] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
2018-02-06 10:51:13.438 INFO 7116 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
name: default
...]
2018-02-06 10:51:13.592 INFO 7116 --- [ main] org.hibernate.Version : HHH000412: Hibernate Core {5.0.12.Final}
2018-02-06 10:51:13.593 INFO 7116 --- [ main] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found
2018-02-06 10:51:13.594 INFO 7116 --- [ main] org.hibernate.cfg.Environment : HHH000021: Bytecode provider name : javassist
2018-02-06 10:51:13.632 INFO 7116 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
2018-02-06 10:51:13.739 INFO 7116 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
2018-02-06 10:51:14.232 INFO 7116 --- [ main] org.hibernate.tool.hbm2ddl.SchemaUpdate : HHH000228: Running hbm2ddl schema update
2018-02-06 10:51:14.243 INFO 7116 --- [ main] rmationExtractorJdbcDatabaseMetaDataImpl : HHH000262: Table not found: roles
2018-02-06 10:51:14.244 INFO 7116 --- [ main] rmationExtractorJdbcDatabaseMetaDataImpl : HHH000262: Table not found: roles
2018-02-06 10:51:14.412 INFO 7116 --- [ main] rmationExtractorJdbcDatabaseMetaDataImpl : HHH000262: Table not found: users
2018-02-06 10:51:14.414 INFO 7116 --- [ main] rmationExtractorJdbcDatabaseMetaDataImpl : HHH000262: Table not found: users
2018-02-06 10:51:15.429 INFO 7116 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2018-02-06 10:51:16.419 INFO 7116 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: org.springframework.security.web.util.matcher.AnyRequestMatcher#1, [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter#54895681, org.springframework.security.web.context.SecurityContextPersistenceFilter#28daf506, org.springframework.security.web.header.HeaderWriterFilter#5a47730c, org.springframework.security.web.csrf.CsrfFilter#440ef8d, org.springframework.security.web.authentication.logout.LogoutFilter#4e48462d, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter#633ddc0c, org.springframework.security.web.savedrequest.RequestCacheAwareFilter#693f2213, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter#7ac48f05, org.springframework.security.web.authentication.AnonymousAuthenticationFilter#2dd0a0d0, org.springframework.security.web.session.SessionManagementFilter#1cde374, org.springframework.security.web.access.ExceptionTranslationFilter#46612bfc, org.springframework.security.web.access.intercept.FilterSecurityInterceptor#3cc3f13e]
2018-02-06 10:51:16.709 INFO 7116 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for #ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#646be2c3: startup date [Tue Feb 06 10:51:10 CET 2018]; root of context hierarchy
2018-02-06 10:51:16.795 INFO 7116 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/login],methods=[GET]}" onto public java.lang.String com.bootcamp.app.controllers.LoginController.showLoginPage(org.springframework.ui.Model,com.bootcamp.app.models.User,java.util.Optional<java.lang.String>,java.util.Optional<java.lang.String>)
2018-02-06 10:51:16.797 INFO 7116 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/register],methods=[GET]}" onto public java.lang.String com.bootcamp.app.controllers.RegisterController.showRegisterPage(org.springframework.ui.Model,com.bootcamp.app.models.User)
2018-02-06 10:51:16.797 INFO 7116 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/register/new-user],methods=[POST]}" onto public java.lang.String com.bootcamp.app.controllers.RegisterController.postRegisterPage(org.springframework.ui.Model,com.bootcamp.app.models.User,org.springframework.validation.BindingResult,javax.servlet.http.HttpServletRequest)
2018-02-06 10:51:16.797 INFO 7116 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/confirm],methods=[GET]}" onto public java.lang.String com.bootcamp.app.controllers.RegisterController.showConfirmationPage(org.springframework.ui.Model,java.lang.String)
2018-02-06 10:51:16.797 INFO 7116 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/confirm],methods=[POST]}" onto public java.lang.String com.bootcamp.app.controllers.RegisterController.processConfirmationForm(org.springframework.ui.Model,java.util.Map)
2018-02-06 10:51:16.798 INFO 7116 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/test],methods=[GET]}" onto public java.lang.String com.bootcamp.app.controllers.TestController.test()
2018-02-06 10:51:16.801 INFO 7116 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2018-02-06 10:51:16.802 INFO 7116 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-02-06 10:51:16.841 INFO 7116 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-02-06 10:51:16.842 INFO 7116 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-02-06 10:51:16.882 INFO 7116 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-02-06 10:51:17.394 INFO 7116 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2018-02-06 10:51:17.458 INFO 7116 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2018-02-06 10:51:17.465 INFO 7116 --- [ main] c.b.app.SpringBootcampApplication : Started SpringBootcampApplication in 7.823 seconds (JVM running for 8.19)
2018-02-06 10:51:35.719 INFO 7116 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2018-02-06 10:51:35.720 INFO 7116 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2018-02-06 10:51:35.748 INFO 7116 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 28 ms
2018-02-06 10:51:47.792 INFO 7116 --- [nio-8080-exec-8] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory
2018-02-06 10:52:46.550 WARN 7116 --- [nio-8080-exec-8] o.s.s.c.bcrypt.BCryptPasswordEncoder : Empty encoded password
Change method configAuthentication() to:
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
This is what spring boot expects for default authentication provider. Then see if your user details service gets called on login attempt.
Also please post your CustomUserDetails implementation.

Endpoint protection configuration via #EnableGlobalMethodSecurity in Spring Boot

While trying to recreate a sample from a book demonstrating how to restrict access to an endpoint, I'm getting an unexpected behavior - an admin with a permitting role is disallowed access:
$ curl -X POST \
> 'http://localhost:9090/oauth/token?grant_type=password&username=admin&password=password2' \
> -H 'authorization: Basic d2ViYXBwOndlYnNlY3JldA==' \
> -H 'cache-control: no-cache' \
> -d '"category":"test","document":"this is a test document"'
{"access_token":"6d149c21-6a48-41e8-885d-d6da70648b49","token_type":"bearer","expires_in":42860,"scope":"read,write,trust"}
$ curl -X GET \
> 'http://localhost:9090/resource?access_token=6d149c21-6a48-41e8-885d-d6da70648b49' \
> -H 'cache-control: no-cache' \
{"timestamp":1508464945487,"status":403,"error":"Forbidden","exception":"org.springframework.security.access.AccessDeniedException","message":"Access Denied","path":"/resource"}
Here are the relevant classes:
#Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManager();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user1").password("password1").roles("USER")
.and().withUser("admin").password("password2").roles("ADMIN");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().antMatchers("/**").permitAll().and()
// default protection for all resources (including /oauth/authorize)
.authorizeRequests()
.anyRequest().hasAnyRole("USER","ADMIN");
// ... more configuration, e.g. for form login
}
}
#Configuration
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
#Autowired
private AuthenticationManager authManager;
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authManager);
}
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("webapp").secret("websecret").authorizedGrantTypes("password")
.scopes("read,write,trust");
}
}
#SpringBootApplication
#EnableAuthorizationServer
#EnableResourceServer
#RestController
#EnableGlobalMethodSecurity(prePostEnabled=true)
public class OauthServerApplication {
#RequestMapping("/resource")
#PreAuthorize("hasRole('ADMIN')")
public String resourceEndpoint() {
return "This resource is protected by the resource server.";
}
public static void main(String[] args) {
SpringApplication.run(OauthServerApplication.class, args);
}
}
What am I missing here?
The goal is to have only adminuser to be able to access the resource endpoint, while the regular user user1is to be denied access.
N.B.: the below stanza is actually something I added:
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().antMatchers("/**").permitAll().and()
// default protection for all resources (including /oauth/authorize)
.authorizeRequests()
.anyRequest().hasAnyRole("USER","ADMIN");
// ... more configuration, e.g. for form login
}
as its absence produces the following during resource acquisition attempt (2nd request):
<html>
<head>
<title>Login Page</title>
</head>
<body onload='document.f.username.focus();'>
<h3>Login with Username and Password</h3>
<form name='f' action='/login' method='POST'>
<table>
<tr>
<td>User:</td>
<td>
<input type='text' name='username' value=''>
</td>
</tr>
<tr>
<td>Password:</td>
<td>
<input type='password' name='password'/>
</td>
</tr>
<tr>
<td colspan='2'>
<input name="submit" type="submit" value="Login"/>
</td>
</tr>
<input name="_csrf" type="hidden" value="1cbdad0b-181e-496c-aed0-eb633b29eab7" />
</table>
</form>
</body>
</html>
After enabling web security log, as some of the commentators suggested, like so:
#Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
.....
#Override
public void configure(WebSecurity web) throws Exception {
web.debug(true);
}
...}
here's the partial resulting server log from the 2 requests:
2017-10-20 07:17:27.836 WARN 12728 --- [ main] o.s.s.c.a.web.builders.WebSecurity :
********************************************************************
********** Security debugging is enabled. *************
********** This may include sensitive information. *************
********** Do not use in a production system! *************
********************************************************************
2017-10-20 07:17:29.116 INFO 12728 --- [ main] o.s.cloud.commons.util.InetUtils : Cannot determine local hostname
2017-10-20 07:17:29.180 INFO 12728 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2017-10-20 07:17:29.186 INFO 12728 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Bean with name 'configurationPropertiesRebinder' has been autodetected for JMX exposure
2017-10-20 07:17:29.187 INFO 12728 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Bean with name 'refreshEndpoint' has been autodetected for JMX exposure
2017-10-20 07:17:29.187 INFO 12728 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Bean with name 'restartEndpoint' has been autodetected for JMX exposure
2017-10-20 07:17:29.187 INFO 12728 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Bean with name 'environmentManager' has been autodetected for JMX exposure
2017-10-20 07:17:29.188 INFO 12728 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Bean with name 'refreshScope' has been autodetected for JMX exposure
2017-10-20 07:17:29.189 INFO 12728 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Located managed bean 'environmentManager': registering with JMX server as MBean [org.springframework.cloud.context.environment:name=environmentManager,type=EnvironmentManager]
2017-10-20 07:17:29.197 INFO 12728 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Located managed bean 'restartEndpoint': registering with JMX server as MBean [org.springframework.cloud.context.restart:name=restartEndpoint,type=RestartEndpoint]
2017-10-20 07:17:29.202 INFO 12728 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Located managed bean 'refreshScope': registering with JMX server as MBean [org.springframework.cloud.context.scope.refresh:name=refreshScope,type=RefreshScope]
2017-10-20 07:17:29.207 INFO 12728 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Located managed bean 'configurationPropertiesRebinder': registering with JMX server as MBean [org.springframework.cloud.context.properties:name=configurationPropertiesRebinder,context=6f7923a5,type=ConfigurationPropertiesRebinder]
2017-10-20 07:17:29.211 INFO 12728 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Located managed bean 'refreshEndpoint': registering with JMX server as MBean [org.springframework.cloud.endpoint:name=refreshEndpoint,type=RefreshEndpoint]
2017-10-20 07:17:29.338 INFO 12728 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 0
2017-10-20 07:17:29.402 INFO 12728 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 9090 (http)
2017-10-20 07:17:29.406 INFO 12728 --- [ main] c.e.spring.cloud.OauthServerApplication : Started OauthServerApplication in 6.879 seconds (JVM running for 7.264)
2017-10-20 07:18:20.584 INFO 12728 --- [nio-9090-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
2017-10-20 07:18:20.584 INFO 12728 --- [nio-9090-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2017-10-20 07:18:20.600 INFO 12728 --- [nio-9090-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 16 ms
2017-10-20 07:18:20.606 INFO 12728 --- [nio-9090-exec-1] Spring Security Debugger :
************************************************************
Request received for POST '/oauth/token?grant_type=password&username=user1&password=password1':
org.apache.catalina.connector.RequestFacade#5ace935e
servletPath:/oauth/token
pathInfo:null
headers:
host: localhost:9090
connection: keep-alive
content-length: 54
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
cache-control: no-cache
origin: chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop
content-type: text/plain;charset=UTF-8
authorization: Basic d2ViYXBwOndlYnNlY3JldA==
postman-token: cd55952b-6c6f-6101-8f24-3942dee9b06a
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.8
cookie: JSESSIONID=F4526A8B6FD15FD35D3D84D25E2C3898
Security filter chain: [
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
LogoutFilter
BasicAuthenticationFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
]
************************************************************
2017-10-20 07:20:18.604 INFO 12728 --- [nio-9090-exec-4] Spring Security Debugger :
************************************************************
Request received for GET '/resource?access_token=5466dfff-f088-4097-8db9-4ed07f0b80a0':
org.apache.catalina.connector.RequestFacade#5ace935e
servletPath:/resource
pathInfo:null
headers:
host: localhost:9090
connection: keep-alive
cache-control: no-cache
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
postman-token: 394b6610-1d18-eec7-338b-ab1de65cfeeb
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.8
cookie: JSESSIONID=F4526A8B6FD15FD35D3D84D25E2C3898
Security filter chain: [
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CsrfFilter
LogoutFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
]
************************************************************
2017-10-20 07:20:18.640 INFO 12728 --- [nio-9090-exec-4] Spring Security Debugger :
************************************************************
New HTTP session created: 1D899B6306F970E097CE746030A28E4A
Call stack:
at org.springframework.security.web.debug.Logger.info(Logger.java:44)
at org.springframework.security.web.debug.DebugRequestWrapper.getSession(DebugFilter.java:166)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:240)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:240)
at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:240)
at org.springframework.security.web.savedrequest.HttpSessionRequestCache.saveRequest(HttpSessionRequestCache.java:59)
at org.springframework.security.web.access.ExceptionTranslationFilter.sendStartAuthentication(ExceptionTranslationFilter.java:201)
at org.springframework.security.web.access.ExceptionTranslationFilter.handleSpringSecurityException(ExceptionTranslationFilter.java:177)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:133)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
at org.springframework.security.web.debug.DebugFilter.invokeWithWrappedRequest(DebugFilter.java:90)
at org.springframework.security.web.debug.DebugFilter.doFilter(DebugFilter.java:77)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:108)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1457)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
************************************************************
When I comment out the #PreAuthorize("hasRole('ADMIN')") annotation on top of the resource endpoint, the resource request correctly displays "This resource is protected by the resource server." Also a breakpoint placed in there gets triggered. Re-enabling the #PreAuthorize annotation seems to introduce the improper behavior and skips the breakpoint. Where in the surrounding Spring infrastructure could I place the breakpoint to research deeper this effect of #PreAuthorize("hasRole('ADMIN')") annotation?
Thanks.
Because you are using OAuth2, instead of using the WebSecurityConfigurerAdapter you need to use the ResourceServerConfigurerAdapter. For example:
#Configuration
#EnableResourceServer
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Override
public void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll().and().cors().disable().csrf().disable().httpBasic().disable()
.exceptionHandling()
.authenticationEntryPoint(
(request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
.accessDeniedHandler(
(request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED));
}
}
Now you should be able to use the security methods.
Here is an implementation for OAuth2 with Spring Boot with custom UserDetails service and JWT token. The basic implementation is the same.
Here is the OAuth2Configuration for the Authorization Server
Here is the WebSecurityConfiguration for the Authorization Server

Resources