首页 文章

在Spring Boot应用程序中使用JSP和Thymeleaf视图

提问于
浏览
1

一般来说,网站和网络上有几个类似的问题,但我还没能像我尝试过的那样在我的例子中使用它们 .

我试图通过 InternalResourceViewResolver 包含JSP视图 . 我已经有了Thymeleaf的观点 .

Application.java

@SpringBootApplication
@ComponentScan("controller")
@EnableWebSecurity
@Configuration
public class Application extends WebSecurityConfigurerAdapter {
    public static void main(String args[]) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public ITemplateResolver templateResolver() {
        SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
        resolver.setPrefix("classpath:/templates/");
        resolver.setSuffix(".html");
        resolver.setTemplateMode(TemplateMode.HTML);
        resolver.setCharacterEncoding("UTF-8");
        resolver.setCacheable(false);
        resolver.setOrder(1);
        return resolver;
    }

    //intended for the .jsp view
    @Bean
    public InternalResourceViewResolver jspResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("classpath:/templates/jsp/");
        resolver.setSuffix(".jsp");
        resolver.setViewClass(JstlView.class);
        resolver.setOrder(2);
        return resolver;
    }

    @Bean
    public SpringTemplateEngine templateEngine() {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.addTemplateResolver(new UrlTemplateResolver());
        templateEngine.addTemplateResolver(templateResolver());

        //IKD if/how I should somehow add jspResolver() here

        templateEngine.addDialect(new SpringSecurityDialect());
        templateEngine.addDialect(new LayoutDialect(new GroupingStrategy()));
        templateEngine.addDialect(new Java8TimeDialect());
        return templateEngine;
    }

    @Bean
    @Description("Thymeleaf View Resolver")
    public ThymeleafViewResolver viewResolver() {
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setTemplateEngine(templateEngine());
        viewResolver.setOrder(0);
        return viewResolver;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/users/**").hasRole("USER")//USER role can access /users/**
                .antMatchers("/admin/**").hasRole("ADMIN")//ADMIN role can access /admin/**
                .antMatchers("/quests/**").permitAll()// anyone can access /quests/**
                .anyRequest().authenticated()//any other request just need authentication
                .and()
                .formLogin();//enable form login
    }

    @Override
    protected void configure(AuthenticationManagerBuilder builder) throws Exception {
        builder.inMemoryAuthentication()
                .passwordEncoder(passwordEncoder())
                .withUser("tim").password(passwordEncoder().encode("123")).roles("ADMIN")
                .and()
                .withUser("joe").password(passwordEncoder().encode("234")).roles("USER");
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}

MainController.java

@Controller
public class MainController {
@GetMapping("/")
ModelAndView index(Principal principal) {
    ModelAndView mv = new ModelAndView("home");
    if (principal != null) {
        mv.addObject("message", principal.getName());
    } else {
        mv.addObject("message", "anon.");
    }

    return mv;
}

@GetMapping("/**")
String request(HttpServletRequest request, Model model) {
    Authentication auth = SecurityContextHolder.getContext()
            .getAuthentication();
    ModelAndView mv = new ModelAndView("home");
    model.addAttribute("uri", request.getRequestURI())
            .addAttribute("user", auth.getName())
            .addAttribute("roles", auth.getAuthorities());

    return "html"; //<-- whenever I change this to return "jsp/jsp"; it breaks
}

html.html (Thymeleaf)

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
    <body>
        <p>
            URI: <h3 th:text="${uri}"></h3>
        User: <h3 th:text="${user}"></h3>
        Roles: <h3 th:text="${roles}"></h3>
        <a href="/admin/">/admin/</a>
<a href="/users/">/users/</a>
<a href="/others/">/others/</a>
<a href="/quests/">/quests/</a>

</p> <form th:action="@{/logout}" method="post"> <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> <input type="submit" value="Logout"> </form> </body> </html>

当我尝试使用JSP文件很好地工作时,browswer只输出

HTTP Status 500 ? Internal Server Error

在NetBeans输出窗口中,gradle的任务运行正好运行,日志显示在最顶层(整个日志非常广泛):

2018-10-07 18:09:40.070 ERROR 6024 --- [nio-8080-exec-4] org.thymeleaf.TemplateEngine : [THYMELEAF][http-nio-8080-exec-4] Exception processing template "jsp/jsp": An error happened during template parsing (template: "class path resource [templates/jsp/jsp.html]")

JSP view I'm trying to include

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html lang="en">
    <body>
        <p>URI: ${uri} 
User : ${user}
roles: ${roles}

<a href="/admin/">/admin/</a>
<a href="/users/">/users/</a>
<a href="/others/">/others/</a>
<a href="/quests/">/quests/</a>

</p> <form action="/logout" method="post"> <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/> <input type="submit" value="Logout"> </form> </body> </html>

最后,我的项目树:

enter image description here

我的假设是该应用程序不知道文件夹 templates/jsp 内的文件 jsp.jsp ,这就是为什么我的目标是查看解析器的问题,但正如我所说,我可能很容易就错了 .

这只是我想要实现和构建的一个例子,所以请随意用建议来粉碎它 .

1 回答

  • 0

    我还没有尝试过,因为我在完全不同的项目中使用了 jspthymeleaf . 并且还将 jsp 转换为 thymeleaf ,但不能一起使用它 . 我只是想帮忙,因为我碰到这个问题,我发现它很有趣 .


    我假设你已经检查了这个帖子? Using both Thymeleaf and JSP


    根据this blog,您可以保留默认配置的百里香 . 您只需要为jsp配置添加 InternalResourceViewResolver .

    完整的例子:

    将以下依赖项添加到您的pom.xml文件中

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-jasper</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
     </dependency>
     <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
     </dependency>
    

    在application.properties中设置百万富翁视图名称和JSP配置以进行内部视图解析

    spring.view.prefix:/WEB-INF/
    spring.view.suffix:.jsp
    spring.view.view-names:jsp/*
    spring.thymeleaf.view-names:thymeleaf/*
    

    为JSP页面的视图解析创建配置类

    package com.example.config;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.view.InternalResourceViewResolver;
    import org.springframework.web.servlet.view.JstlView;
    
    @Configuration
    public class JspConfig {
        @Value("${spring.view.prefix}")
        private String prefix;
    
        @Value("${spring.view.suffix}")
        private String suffix;
    
        @Value("${spring.view.view-names}")
        private String viewNames;
    
        @Bean
        InternalResourceViewResolver jspViewResolver() {
            final InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
            viewResolver.setPrefix(prefix);
            viewResolver.setSuffix(suffix);
            viewResolver.setViewClass(JstlView.class);
            viewResolver.setViewNames(viewNames);
            return viewResolver;
        }
    }
    

相关问题