Spring Boot + Web + Thymeleaf: Circular view path in Spring IO Guide for "Securing a Web Application" - spring

I am trying out the Spring IO Guide for "Securing a Web Application" available at https://spring.io/guides/gs/securing-web/.
The guide instructs to build a simple unsecured web application first and secure it using Spring Security later. However, after building the unsecured web application with Spring Boot 2.0.1.RELEASE version, I am getting the following error on trying to access a URL (http://localhost:9191/hello) of the web application:
2018-05-04 09:58:07.742 ERROR 25968 --- [nio-9191-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Circular view path [hello]: would dispatch back to the current handler URL [/hello] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)] with root cause
javax.servlet.ServletException: Circular view path [hello]: would dispatch back to the current handler URL [/hello] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
I replicated the code as available at the above URL (i.e. https://spring.io/guides/gs/securing-web/) and my embedded tomcat server is running on port 9191 (as port 8080 is used by some other app). Any help is appreciated. Thanks in advance!
Edit:
Following is the configuration/controller code from the guide:
#Configuration
public class MvcConfig implements WebMvcConfigurer {
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/home").setViewName("home");
registry.addViewController("/").setViewName("home");
registry.addViewController("/hello").setViewName("hello");
registry.addViewController("/login").setViewName("login");
}
}

Please add dependency for thymeleaf in your pom. as ViewResolver of thymeleaf is not present to resolve th:href="#{/hello} in your hello.html so throwing error:
Add below dependency in your pom.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

check spring-boot-starter-thymeleaf dependency in your build path

Related

Spring Boot + Thymeleaf CSS file cannot access and have 500 error no template found

When I use Spring Boot 1.4.0 + Thymeleaf, I find the static resources couldn't access and throw the error "template might not exist or might not be accessible by any of the configured Template Resolvers".
Folder structure about my static resources
Browser show 500 error
From server log, can find the error "template not found". But the URL should be my CSS file location.
2018-08-28 21:07:29.826 ERROR 5676 --- [nio-8080-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: Error resolving template "Spring Boot Application is available.", template might not exist or might not be accessible by any of the configured Template Resolvers] with root cause
It sounds like Spring Boot is trying to resolve the resource path as a template. There may be a conflict with a path to one of your controllers. Spring Boot by default serves static resources from /**. You can alter this default path in your application.properties file with the spring.mvc.static-path-pattern.
## application.properties
spring.mvc.static-path-pattern=/resources/**
This would result in a new resource path to your static content
boostrap.min.css
http://localhost:8080/resources/css/bootstrap.min.css
https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-spring-mvc-static-content
After checking my source code, I find it's because I have another controller has request mapping to home page and block CSS/JS URL. After I comment the function test2(), home page can load static resources now.
#RequestMapping(value = "/")
public String test1(){
return "index";
}
#RequestMapping
public String test2(){
return "index";
}

How to enable swagger in a jersey + spring-boot web application [duplicate]

I am getting a HTTP 404 error when trying to serve index.html ( located under main/resources/static) from a spring boot app. However if I remove the Jersey based JAX-RS class from the project, then http://localhost:8080/index.html works fine.
The following is main class
#SpringBootApplication
public class BootWebApplication {
public static void main(String[] args) {
SpringApplication.run(BootWebApplication.class, args);
}
}
I am not sure if I am missing something here.
Thanks
The problem is the default setting of the Jersey servlet path, which defaults to /*. This hogs up all the requests, including request to the default servlet for static content. So the request is going to Jersey looking for the static content, and when it can't find the resource within the Jersey application, it will send out a 404.
You have a couple options around this:
Configure Jerse runtime as a filter (instead of as a servlet by default). See this post for how you can do that. Also with this option, you need to configure one of the ServletProperties to forward the 404s to the servlet container. You can use the property that configures Jersey to forward all request which results in a Jersey resource not being found, or the property that allows you to configure a regex pattern for requests to foward.
You can simply change the Jersey servlet pattern to something else other than the default. The easiest way to do that is to annotate your ResourceConfig subclass with #ApplicationPath("/root-path"). Or you can configure it in your application.properties - spring.jersey.applicationPath.

Birt integration in JHipster application

I'm fairly new to Jhipster and angularjs and i'm trying to integrate the Birt engine in a JHipster application using an H2 embedeed database.
I found this page that details how to integrate the birt engine in a spring application but i don't to how to applicate this for my application.
Here are the modifications performed in the jhipster project:
add dependency to org.eclipse.birt.runtime in pom
Create the classes Car, CarServiceImpl, BirtView, BirtEngineFactory and BirtDataServiceConfiguration in a sub-package report as described in the article.
I added the BirtWebConfiguration class in the sub-package config. I removed the #ComponentScan line that is already taken into account in the Application class.
I created an empty report in src/main/webapp/reports/toto.rptdesign
My problems are:
When accessing the application main page a "PageNotFound exception" with the following message "No mapping found for HTTP request with URI [/] in DispatcherServlet with name 'dispatcherServlet'". I presume this is due to the BirtWebConfiguration that seems to overwritte the rest path configuration.
How shall I define a new rest end-point /reports ?
When accessing the http://localhost:8080/reports page, a thymeleaf exception is raised
[ERROR] org.thymeleaf.TemplateEngine - [THYMELEAF][http-nio-127.0.0.1-8090-exec-5] Exception processing template "birtView": Error resolving template "birtView", template might not exist or might not be accessible by any of the configured Template Resolvers
[ERROR] org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: Error resolving template "birtView", template might not exist or might not be accessible by any of the configured Template Resolvers] with root cause
org.thymeleaf.exceptions.TemplateInputException: Error resolving template "birtView", template might not exist or might not be accessible by any of the configured Template Resolvers
at org.thymeleaf.TemplateRepository.getTemplate(TemplateRepository.java:245) ~[thymeleaf-2.1.3.RELEASE.jar:na]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1104) ~[thymeleaf-2.1.3.RELEASE.jar:na]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1060) ~[thymeleaf-2.1.3.RELEASE.jar:na]
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1011) ~[thymeleaf-2.1.3.RELEASE.jar:na]
at org.thymeleaf.spring4.view.ThymeleafView.renderFragment(ThymeleafView.java:335) ~[thymeleaf-spring4-2.1.3.RELEASE.jar:na]
at org.thymeleaf.spring4.view.ThymeleafView.render(ThymeleafView.java:190) ~[thymeleaf-spring4-2.1.3.RELEASE.jar:na]
Thanks for any help.
Has the BirtView bean been created? For example, in config/LocaleConfiguration.java:
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/reports").setViewName("birtView");
}
#Bean
public BirtView birtView(){
BirtView birtView = new BirtView();
birtView.setDataSource(dataSource);
birtView.setAppContext(applicationContext);
birtView.setBirtEngine(this.engine().getObject());
return birtView;
}

Mapping conflict when deploying with spring boot Jersey starter deployed as WAR

We're using Spring Boot with its Jersey Starter and deploy it as a WAR, programmatically deployed into another application's embedded Tomcat.
After our application startup, in some environments, a mapping conflict occurs and is logged as follows:
o.g.j.s.i.JerseyServletContainerInitializer : Mapping conflict. A Servlet registration exists with same mapping as the Jersey servlet application, named com.vidal.pmsi.config.PmsiResourceConfiguration, at the servlet mapping, /*.
The resource configuration is as follows:
#ApplicationPath("/")
#ExposedApplication
#Component
public class PmsiResourceConfiguration extends ResourceConfig {
public PmsiResourceConfiguration() {
packages("com.vidal.pmsi.api");
packages("com.vidal.pmsi.config");
property(ServerProperties.BV_DISABLE_VALIDATE_ON_EXECUTABLE_OVERRIDE_CHECK, true);
property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true);
}
}
As far as I understand, Spring Boot Jersey Starter will register a 'jerseyServlet'-named servlet mapping to '/*'.
In some environments, Jersey's own JerseyServletContainerInitializer will trigger after SpringApplication startup, failing to register PmsiResourceConfiguration because of the existing jerseyServlet mapping.
This is a problem because of our own open-source library that tries (and crashes at) getting the context path at startup:
// compile-time generated Linkers.java
#WebListener
#Generated("fr.vidal.oss.jax_rs_linker.LinkerAnnotationProcessor")
public final class Linkers implements ServletContextListener {
private static String contextPath = "";
private static String applicationName = ApplicationName.get();
#Override
public void contextInitialized(ServletContextEvent sce) {
//applicationName = FQCN of PmsiResourceConfiguration
contextPath = ContextPaths.contextPath(sce.getServletContext(), applicationName);
}
// [...]
}
// ContextPaths.java
public static String contextPath(ServletContext servletContext, String registeredKey) {
// registeredKey is therefore the FQCN of PmsiResourceConfiguration
String mappedPath = stripWildcard(servletContext.getServletRegistration(registeredKey).getMappings().iterator().next());
return servletContext.getContextPath() + mappedPath;
}
The last snippet of code will fail as there is no mapping for the registered resource configuration class (there is only one for 'jerseyServlet' key).
This does not fail when there isn't any mapping conflict reported.
Why?
I was running my head against a similar problem where I have a Spring Boot Application with a Jersey JAX-RS Webservice. Everything worked fine when using the embeddedTomcat but it went to hell when I tried deploying the war on a regular Tomcat of the same version (Tomcat8).
The problem is that by default the embeddedTomcat does not scan for ServletContainerInitializer in jar files, yet the regular one does and that conflicted with the ServletContainer/Config that Spring sets up.
Apart from excluding the jar containing the JerseyServletContainerInitializer I found an option to tell tomcat to filter out this particular ServletContainerInitializer (SCI). Setting the containerSciFilter attribute on the context helped:
<Context containerSciFilter="JerseyServletContainerInitializer">
...
</Context>
I did not define any SCI in my META-INF/services but the jar that contains the JerseySCI has defined it and it was on the right path to be found by Tomcat.
Considering that this was the closest matchinb question and without an answer I don't repost my question and try to answer this one as I believe that the cause is the same.

How can I tell if Spring has loaded my #Controller?

Is there a way to tell if Spring has loaded my #Controller?
I'm requesting a URL but I'm not hitting my controller and I can't figure out why
I'm loading controllers by doing a component scan
<context:component-scan base-package="com.example.app.web"/>
Other controllers in the same package as my failing controller are working fine.
My controller code is:
#Controller
#RequestMapping(value = "/app/administration/ecosystem")
public class AppEcosystemController {
#Autowired
EcosystemManagerService ecosystemManagerService;
#RequestMapping(value = "/Foo", method = RequestMethod.GET)
public String getEcosystem() {
/* Implementation */
}
The first thing I'd like to do is to be sure that this controller is getting picked up by the component scan.
Any suggestions?
Just enable logging for your application, you can find this information at INFO level
For example in my application I have a controller named UserController.
The following log4j.properties does the trick.
log4j.rootLogger=INFO, FILE
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=../logs/rest-json.log
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
I can see in the log that RequestMappingHandlerMapping mapped my controller (scroll all the way to the right).
07:28:36,255 INFO RequestMappingHandlerMapping:182 - Mapped "{[/rest/**/users/{id}],methods=[GET],params=[],headers=[],consumes=[],produces=[text/xml || application/json],custom=[]}" onto public org..domain.User org.ramanh.controller.UserController.getUser(java.lang.String)
07:28:36,255 INFO RequestMappingHandlerMapping:182 - Mapped "{[/rest/**/users],methods=[POST],params=[],headers=[],consumes=[],produces=[text/xml || application/json],custom=[]}" onto public void org..controller.UserController.addUser(org...domain.User)
If you are still unsure I would suggest adding a method annotated with #PostConstruct.
You could easily look up the message in the log or place a break point in this method.
#PostConstruct
protected void iamAlive(){
log.info(“Hello AppEcosystemController”)
}
If you find that your controller is initialized correctly but still the url is not accessible.I would test the following
You are getting 404 error - maybe you are not pointing to the correct
url (do not forget to add the application as prefix to the url)
You are getting 404 error - Dispatcher servlet mapping in web.xml doesn't meet
the url above
You are getting 403/401 – maybe you are using
spring security and it’s blocking the url
You are getting 406 – your
content type definition is conflicting with your request
You are getting 50x – something is buggy in your code
I made an ApplicationContextDumper. Add it into application context, it will dump all beans and their dependencies in the current context and parent contexts (if any) into log file when the application context initialization finishes. It also lists the beans which aren’t referenced.
It was inspired by this answer.
You could start out with enabling debug logging for Spring as outlined here.
I'd also recommend leveraging the MVC testing support, which you'll find in the spring-test jar. Details on how to use it can be found here and here.

Resources