【问题标题】:deploying spring boot war generated file to tomcat server, TemplateResolver not locating files将spring boot war生成的文件部署到tomcat服务器,TemplateResolver没有定位文件
【发布时间】:2015-10-11 19:48:07
【问题描述】:

我正在开发一个 Spring Boot Web 应用程序,当我像这样运行它时一切都运行良好

java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n -jar build/libs/MobileQuestionnaire-0.1.0.jar

但如果我尝试将战争部署到 Tomcat 8,它会正确加载,但我认为我的“TemplateResolver”bean 有问题。这是我的 MVC 配置文件:

@Configuration
@ComponentScan({"controler","data.service"})
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = { "data.dao.repository" })
@EntityScan(basePackages = { "data.domain" })
@PropertySource("classpath:properties\\config.properties")
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Autowired
    Environment env;

    private static String[] CLASSPATH_RESOURCE_LOCATIONS = { 
        "classpath:/META-INF/resources/", 
        "classpath:/static/", 
        "classpath:/public/" };

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean(name = "DataSource")
    public DriverManagerDataSource dataSource() {
        DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
        driverManagerDataSource.setDriverClassName(env.getProperty("database.driverManagerDataSource.setDriverClassName"));
        driverManagerDataSource.setUrl(env.getProperty("database.driverManagerDataSource.setUrl"));
        driverManagerDataSource.setUsername(env.getProperty("database.driverManagerDataSource.setUsername"));
        driverManagerDataSource.setPassword(env.getProperty("database.driverManagerDataSource.setPassword"));
        return driverManagerDataSource;
    }

    @Bean
    public EntityManagerFactory entityManagerFactory() {

        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setGenerateDdl(true);

        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setPackagesToScan("data.domain", "data.dao.Repository");
        factory.setDataSource(dataSource());
        factory.afterPropertiesSet();

        return factory.getObject();
    }

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);

        return transactionManager;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }

    public Properties additionalProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
        return properties;
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations(CLASSPATH_RESOURCE_LOCATIONS);
    }



    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver();
        resolver.setPageParameterName("page.page");
        resolver.setSizeParameterName("page.size");
        resolver.setOneIndexedParameters(true);    
        resolver.setMaxPageSize(Integer.parseInt(env.getProperty("pagenation.pagesize")));
        argumentResolvers.add(resolver);
        super.addArgumentResolvers(argumentResolvers);
    }


    @Bean(name = "messageSource")
    public MessageSource messageSource() {
        final ResourceBundleMessageSource messageSource;

        messageSource = new ResourceBundleMessageSource();
        messageSource.setDefaultEncoding("UTF-8");
        messageSource.setBasename("local/messages");

        return messageSource;
    }

    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
        localeChangeInterceptor.setParamName("language");
        return localeChangeInterceptor;
    }

    @Bean(name="localeResolver")
    public SessionLocaleResolver localeResolver() {
        SessionLocaleResolver localeResolver = new SessionLocaleResolver();
        localeResolver.setDefaultLocale(new Locale("en"));
        return localeResolver;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeChangeInterceptor());
    }


    @Bean
    WebMvcConfigurerAdapter mvcViewConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/login").setViewName("login");
                registry.addViewController("/").setViewName("/login");
            }
        };
    }



}

这是我的 Thymeleaf 配置

@Configuration
public class ThymeleafConfiguration {

    @Bean
    public ITemplateResolver defaultTemplateResolver() {
        final TemplateResolver resolver = new FileTemplateResolver();
        resolver.setSuffix(".html");
        resolver.setPrefix("src/main/resources/templates/");
        resolver.setTemplateMode("HTML5");
        resolver.setCharacterEncoding("UTF-8");
        resolver.setCacheable(false);
        return resolver;
    }

}

所以我确定我不完全理解在 Tomcat 中运行我的 jar 文件“MobileQuestionnaire-0.1.0.jar”和运行我的 war 文件之间的区别。

如果您需要更多信息,请尽管询问,我会提供。

非常感谢。

编辑:

好的,所以我已经设法设置 tomcat 让我附加一个调试器,我已经将 Elcipse 连接到它,我已经做了一些挖掘工作。

How to set up debugger in tomcat

这里失败了:

templateInputStream = resourceResolver.getResourceAsStream(templateProcessingParameters, resourceName);

它试图获取文件

public InputStream getResourceAsStream(final TemplateProcessingParameters templateProcessingParameters, final String resourceName) {
        Validate.notNull(resourceName, "Resource name cannot be null");
        final File resourceFile = new File(resourceName);
        try {
            return new FileInputStream(resourceFile);

它在这里失败了。路径是:

\src\main\resources\templates\home.html

当我查看 Tomcat 中的网络应用程序文件夹时,该文件位于另一个位置:

C:\Program Files\Apache Software Foundation\Tomcat 8.0\webapps\MobileQuestionnaire\WEB-INF\classes\templates\home.html

所以我认为我需要更新模板解析器,以便它看起来在正确的位置。有什么建议吗?

-干杯

编辑

好的,所以这个问题只是 Tomcat 无法在 war 文件中找到我的 html/资源。这是我的 gradle 文件:

buildscript {
    repositories {
        mavenCentral()
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.5.RELEASE")
        classpath 'com.bmuschko:gradle-cargo-plugin:2.1.1'
        classpath 'mysql:mysql-connector-java:5.1.16'
        classpath 'org.springframework:springloaded:1.2.0.RELEASE'

    }
}


apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'eclipse-wtp'
apply plugin: 'war'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'com.bmuschko.cargo'


jar {
    baseName = 'MobileQuestionnaire'
    version =  '0.1.0'
}

repositories {
    mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    compile("org.springframework.boot:spring-boot-starter-thymeleaf")
    compile("org.springframework.boot:spring-boot-starter-security")
    compile("org.springframework:spring-jdbc:4.1.0.RELEASE")
    compile("org.springframework.boot:spring-boot-starter-data-jpa")
    compile("mysql:mysql-connector-java:5.1.+")
    compile("org.webjars:bootstrap:3.0.3")
    compile("org.webjars:jquery:2.0.3-1")
    compile("org.springframework.security.oauth:spring-security-oauth2:2.0.7.RELEASE")
    compile("org.thymeleaf:thymeleaf-spring4")
    compile("nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect")

    testCompile("junit:junit")
}

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

idea {
    module {
        inheritOutputDirs = false
        outputDir = file("$buildDir/classes/main/")
    }
}

这是我部署后的网络应用程序目录结构(减去 lib 文件夹):

....\App>dir /b /s | sort
....\App\META-INF
....\App\META-INF\MANIFEST.MF
....\App\META-INF\war-tracker
....\App\org
....\App\org\springframework
....\App\org\springframework\boot
....\App\org\springframework\boot\loader
....\App\org\springframework\boot\loader\archive
....\App\org\springframework\boot\loader\archive\Archive$Entry.class
....\App\org\springframework\boot\loader\archive\Archive$EntryFilter.class
....\App\org\springframework\boot\loader\archive\Archive$EntryRenameFilter.class
....\App\org\springframework\boot\loader\archive\Archive.class
....\App\org\springframework\boot\loader\archive\ExplodedArchive$FileEntry.class
....\App\org\springframework\boot\loader\archive\ExplodedArchive$FileNotFoundURLConnection.class
....\App\org\springframework\boot\loader\archive\ExplodedArchive$FilteredURLStreamHandler.class
....\App\org\springframework\boot\loader\archive\ExplodedArchive.class
....\App\org\springframework\boot\loader\archive\FilteredArchive$1.class
....\App\org\springframework\boot\loader\archive\FilteredArchive$2.class
....\App\org\springframework\boot\loader\archive\FilteredArchive.class
....\App\org\springframework\boot\loader\archive\JarFileArchive$1.class
....\App\org\springframework\boot\loader\archive\JarFileArchive$JarFileEntry.class
....\App\org\springframework\boot\loader\archive\JarFileArchive.class
....\App\org\springframework\boot\loader\data
....\App\org\springframework\boot\loader\data\ByteArrayRandomAccessData.class
....\App\org\springframework\boot\loader\data\RandomAccessData$ResourceAccess.class
....\App\org\springframework\boot\loader\data\RandomAccessData.class
....\App\org\springframework\boot\loader\data\RandomAccessDataFile$DataInputStream.class
....\App\org\springframework\boot\loader\data\RandomAccessDataFile$FilePool.class
....\App\org\springframework\boot\loader\data\RandomAccessDataFile.class
....\App\org\springframework\boot\loader\ExecutableArchiveLauncher$1.class
....\App\org\springframework\boot\loader\ExecutableArchiveLauncher.class
....\App\org\springframework\boot\loader\InputArgumentsJavaAgentDetector$1.class
....\App\org\springframework\boot\loader\InputArgumentsJavaAgentDetector.class
....\App\org\springframework\boot\loader\jar
....\App\org\springframework\boot\loader\jar\Bytes.class
....\App\org\springframework\boot\loader\jar\CentralDirectoryEndRecord.class
....\App\org\springframework\boot\loader\jar\Handler.class
....\App\org\springframework\boot\loader\jar\JarEntry.class
....\App\org\springframework\boot\loader\jar\JarEntryData.class
....\App\org\springframework\boot\loader\jar\JarEntryFilter.class
....\App\org\springframework\boot\loader\jar\JarFile$1.class
....\App\org\springframework\boot\loader\jar\JarFile$2.class
....\App\org\springframework\boot\loader\jar\JarFile.class
....\App\org\springframework\boot\loader\jar\JarURLConnection$1.class
....\App\org\springframework\boot\loader\jar\JarURLConnection$JarEntryName.class
....\App\org\springframework\boot\loader\jar\JarURLConnection.class
....\App\org\springframework\boot\loader\jar\ZipInflaterInputStream.class
....\App\org\springframework\boot\loader\JarLauncher.class
....\App\org\springframework\boot\loader\JavaAgentDetector.class
....\App\org\springframework\boot\loader\LaunchedURLClassLoader$1.class
....\App\org\springframework\boot\loader\LaunchedURLClassLoader$2.class
....\App\org\springframework\boot\loader\LaunchedURLClassLoader$Java7LockProvider.class
....\App\org\springframework\boot\loader\LaunchedURLClassLoader$LockProvider.class
....\App\org\springframework\boot\loader\LaunchedURLClassLoader.class
....\App\org\springframework\boot\loader\Launcher.class
....\App\org\springframework\boot\loader\MainMethodRunner.class
....\App\org\springframework\boot\loader\PropertiesLauncher$1.class
....\App\org\springframework\boot\loader\PropertiesLauncher$ArchiveEntryFilter.class
....\App\org\springframework\boot\loader\PropertiesLauncher$PrefixMatchingArchiveFilter.class
....\App\org\springframework\boot\loader\PropertiesLauncher.class
....\App\org\springframework\boot\loader\util
....\App\org\springframework\boot\loader\util\AsciiBytes.class
....\App\org\springframework\boot\loader\util\SystemPropertyUtils.class
....\App\org\springframework\boot\loader\WarLauncher.class
....\App\WEB-INF
....\App\WEB-INF\classes
....\App\WEB-INF\classes\configuration
....\App\WEB-INF\classes\configuration\Application.class
....\App\WEB-INF\classes\configuration\eunms
....\App\WEB-INF\classes\configuration\eunms\ENUM_ENABLED_STATUS.class
....\App\WEB-INF\classes\configuration\eunms\ENUM_HTML_RESOURSES.class
....\App\WEB-INF\classes\configuration\eunms\ENUM_LANGUAGE$1.class
....\App\WEB-INF\classes\configuration\eunms\ENUM_LANGUAGE.class
....\App\WEB-INF\classes\configuration\eunms\ENUM_USER_ROLES.class
....\App\WEB-INF\classes\configuration\MvcConfig$1.class
....\App\WEB-INF\classes\configuration\MvcConfig.class
....\App\WEB-INF\classes\configuration\ThymeleafConfiguration.class
....\App\WEB-INF\classes\configuration\util
....\App\WEB-INF\classes\configuration\util\converters
....\App\WEB-INF\classes\configuration\util\converters\ConverterCompany.class
....\App\WEB-INF\classes\configuration\util\converters\ConverterUsers.class
....\App\WEB-INF\classes\configuration\util\converters\ConverterUsersRoles.class
....\App\WEB-INF\classes\configuration\util\PageWrapper$PageItem.class
....\App\WEB-INF\classes\configuration\util\PageWrapper.class
....\App\WEB-INF\classes\configuration\util\RandomGenerator$1.class
....\App\WEB-INF\classes\configuration\util\RandomGenerator$Mode.class
....\App\WEB-INF\classes\configuration\util\RandomGenerator.class
....\App\WEB-INF\classes\configuration\util\RandomString.class
....\App\WEB-INF\classes\configuration\WebSecurityConfig.class
....\App\WEB-INF\classes\controler
....\App\WEB-INF\classes\controler\AdminController.class
....\App\WEB-INF\classes\controler\CompanyAdminController.class
....\App\WEB-INF\classes\controler\MainMenuController.class
....\App\WEB-INF\classes\controler\NotLoggedInController.class
....\App\WEB-INF\classes\data
....\App\WEB-INF\classes\data\dao
....\App\WEB-INF\classes\data\dao\repository
....\App\WEB-INF\classes\data\dao\repository\CompanyRepository.class
....\App\WEB-INF\classes\data\dao\repository\UsersRepository.class
....\App\WEB-INF\classes\data\dao\repository\UsersRolesRepository.class
....\App\WEB-INF\classes\data\domain
....\App\WEB-INF\classes\data\domain\Company.class
....\App\WEB-INF\classes\data\domain\form
....\App\WEB-INF\classes\data\domain\form\CreateCompanyForm.class
....\App\WEB-INF\classes\data\domain\form\CreateUsersForm.class
....\App\WEB-INF\classes\data\domain\form\CreateUsersRolesForm.class
....\App\WEB-INF\classes\data\domain\form\EditCompanyForm.class
....\App\WEB-INF\classes\data\domain\form\EditUsersForm.class
....\App\WEB-INF\classes\data\domain\Users.class
....\App\WEB-INF\classes\data\domain\UsersRoles.class
....\App\WEB-INF\classes\data\service
....\App\WEB-INF\classes\data\service\CompanyManagment.class
....\App\WEB-INF\classes\data\service\CompanyManagmentImpl.class
....\App\WEB-INF\classes\data\service\SecurityService.class
....\App\WEB-INF\classes\data\service\SecurityServiceImpl.class
....\App\WEB-INF\classes\local
....\App\WEB-INF\classes\local\messages_en.properties
....\App\WEB-INF\classes\local\messages_es.properties
....\App\WEB-INF\classes\properties
....\App\WEB-INF\classes\properties\config.properties
....\App\WEB-INF\classes\static
....\App\WEB-INF\classes\static\css
....\App\WEB-INF\classes\static\css\menu_listing.css
....\App\WEB-INF\classes\static\css\style.css
....\App\WEB-INF\classes\static\images
....\App\WEB-INF\classes\static\images\icon_ADMIN.png
....\App\WEB-INF\classes\static\images\icon_ADMIN_createcompany.png
....\App\WEB-INF\classes\static\images\icon_ADMIN_viewcompany.png
....\App\WEB-INF\classes\static\images\icon_COMPANY_ADMIN.png
....\App\WEB-INF\classes\static\images\icon_mainMenu.png
....\App\WEB-INF\classes\static\js
....\App\WEB-INF\classes\static\js\sample.js
....\App\WEB-INF\classes\static\js\timeStampPicker
....\App\WEB-INF\classes\static\js\timeStampPicker\cal.gif
....\App\WEB-INF\classes\static\js\timeStampPicker\next.gif
....\App\WEB-INF\classes\static\js\timeStampPicker\prev.gif
....\App\WEB-INF\classes\static\js\timeStampPicker\ts_picker.js
....\App\WEB-INF\classes\templates
....\App\WEB-INF\classes\templates\adminMenu.html
....\App\WEB-INF\classes\templates\assignUserRoles.html
....\App\WEB-INF\classes\templates\companyAdminMenu.html
....\App\WEB-INF\classes\templates\createCompany.html
....\App\WEB-INF\classes\templates\createUser.html
....\App\WEB-INF\classes\templates\editCompany.html
....\App\WEB-INF\classes\templates\editUser.html
....\App\WEB-INF\classes\templates\error.html
....\App\WEB-INF\classes\templates\home.html
....\App\WEB-INF\classes\templates\login.html
....\App\WEB-INF\classes\templates\mainMenu.html
....\App\WEB-INF\classes\templates\viewCompanies.html
....\App\WEB-INF\classes\templates\viewCompany.html
....\App\WEB-INF\classes\templates\viewUser.html
....\App\WEB-INF\classes\templates\viewUserRoles.html
....\App\WEB-INF\classes\templates\viewUsers.html

....\App>

【问题讨论】:

    标签: spring tomcat thymeleaf


    【解决方案1】:

    我想通了。

    确保将 CATALINA_HOME 设置为类变量,因为 Tomcat 使用它来确定文件的位置。一旦我将 CATALINA_HOME 设置为指向 Tomcat 文件夹中的 bin 目录,一切正常

    运行jar文件时,使用这个bean:

    /*
         * This is for when we run the jar file
         */
        @Bean
        public ITemplateResolver defaultTemplateResolver() {
            final TemplateResolver resolver = new FileTemplateResolver();
            resolver.setSuffix(".html");
            resolver.setPrefix("src/main/resources/templates/");
            resolver.setTemplateMode("HTML5");
            resolver.setCharacterEncoding("UTF-8");
            resolver.setCacheable(false);
            return resolver;
        }
    

    当我们在 Tomcat 上运行时,使用这个 bean:

    /*
         * This is for when we run it on the Tomcat server
         */
        @Bean
        public ServletContextTemplateResolver templateResolver() {
            ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
            resolver.setPrefix("/src/main/resources/templates/");
            resolver.setSuffix(".html");
            resolver.setTemplateMode("HTML5");
            resolver.setCacheable(false);
            return resolver;
    
        }
    

    如果两个 bean 都存在,jar 就可以工作。 如果两个 bean 都存在,则战争将无法进行。 战争只适用于第二个 bean。

    【讨论】:

      猜你喜欢
      • 2018-07-25
      • 2020-11-29
      • 2012-08-10
      • 1970-01-01
      • 2015-09-03
      • 2015-12-10
      • 2019-09-20
      • 2012-10-29
      • 2019-03-09
      相关资源
      最近更新 更多