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

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.

Related

Problems with interaction between spring boot and extjs frontend

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...

Create form dynamically using thymeleaf

I am new in Spring MVC. I'm stuck for more than 24hrs trying to add a dynamic row using thymeleaf. I followed this link and also the thymeleaf documentation In this tutorial but i have not been able to make it work. Clicking addRow and removeRow doesn't work. Someone should please help me. Thanks
Here is my Controller code:
#Controller
#SessionAttributes("qualification")
public class QualificationController {
private final QualificationService qualificationService;
private final StaffService staffService;
private final CourseService courseService;
#Autowired
public QualificationController(QualificationService qualificationService,
StaffQualificationService service,
StaffService staffService, CourseService courseService) {
this.qualificationService = qualificationService;
this.staffService = staffService;
this.courseService = courseService;
}
#InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {
dataBinder.setDisallowedFields("id");
}
#GetMapping("/staff/{id}/qualification")
public String initForm(#PathVariable("id") Integer id, Model model) {
Staff staff = staffService.findById(id);
staff.addQualification(new StaffQualification());
model.addAttribute("qualification", staff);
model.addAttribute("qualifications", qualificationService.findAll());
model.addAttribute("courses", courseService.findAll());
return "registration/qualification";
}
#PostMapping(path = "/staff/{id}/qualification/new", params = {"save"})
public String addQualification(#ModelAttribute("qualification")
#Valid Staff staff,
BindingResult result, RedirectAttributes attributes,
SessionStatus status) {
if (result.hasErrors()) {
return "registration/qualification";
}
staffService.save(staff);
attributes.addFlashAttribute("successMessage", "Qualification successfully saved");
status.setComplete();
return "registration/qualification";
}
#PostMapping(path = "/staff/{id}/qualification/new", params = {"addRow"})
public String addRow(final Staff staff, BindingResult result) {
staff.getQuals().add(new StaffQualification());
return "registration/qualification";
}
#PostMapping(params = "removeRow", path = {"/staff/{id}/qualification/new"})
public String removeRow(final Staff staff, final BindingResult result,
final HttpServletRequest request) {
final int rowId = Integer.parseInt(request.getParameter("removeRow"));
staff.removeQualification(staff.getQuals().remove(rowId));
return "registration/qualification";
}
}
My entities:
public class Staff extends NamedEntity {
#NotBlank(message = "First Name is blank")
private String firstName;
#NotBlank(message = "Last Name is blank")
private String lastName;
private String middleName;
#Digits(fraction = 0, integer = 10)
#NotBlank(message = "Please fill in your phone number")
private String phoneNumber;
private boolean married;
private String gender;
#Transient
private int age;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "staff", orphanRemoval = true)
private List<StaffQualification> quals = new ArrayList<>();
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "staff", orphanRemoval = true)
private List<Document> documents = new ArrayList<>();
}
public class StaffQualification extends BaseEntity {
private String qualification;
private String course;
private String school;
#NotNull(message = "Date obtained qualification must be in the past")
#DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
private LocalDate qualDate;
#ManyToOne
private Staff staff;
}
Thymeleaf code:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Staff form</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css"
th:href="#{https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css}"
integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
</head>
<body>
<div class="justify-content-start">
<div th:include="fragments/bodyHeader.html"></div>
</div>
<div class="main body-content">
<div class="container">
<form th:object="${qualification}" th:action="#{/staff/{id}/qualification/new}" th:method="post">
<div class="alert alert-info" th:if="${successMessage}" th:utext="${successMessage}"></div>
<fieldset>
<legend class="w-auto" th:text="#{qualification.staff}">Staff Qualifications</legend>
<div>
<table id="items" class="table table-bordered">
<thead>
<tr>
<th th:scope="col">#</th>
<th th:scope="col">Title</th>
<th th:scope="col">Course</th>
<th th:scope="col">School</th>
<th th:scope="col" type="date">Date Obtained</th>
<th>
<button type="submit" name="addRow" th:text="#{qualification.row.add}">Add row</button>
</th>
</tr>
</thead>
<tbody id="tbodyContainer">
<tr th:each="row, rowStat : *{quals}">
<td th:text="${rowStat.count}">1</td>
<td>
<label>
<select th:field="*{quals[__${rowStat.index}__].qualification}">
<option th:each="var : ${qualifications}"
th:value="${var.id}"
th:text="${var.name}">
</option>
</select>
</label>
</td>
<td>
<label>
<select th:field="*{quals[__${rowStat.index}__].course}">
<option th:each="let : ${courses}"
th:value="${let.id}"
th:text="${let.name}">
</option>
</select>
</label>
</td>
<td>
<label>
<input type="text" th:field="*{quals[__${rowStat.index}__].school}"
th:errorClass="fieldError"/>
</label>
</td>
<td>
<label>
<input type="date" th:field="*{quals[__${rowStat.index}__].qualDate}"/>
</label>
</td>
<td>
<button type="submit" name="removeRow" th:value="${rowStat.index}"
th:text="#{qualification.row.remove}">Remove row
</button>
</td>
</tr>
</tbody>
</table>
</div>
<div>
<button class="btn btn-primary" name="save" style="margin-right: 50px" type="submit">Save</button>
</div>
</fieldset>
<div class="form-actions row justify-content-center" style="padding-top:10px; padding-right: 200px">
<a th:if="${qualification.id}" href="/staff/{id}/qualification"
th:href="#{/staff/{id}/qualification/(id=${qualification.id})}"
class="btn btn-primary">Next</a>
</div>
</form>
</div>
</div>
</body>
</html>
Account Controller:
#Controller
#SessionAttributes("account")
public class AccountController {
private final PencomService pencomService;
private final StaffService staffService;
private final BankService bankService;
#Autowired
public AccountController(PencomService pencomService, StaffService staffService,
BankService bankService) {
this.pencomService = pencomService;
this.staffService = staffService;
this.bankService = bankService;
}
#InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {
dataBinder.setDisallowedFields("id");
}
#GetMapping("/staff/{id}/account")
public String initCreationForm(#PathVariable("id") Integer staffId, Model model) {
Staff staff = staffService.findById(staffId);
staff.setBankAccount(new BankAccount());
staff.setPencomAccount(new PencomAccount());
model.addAttribute("account", staff);
model.addAttribute("listBanks", bankService.findAll());
model.addAttribute("listPensions", pencomService.findAll());
return "registration/account";
}
#PostMapping("/staff/{id}/account/new")
public String addAccount(#ModelAttribute("account") #Valid Staff staff,
BindingResult result, RedirectAttributes attributes, SessionStatus status) {
if (result.hasErrors()) {
return "registration/account";
} else {
staffService.save(staff);
attributes.addFlashAttribute("successMessage", "Accounts successfully saved");
status.setComplete();
return "/registration/account";
}
}
}
Error Message:
java.lang.NullPointerException: null
at com.chairmo.cadre.controller.AccountController.initCreationForm(AccountController.java:48) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.36.jar:9.0.36]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]

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

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

Symfony Routing with locale No route found for "GET /login_check/"

today I implemented a multilanguage-feature for my project and it works just great. But just the point I was trying to login again. Everytime I want to login this is the error:
No route found for "GET /login_check/" (from "http://localhost:8000/de/")
I googled a lot but found little.
My routing.yml:
project:
resource: "#AeTmProjectBundle/Resources/config/routing.yml"
prefix: /{_locale}/
requirements:
_locale: '%app.locales%'
cms:
resource: "#AeTmCMSBundle/Resources/config/routing.yml"
prefix: /{_locale}/
requirements:
_locale: '%app.locales%'
donation:
resource: "#AeTmDonationBundle/Resources/config/routing.yml"
prefix: /{_locale}/
requirements:
_locale: '%app.locales%'
homepage:
resource: "#AeTmHomepageBundle/Resources/config/routing.yml"
prefix: /{_locale}/
requirements:
_locale: '%app.locales%'
mailer:
resource: "#AeTmMailerBundle/Resources/config/routing.yml"
prefix: /{_locale}/
requirements:
_locale: '%app.locales%'
user:
resource: "#AeTmUserBundle/Resources/config/routing.yml"
prefix: /{_locale}/
requirements:
_locale: '%app.locales%'
sponsor:
resource: "#AeTmSponsorBundle/Resources/config/routing.yml"
prefix: /{_locale}/
requirements:
_locale: '%app.locales%'
statistics:
resource: "#AeTmStatisticsBundle/Resources/config/routing.yml"
prefix: /{_locale}/
requirements:
_locale: '%app.locales%'
fos_user:
resource: "#FOSUserBundle/Resources/config/routing/all.xml"
prefix: /{_locale}/
requirements:
_locale: '%app.locales%'
fos_js_routing:
resource: "#FOSJsRoutingBundle/Resources/config/routing/routing.xml"
prefix: /{_locale}/
requirements:
_locale: '%app.locales%'
BladeTesterCalendarBundle:
resource: "#BladeTesterCalendarBundle/Resources/config/routing.yml"
prefix: /{_locale}/
requirements:
_locale: '%app.locales%'
My security.yml firewall:
firewalls:
main:
pattern: ^/
form_login:
#provider: fos_userbundle
#csrf_token_generator: security.csrf.token_manager
success_handler: redirect.after.login
remember_me:
secret: '%secret%'
lifetime: 604800 # 1 week in seconds
always_remember_me: true
logout: true
anonymous: true
switch_user: { role: ROLE_ADMIN }
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
And my config.yml framework:
framework:
#esi: ~
translator: { fallback: de }
secret: "%secret%"
router:
resource: "%kernel.root_dir%/config/routing.yml"
strict_requirements: ~
form: ~
csrf_protection: ~
validation: { enable_annotations: false }
templating:
engines: ['twig']
#assets_version: SomeVersionScheme
default_locale: "%locale%"
trusted_hosts: ~
trusted_proxies: ~
session:
# handler_id set to null will use default session handler from php.ini
handler_id: ~
save_path: "%kernel.root_dir%/../var/sessions/%kernel.environment%"
fragments: ~
http_method_override: true
assets: ~
Parameters.yml:
locale: de
app.locales: "|de|en"
locale_supported:
en_EN: en
de_DE: de
If anyone has an idea, I would be very thankfull!
I think you have add a prefix to FosUserBundle routes in your routing.yml. Maybe this is the problem. Try to change the check path of your form login in your firewall.

Resources