访问从 sevrlet 转发的 JSP 文件(在 scriptlet 内)中的数据时出现异常

Exception while accessing data in JSP file (within scriptlet) forwarded from sevrlet

我正在尝试访问从 Servlet 发送的 JSP 文件数据。 每当我 运行 项目时,我都会收到异常。 我已经尝试使用
- <% … %>
- ${…}
- <c:out value="${loginFailed}"/>

即使我尝试使用评论标签,也会出现异常。

我一无所知,欢迎任何帮助。

我的一些reading/research

https://whosebug.com/tags/el/info
https://www.tutorialspoint.com/jsp/jsp_actions.htm
How to avoid Java code in JSP files?
...

login.jsp

<?xml version="1.0" encoding="UTF-8" ?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
    <jsp:directive.page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" />
    <jsp:text> <![CDATA[ <?xml version="1.0" encoding="UTF-8" ?> ]]> </jsp:text>
    <jsp:text> <![CDATA[ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> ]]> </jsp:text>

    <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
            <link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/styles/login/css/style.css" />
            <title>Connexion</title>
        </head>

        <body>
            <form class="sign-up" method="Post" action="/TP1MiniProjetBanque/home">
                <h1 class="sign-up-title">Connexion</h1>
                <input type="text" name="mail" class="sign-up-input" placeholder="Mail"/>
                <input type="password" name="mdp" class="sign-up-input" placeholder="Mot de passe"/>

                <input type="submit" value="Entrer" class="sign-up-button"/>
            </form>

            <% out.println((String)request.getAttribute("loginFailed")); %>
    </body>
    </html>
</jsp:root>

JRServlet.java

protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.getWriter().append("Served at :").append(request.getContextPath());
    request.getRequestDispatcher("/login.jsp").forward(request, response);
}


protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String mail = request.getParameter("mail");
    String mdp  = request.getParameter("mdp");

    if (mail.isEmpty() || mdp.isEmpty() || /**/) {
        request.setAttribute("loginFailed", true);
        request.getRequestDispatcher("/login.jsp").forward(request, response);
        return;
    } else {
        Client  user = new Client(mail, mdp);

        request.getRequestDispatcher("/home.jsp").forward(request, response);
        return;
    }

    //doGet(request, response);
}    

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"
         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">

  <display-name>TP1MiniProjetBanque</display-name>

  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>

  <servlet>
    <servlet-name>home</servlet-name>
    <servlet-class>jrservlet.JRServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>home</servlet-name>
    <url-pattern>/home</url-pattern>
  </servlet-mapping>
</web-app>    

层次结构

workspace/TP1MiniProjetBanque/    
├── build    
│   └── classes    
│       └── jrservlet    
│           ├── Client.class    
│           ├── Compte.class    
│           ├── DB.class    
│           ├── JRServlet.class    
│           └── testing.class    
├── src    
│   └── jrservlet    
│       ├── Client.java    
│       ├── Compte.java    
│       ├── DB.java    
│       ├── JRServlet.java    
│       └── testing.java    
└── WebContent    
    ├── home.jsp    
    ├── login.jsp    
    ├── META-INF    
    │   └── MANIFEST.MF    
    ├── styles    
    │   ├── home    
    │   └── login    
    └── WEB-INF    
        ├── lib    
        │   └── mysql-connector-java-5.1.39-bin.jar    
        └── web.xml    

启动 Servlet 时出现错误

HTTP Status 500 - /login.jsp(行:23,列:11)元素的内容必须由格式正确的字符数据或标记组成。

输入异常报告

message /login.jsp(行:23,列:11)元素的内容必须由格式正确的字符数据或标记组成。

说明服务器遇到内部错误,无法完成此请求。

异常

org.apache.jasper.JasperException: /login.jsp (line: 23, column: 11) The content of elements must consist of well-formed character data or markup.
    org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:42)
    org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:443)
    org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:308)
    org.apache.jasper.compiler.JspDocumentParser.parse(JspDocumentParser.java:228)
    org.apache.jasper.compiler.ParserController.doParse(ParserController.java:226)
    org.apache.jasper.compiler.ParserController.parseDirectives(ParserController.java:119)
    org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:194)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:374)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:354)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:341)
    org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:662)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:364)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:395)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:339)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    jrservlet.JRServlet.doGet(JRServlet.java:41)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause

org.xml.sax.SAXParseException; lineNumber: 23; columnNumber: 11; The content of elements must consist of well-formed character data or markup.
    com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:203)
    com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.fatalError(ErrorHandlerWrapper.java:177)
    com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:400)
    com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:327)
    com.sun.org.apache.xerces.internal.impl.XMLScanner.reportFatalError(XMLScanner.java:1437)
    com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.startOfMarkup(XMLDocumentFragmentScannerImpl.java:2637)
    com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2735)
    com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
    com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:118)
    com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
    com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
    com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
    com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
    com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
    com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
    com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(SAXParserImpl.java:327)
    org.apache.jasper.compiler.JspDocumentParser.parse(JspDocumentParser.java:195)
    org.apache.jasper.compiler.ParserController.doParse(ParserController.java:226)
    org.apache.jasper.compiler.ParserController.parseDirectives(ParserController.java:119)
    org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:194)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:374)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:354)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:341)
    org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:662)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:364)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:395)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:339)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    jrservlet.JRServlet.doGet(JRServlet.java:41)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.70 logs.

Apache Tomcat/7.0.70

好的,问题是不允许在标签内使用 scriplet。相反,您必须将 scriplet 内容包装在 <jsp:scriptlet> 标签内,

<jsp:scriptlet>
      out.println((String)request.getAttribute("loginFailed"));
</jsp:scriptlet>

为了允许 c:out 和你需要在你的 jsp:root 元素上包含 JSTL 定义的东西,比如,

<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:c="http://java.sun.com/jsp/jstl/core" version="2.0">

其背后的原因是 <jsp:root> 强制使用 XML 语法,因此需要 XML 种常用语法的替代方法,例如 scriptlet。

此外,请参阅更多关于 <jsp:root> here

并且,XML 符合语法 here