无法访问webapp下的views文件夹中的.xhtml文件。但如果我在webapp下面,我可以从webapp访问

时间:2018-01-11 18:03:14

标签: java spring-mvc spring-boot primefaces jsf-2.2

我无法访问webapp下的文件夹(视图)中的.xhtml,但如果我使用requestMapping URL将它们放在webapp下,我可以访问它。

有人可以使用 Spring MVC spring boot 帮助我如何访问webapp下的文件夹中的 xhtml 文件,我' m还计划通过在webapp下创建文件夹(css,images)来嵌入静态资源,如图像和css文件。

感谢。

这是我的代码

project explorer

MyAutoConfiguration.java

@Configuration
@ConditionalOnClass(Some.class)
@EnableConfigurationProperties(SomeProperties.class)
@ComponentScan("com.boot.configurations")
@SpringBootApplication
public class MyAutoConfiguration {

    private static Log log = LogFactory.getLog(MyAutoConfiguration.class);


    @Bean
    public static ViewScope viewScope() {
        return new ViewScope();
    }

    /**
     * Allows the use of @Scope("view") on Spring @Component, @Service and @Controller
     * beans
     */
    @Bean
    public static CustomScopeConfigurer scopeConfigurer() {
        CustomScopeConfigurer configurer = new CustomScopeConfigurer();
        HashMap<String, Object> hashMap = new HashMap<String, Object>();
        hashMap.put("view", viewScope());
        configurer.setScopes(hashMap);
        return configurer;
    }

    /*
     * Below sets up the Faces Servlet for Spring Boot
     */
    @Bean
    public FacesServlet facesServlet() {
        return new FacesServlet();
    }

    /*This one replaces both the web.xml and the Spring configuration file! 
     * To add a servlet, you add a method to the main class 
     * (instead of configuring it in the obsolete web.xml)
     * */
    @Bean
    public ServletRegistrationBean facesServletRegistration() {
        ServletRegistrationBean registration = new ServletRegistrationBean(
                facesServlet(), "*.xhtml");
        registration.setName("FacesServlet");
        registration.addUrlMappings("/views/*","*.xhtml","/faces/*","*.jsf");
        registration.setLoadOnStartup(1);
        registration.setEnabled(true);
        registration.setOrder(1);
        return registration;
    }


    @Bean
    WebMvcConfigurer configurer () {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addResourceHandlers (ResourceHandlerRegistry registry) {
                ResourceHandlerRegistration resourceRegistration  = registry
                        .addResourceHandler("/pages/**")
                        .addResourceLocations("/resources/","classpath:/images/")  //Configuring Multiple Locations for a Resource
                        .setCachePeriod(3600);            //The resources served will be cached in the browser for 3600 seconds
                registry.addResourceHandler("resources/**").addResourceLocations("/resources/");
                registry.addResourceHandler("/css/**").addResourceLocations("/css/");
                registry.addResourceHandler("/img/**").addResourceLocations("/img/");
                registry.addResourceHandler("/js/**").addResourceLocations("/js/");
            }
        };
    }

    @Bean
    public ServletListenerRegistrationBean<ConfigureListener> jsfConfigureListener() {
        return new ServletListenerRegistrationBean<ConfigureListener>(
                new ConfigureListener());
    }

Initializer.java

@Configuration
public class Initializer implements ServletContextInitializer {

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
    servletContext.setInitParameter("primefaces.CLIENT_SIDE_VALIDATION", "true");
    servletContext.setInitParameter("javax.faces.PROJECT_STAGE", "Development");

}
}

SpringMVCService

@RestController
@Scope("request")
public class SpringMVCService {

    @Autowired(required=true)
    TestService testService;

    /**
     * Displays the message from the test service including information in the
     * session scope
     * 
     * This is a proof that calling the Spring MVC service is on the same
     * context as the JSF views(A problem I had before)
     */
    @RequestMapping("/greeting")
    public String greeting() {
        return testService.getMessage();
    }

    @RequestMapping("/welcome.html")
    public ModelAndView firstPage() {
        return new ModelAndView("test.xhtml");
    }

    @RequestMapping("/login.html")
    public ModelAndView loginPage() {
        String transferFunds = "hellooooooooo";
        return new ModelAndView("login.xhtml","transferFunds",transferFunds);
    }

    @RequestMapping("/home.jsp")
    public ModelAndView homePage() {
        String transferFunds = "hellooooooooo";
        return new ModelAndView("home.xhtml");
    }

    @RequestMapping("/loginUser.jsp")
    public ModelAndView loginUserPage() {
        return new ModelAndView("loginPage.xhtml");
    }

    @RequestMapping("/userAccount.html")
    public ModelAndView registerPage() {
        return new ModelAndView("useraccount.xhtml");
    }
}

Viewscope.java

public class ViewScope implements Scope {
    public Object get(String name, ObjectFactory<? extends Object> objectFactory) {
        Map<String, Object> viewMap = FacesContext.getCurrentInstance()
                .getViewRoot().getViewMap();
        Object obj;
        if (viewMap.containsKey(name)) {
            obj = viewMap.get(name);
        } else {
            Object object = objectFactory.getObject();
            viewMap.put(name, object);
            obj = object;
        }
        return obj;
    }

    public Object remove(String name) {
        return FacesContext.getCurrentInstance().getViewRoot().getViewMap()
                .remove(name);
    }

    public String getConversationId() {
        return null;
    }

    public void registerDestructionCallback(String name, Runnable callback) {
        // Not supported
    }

    public Object resolveContextualObject(String key) {
        return null;
    }
}

application.properties

logging.level.org.springframework: DEBUG
logging.level.com=TRACE

spring.mvc.view.prefix=/
#spring.mvc.view.suffix=.xhtml

# for context-param in web.xml
#https://jsflive.wordpress.com/2013/04/01/jsf22-config-resource-dir/
server.context_parameters.javax.faces.WEBAPP_RESOURCES_DIRECTORY=/WEB-INF/

# ADMIN (SpringApplicationAdminJmxAutoConfiguration)
spring.application.admin.enabled=true
spring.application.admin.jmx-name=org.springframework.boot:type=Admin,name=SpringApplication # JMX name of the application admin MBean.

Web.xml(src - &gt; main - &gt; webapp - &gt; WEB-INF - &gt; Web.xml)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
        id="WebApp_ID" version="3.0">

<!--    TODO put session timeout? where does JSF view scope grab it's timeout from? -->

<!-- TODO How do I get rid of this web.xml because right now this is throwing a could
not find backup factory exception when not adding this entry(Even thought it's a 
different servlet name(It has a space)) -->
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    </servlet>

</web-app>

的build.gradle

buildscript {
    repositories {
        maven { url "http://repo.spring.io/libs-release" }
        mavenLocal()
        mavenCentral()
        jcenter()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.8.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'

repositories {
    mavenLocal()
    mavenCentral()
    maven { url "http://repo.spring.io/libs-release" }
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")

    //compile group: "org.springframework.boot", name: "spring-boot-starter"
//compile group: "org.springframework", name: "spring-web", version: "4.0.2.RELEASE"

    compile group: "org.primefaces", name: "primefaces", version: "6.1"
    compile group: "com.sun.faces", name: "jsf-api", version: "2.2.7"
    compile group: "com.sun.faces", name: "jsf-impl", version: "2.2.7"
    compile group: 'javax.el', name: 'el-api', version: '2.2'
    compile "org.glassfish.web:el-impl:2.2"
    compile "org.springframework.boot:spring-boot-autoconfigure:1.5.8.RELEASE",
            "org.springframework.boot:spring-boot-configuration-processor:1.5.8.RELEASE",

    compile group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1'
    compile group: 'javax.servlet', name: 'jstl', version: '1.2'
    //compile group: 'javax.servlet', name: 'servlet-api', version: '2.5'
    compile group: 'javax.servlet.jsp', name: 'jsp-api', version: '2.1'
    compile group: 'org.glassfish', name: 'javax.faces', version: '2.2.8'
    compile group: 'javax.inject', name: 'javax.inject', version: '1'

    compile "org.apache.tomcat.embed:tomcat-embed-core:8.5.24"
    compile "org.apache.tomcat.embed:tomcat-embed-logging-juli:8.5.24"
    //compile "org.apache.tomcat.embed:tomcat-embed-jasper:8.5.24"
    compile group: "org.apache.tomcat.embed", name: "tomcat-embed-jasper", version: "8.5.24"

    //below dependency  dont got @RestController    but current version is 4.3.12.RELEASE which got @RestController 
    //compile group: 'org.springframework', name: 'spring-web', version: '3.0.4.RELEASE'

    testCompile("junit:junit")
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.6'
}

1 个答案:

答案 0 :(得分:0)

从FacesServlet的urlMappings中删除/views/*。在映射*.xhtml时,您不需要它,并且当servlet查找实际文件时,文件夹映射将从路径中删除。

@Bean
public ServletRegistrationBean facesServletRegistration() {
    ServletRegistrationBean registration = new ServletRegistrationBean(
            facesServlet(), "*.xhtml");
    registration.setName("FacesServlet");
    registration.addUrlMappings("*.xhtml", "/faces/*", "*.jsf");
    registration.setLoadOnStartup(1);
    registration.setEnabled(true);
    registration.setOrder(1);
    return registration;
}

事实上,你只能做*.xhtml映射,一切都会好的。

您现在可以使用http://yourserver/yourapp/views/home.xhtml访问您的文件。使用您当前的配置,此网址只会直接在home.xhtml目录下找到webapp