Teifi
Teifi

Reputation: 713

how to tell spring to load resources from custom directory with maven multi-module springboot

I tried to build a maven multi-module web project:

project A, project B, ...

B dependent on A

run project B, the console shown than /hello were mapped, but hello.jsp not found when check localhost:8080/hello

here are my questions:

  1. how did i use hello.jsp(resources in A)while running project B?

  2. how to tell spring load resources from directory src/main/resources/?

structure A/B

A/B
|_src
|  |_main
|  |   |_java
|  |   |  |_com.x
|  |   |  |  |_AStarter.java/BStarter.java 
|  |   |  |_com.x.domain
|  |   |  |_com.x.services
|  |   |  |_com.x.web
|  |   |     |_HelloController.java/FooController.java
|  |   |_resources
|  |      |_application.properties
|  |      |_templates
|  |         |_hello.jsp
|  |_test
|      |_java
|      |_resources
|_pom.xml  

(A)pom.xml were a simple spring-boot like file. (B)pom.xml similar to (A)pom.xml just add a dependency:

<dependency>
    <groupId>X</groupId>
    <artifactId>A</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

application.properties: spring.view.suffix: .jsp


update

Starters:

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class AStarter extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(
            SpringApplicationBuilder application) {
        return application.sources(AStarter.class);
     }
    public static void run(Class<? extends AStarter> c, String[] args) {
        SpringApplication.run(c, args);
    }
    public static void main(String[] args) throws Exception {
        run(AStarter.class, args);
    }
}

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class BStarter extends AStarter {
    public static void main(String[] args) {
        AStarter.run(BStarter.class, args);
    }
}

Controllers:

@Controller
public class HelloController {
    private String message = "Hello World";
    @RequestMapping("/hello")
    public String welcome(Map<String, Object> model) {
        model.put("time", new Date());
        model.put("message", this.message);
        return "hello";
    }
}

@Controller
public class FooController {
    @RequestMapping("/foo")
    public String foo(Map<String, Object> model) {
        model.put("foo", "foo!");
        return "foo";
    }
}

console:

--- {main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/foo],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String com.x.FooController.foo(java.util.Map<java.lang.String, java.lang.Object>)
--- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/hello],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String com.x.web.HelloController.welcome(java.util.Map<java.lang.String, java.lang.Object>)
--- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
--- [main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[text/html],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest)

when i check localhoust:8080/hello, error came out enter image description here

Thanks in advance!

Upvotes: 0

Views: 3409

Answers (3)

Jeremy Mason
Jeremy Mason

Reputation: 3

Did you resolve this issue? I'm having the same issue and believe it is caused by the combination of using a maven submodule and the JSP spring view resolver.

Thymleaf tempting engine works fine, and I can move the subproject to it's own project, it works fine (no code or configuration changes required).

Upvotes: 0

lenicliu
lenicliu

Reputation: 957

your pom.xml use <package>war</package>? because embbed tomcat not support jsp

for template engine like freemarker, put *.ftl into different fold in classpath, and custom FreeMarkerConfigurer

multi-module project like this :

  Model-A
    src/main/java
    src/main/resources/templates1/hello.ftl
    pom.xml
  Model-B
    src/main/java
      org.lenic.sof.Application.java
    src/main/resources/templates2/index.ftl
    pom.xml(like Model-A additional dependent on Model-A)

and java config like this :

@Configuration
@ComponentScan
@EnableAutoConfiguration
@Controller
public class Application {
    private String  message = "Hello World";

    @RequestMapping("/hello")
    public String welcome(Map<String, Object> model) {
        model.put("time", new Date());
        model.put("message", this.message);
        return "hello";
    }

    @RequestMapping("/index")
    public String index(Map<String, Object> model) {
        model.put("message", "this is index page");
        return "index";
    }

    @Bean
    public FreeMarkerConfigurer freeMarkerConfigurer() {
        FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
        configurer.setDefaultEncoding("UTF-8");
        configurer.setTemplateLoaderPaths("classpath:/templates1/", "classpath:/templates2/");
        return configurer;
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

hello.ftl like this:

<html> 
    <head> 
        <title>welcome spring-boot!</title>
    </head> 
    <body>
        ${message}
    </body>
</html>

index.ftl like this:

<html> 
    <head> 
        <title>welcome spring-boot!</title>
    </head> 
    <body>
        ${message}
    </body>
</html>

Upvotes: 0

Don't use WEB-INF with Spring applications; it's always been fragile, and Spring can look in jars on the classpath. Put your files in src/main/resources/templates and don't specify any spring.view.prefix.

Upvotes: 1

Related Questions