簡體   English   中英

Spring 引導 2.1.x JSP 文件找到但未呈現

[英]Spring Boot 2.1.x JSP file found but not rendered

我目前正在將一個小型應用程序遷移到 SpringBoot。 我們有遺留代碼,我希望通過將登錄頁面掛鈎到 SpringBoot,我能夠讓 web 應用程序的 JSP/JS 文件處理 rest。

目前我已經成功地將我們升級到 Spring 5,並使用 SpringBoot 2.1.8。

POM snippet: The application is using Tomcat defaults provided by Spring, and have pulled in the relevant Jasper/JSTL JARS so Tomcat can read

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-activemq</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-classic</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-classic</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

根據這篇DZone 文章,我構建了一個小型 controller 來處理登錄過程

@Controller
public class LoginController {

    @Resource
    private UserSessionService userSessionService;

    @GetMapping(value = "/")
    public String index() {
        Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "LoginController: Hit /, returning index.jsp");
        return "index";
    }

    @GetMapping(value = "/login")
    public String login() {
        Logger.getLogger(this.getClass().getName())
              .log(Level.SEVERE, "LoginController: Hit /login, returning login.jsp");
        return "login";
    }

    @GetMapping(value = "/loginFailed")
    public String loginError(Model model) {
        Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "LoginController: Failed to login");
        model.addAttribute("error", "true");
        return "login";
    }

    @GetMapping(value = "/logout")
    public String logout(SessionStatus session) {
        Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "LoginController: Logging out");
        SecurityContextHolder.getContext().setAuthentication(null);
        session.setComplete();
        return "redirect:/login";
    }

    @PostMapping(value = "/postLogin")
    public String postLogin(Model model, HttpSession session) {
        Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "LoginController: postLogin");
        return "redirect:/";
    }

}

login.jsp :遺留代碼,修改為調用 controller。 我正在盡最大努力讓 Spring 安全處理調用我的 AuthenticaionProvider 和我的數據庫的過程(為簡潔起見,我只顯示關鍵區域的東西,無論如何頁面都相當簡單

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>
<c:set var="contextPath" value="${pageContext.request.contextPath}"/>

<!DOCTYPE html>
<html>
    <head>
        <%@page contentType="text/html" pageEncoding="UTF-8" %>
        <link type="text/css" href="${contextPath}/css/login.css" rel="stylesheet"/>
        <link rel="stylesheet" href="${contextPath}/css/font-awesome/css/font-awesome.min.css">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title></title>
    </head>

    <body class="loginBody">
          .
          .
          <div class="formdiv">
              <form name='f' action='doLogin' method='POST'>
                  <div style="width: 215px; margin: 0 auto; ">
                      <label class="loginLabel">Login</label><br>
                      <input type="text" name="username".../>
                      <label class="loginLabel">Password</label><br>
                      <input type="password" size="25" name="password".../><br>
                      <input type="submit" class="header_btn_class" value="Login" id="loginButton" style="..."/>
                    </div>
              </form>
           </div>
        .
        .
    </body>
</html>

index.jsp:遺留代碼,處理主登陸頁面

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="contextPath" value="${pageContext.request.contextPath}"/>
<%@include file="beforeHtml.jsp" %>

<html>
    <head>
        <%@include file="head.jsp" %>
        <script type="text/javascript" src="${contextPath}/js/home/home.js"></script>
        <title></title>
    </head>

    <body>
        <%@include file="top.jsp" %>


        <h2 style="margin-left: 60px;">Release Notes</h2>
        <div id="changeLog" style=...">
        </div>

        <jsp:include page="../html/Changelog.html"/>
    </body>
</html>

我有一個名為SecurityConfig的文件,讓 SpringBoot 知道繞過“默認”登錄頁面:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests().antMatchers("/xxx").hasAnyRole("ADMIN", "USER")
                .and()
                .authorizeRequests().antMatchers("/login", "/resource/**").permitAll()
                .and()
                .formLogin().loginPage("/login").usernameParameter("username").passwordParameter("password").permitAll()
                .loginProcessingUrl("/doLogin")
                .successForwardUrl("/postLogin")
                .failureUrl("/loginFailed")
                .and()
                .logout().logoutUrl("/doLogout").logoutSuccessUrl("/logout").permitAll()
                .and()
                .csrf().disable();
    }

我的application.properties文件中有這些字段

server.port=8888
server.servlet.context-path=/xxx
server.tomcat.additional-tld-skip-patterns=*mchange-commons-java*.jar

spring.mvc.view.prefix=/WEB-INF/view/jsp/
spring.mvc.view.suffix=.jsp
spring.mvc.servlet.load-on-startup=1

所有這些放在一起使我可以很好地登錄我請求的localhost:8888/xxx/login的 URL,然后登錄,查看日志 Spring 找到我的設置並正常登錄。 問題是當它去獲取登陸頁面時,它是一個名為index.jsp的 JSP 文件。 根據 SpringBoot/Application 的日志記錄

Oct 09, 2019 2:44:37 PM org.springframework.core.log.LogFormatUtils traceDebug
FINE: GET "/xxx/login", parameters={}
Oct 09, 2019 2:44:37 PM org.springframework.web.servlet.handler.AbstractHandlerMapping getHandler
FINE: Mapped to public java.lang.String com.rhdjapan.xxx.controllers.LoginController.login()
Oct 09, 2019 2:44:37 PM com.xx.xxx.controllers.LoginController login
SEVERE: LoginController: Hit /login, returning login.jsp
Oct 09, 2019 2:44:37 PM org.springframework.web.servlet.view.ContentNegotiatingViewResolver getBestView
FINE: Selected 'text/html' given [text/html,...]
Oct 09, 2019 2:44:37 PM org.springframework.web.servlet.view.AbstractView render
FINE: View name 'login', model {}
Oct 09, 2019 2:44:37 PM org.springframework.web.servlet.view.InternalResourceView renderMergedOutputModel
FINE: Forwarding to [/WEB-INF/view/jsp/login.jsp]
Oct 09, 2019 2:44:38 PM org.springframework.web.servlet.FrameworkServlet logResult
FINE: Completed 200 OK
Oct 09, 2019 2:44:42 PM com.xx.xxx.services.common.security.service.UserDetailsServiceImpl loadUserByUsername
SEVERE: loadUserByUsername: looking up user [admin]
Oct 09, 2019 2:44:42 PM com.xx.xxx.services.common.security.service.UserDetailsServiceImpl loadUserByUsername
SEVERE: loadUserByUsername: userId found = [1111111]
Oct 09, 2019 2:44:42 PM org.springframework.core.log.LogFormatUtils traceDebug
FINE: "FORWARD" dispatch for POST "/xxx/postLogin", parameters={username:[admin], password:[admin]}
Oct 09, 2019 2:44:42 PM org.springframework.web.servlet.handler.AbstractHandlerMapping getHandler
FINE: Mapped to public java.lang.String com.xx.xxx.controllers.LoginController.postLogin(org.springframework.ui.Model,javax.servlet.http.HttpSession)
Oct 09, 2019 2:44:42 PM com.xx.xxx.controllers.LoginController postLogin
SEVERE: LoginController: postLogin
Oct 09, 2019 2:44:42 PM org.springframework.web.servlet.view.AbstractView render
FINE: View name 'redirect:', model {}
Oct 09, 2019 2:44:42 PM org.springframework.web.servlet.FrameworkServlet logResult
FINE: Exiting from "FORWARD" dispatch, status 302
Oct 09, 2019 2:44:42 PM org.springframework.core.log.LogFormatUtils traceDebug
FINE: GET "/xxx/", parameters={}
Oct 09, 2019 2:44:42 PM org.springframework.web.servlet.handler.AbstractHandlerMapping getHandler
FINE: Mapped to public java.lang.String com.xx.xxx.controllers.LoginController.index()
Oct 09, 2019 2:44:42 PM com.xx.xxx.controllers.LoginController index
SEVERE: LoginController: Hit /, returning index.jsp
Oct 09, 2019 2:44:42 PM org.springframework.web.servlet.view.ContentNegotiatingViewResolver getBestView
FINE: Selected 'text/html' given [text/html, ...]
Oct 09, 2019 2:44:42 PM org.springframework.web.servlet.view.AbstractView render
FINE: View name 'index', model {}
Oct 09, 2019 2:44:42 PM org.springframework.web.servlet.view.InternalResourceView renderMergedOutputModel
FINE: Forwarding to [/WEB-INF/view/jsp/index.jsp]
Oct 09, 2019 2:44:42 PM org.springframework.web.servlet.FrameworkServlet logResult
FINE: Completed 200 OK

這就是問題所在:雖然成功找到 JSP 文件,但頁面未呈現 我返回了一個空的 HTML 文件,並且使用 web 調試器(chrome)僅顯示 15 個空白行的來源。 我假設它是我的index.jsp文件的長度;

我的問題是雙重的

  1. HTML/JSP 未在我的屏幕上呈現的原因可能是什么?
  2. 如果有修復,對於我需要在 SpringBoot 下工作的所有其他遺留 JSP 文件,它們是否都需要類似的程序?

謝謝!

更新為簡潔起見,有人問我制作的WAR的結構,當我拉起檔案時結構是這樣的

WAR
|____css
|____dashboard_view
|____excel
|____images
|____jquery
|____js
|____jsp
|____META-INF
|____org
|____third-party
|____WEB-INF
|________classes
|________lib
|________view
|____________html
|____________jsp
|_________________index.jsp
|_________________login.jsp

考慮到我提供的登錄名和索引 jsp 文件,我想知道在渲染過程中是否有什么地方靜默失敗?

似乎是 servlet 無法找到某些有問題的文件,因此沒有呈現任何內容,因為它找不到任何內容

我需要進一步驗證。 但是在WEB-INF/view/js/home每個index.jsp下移動home.js后,我開始從我的網頁中獲取一些堆棧跟蹤

Exception: org.apache.jasper.JasperException: java.lang.NullPointerException

Stack Trace
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:516) org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385) org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329) javax.servlet.http.HttpServlet.service(HttpServlet.java:741) 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:712) 
org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:580) 
org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:516) 
org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequestDispatcher.include(HeaderWriterFilter.java:149) 
org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:955) 
org.apache.jsp.WEB_002dINF.view.jsp.index_jsp._jspService(index_jsp.java:150)

對於我登錄 SpringBoot

SEVERE: Servlet.service() for servlet [dispatcherServlet] in context with path [/xxx] threw exception [java.lang.NullPointerException] with root cause
java.lang.NullPointerException
    at java.util.Properties$LineReader.readLine(Properties.java:434)
    at java.util.Properties.load0(Properties.java:353)
    at java.util.Properties.load(Properties.java:341)
    at com.xx.xxx.common.utils.common.GenericPropertiesUtil.loadProperties(GenericPropertiesUtil.java:16)
    at com.xx.xxx.common.utils.common.EnvPropertiesUtil.getEnvironmentProperties(EnvPropertiesUtil.java:43)
    at com.xx.xxx.common.utils.common.EnvPropertiesUtil.getParameterValue(EnvPropertiesUtil.java:23)
    at com.xx.xxx.common.utils.common.EnvPropertiesUtil.getFlagParameterValue(EnvPropertiesUtil.java:37)
    at com.xx.xxx.common.utils.Config.getFlagValue(Config.java:131)
    at com.xx.xxx.common.utils.Config.isProd(Config.java:59)
    at com.xx.xxx.common.utils.IO.debug(IO.java:514)

這似乎表明頁面上現在有活動

如果需要,我會驗證並重新打開。 我會保留這篇文章,以防其他人有類似的問題

由於您使用外部 tomcat 通過將spring-boot-starter-tomcat設置為providedscope進行部署。 嘗試將以下 scope 添加到碧玉:

    <dependency>
        <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-jasper</artifactId>
        <scope>provided</scope>
    </dependency>

jasper 依賴項不包含在嵌入式 tomcat 中,但由於部署是到外部的,因此 tomcat 已經有了這個。 因此,您可以將其標記為已提供。 The jasper dependency is the one which transpile the jsp.Also ensure that a war packaging is used as JSP won't work properly with jar as packaging in spring boot.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM