前言

第一次接触jsp是在初中,在学习他后做了一个个人博客,后来一直没使用过他,原因有很多,但是今天还是想记录一篇关于JSP的,多数是因为身边的小伙伴。

我记得我也是从JSP学起的,而非Servlet,先学习了那几个内置对象,后来大概学了一半吧,学Servlet去了,是因为当时跟着教程,人家在JSP中写Java代码,写各种逻辑,写各种循环,当时我因为循环时一个%>忘写了,半天没找出了,有时又是}忘写了,调试半天。后来才知道一般都是Servlet中处理好逻辑,数据传递给JSP,在JSP中使用JSTL渲染,后来也跟着学了学,简直爽了很多。那管什么<%xxx%>,写起来就是一把俊。

当时都后悔先学JSP了。

然而,身边的小伙伴,由于一些原因,都在JSP中写各种逻辑,数据库增删该查,查出来的数据都通过for渲染生成标签。有时候也少写几个%>},找半天,也好在整体代码较少。还容易找。但是,我是崩溃了。

我们都知道JSP最终是编译成Servlet的,也就是Jasper模块,JSP会经历JSP转Servlet,再由Servlet转Class,但是!!,都知道了是这样,空口又无凭,还是来演示一下。

下面是一段简单的JSP,名为index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  $END$
  </body>
</html>

如果项目打包成war后,放入webapps下,运行访问这个jsp,就会在下图路径生成对应.java和.class。如果在Eclipse、IDEA、也有对应目录。

jsp java代码debug jsp中的java代码怎样调试_web


class就不看了,也看不懂,来看看java文件。从中可以看到他是继承org.apache.jasper.runtime.HttpJspBase的,

jsp java代码debug jsp中的java代码怎样调试_servlet_02


下面是HttpJspBase的继承结构,他是HttpServlet的子类。

jsp java代码debug jsp中的java代码怎样调试_web_03


下面这段是输出内容,大量的out.write。是不是像极了你在JSP中输出数据的样子呢?

try {
      response.setContentType("text/html;charset=UTF-8");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("\n");
      out.write("\n");
      out.write("<html>\n");
      out.write("  <head>\n");
      out.write("    <title>$Title$</title>\n");
      out.write("  </head>\n");
      out.write("  <body>\n");
      out.write("  $END$\n");
      out.write("  </body>\n");
      out.write("</html>\n");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              out.clearBuffer();
            }
          } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }

为什么尽量不要在JSP中写Java代码?

这其实可以写的,但是写时一时爽,后期维护性差,页面跳转、业务逻辑、数据库访问这些统统混在一起,放在jsp里面,一锅粥吗这是。一般都是使用Servlet处理逻辑,然后配合JSTL。那时候我也看过不少完整的项目(Github、Gitee上找的),或许是找的少了,没找到一个JSP中有Java代码的痕迹。

但是,我在今天又重新找了一遍,结果,却还真发现一个,下面这段是截图其中的一段,就问你炸不炸,反正我是很讨厌。

jsp java代码debug jsp中的java代码怎样调试_web_04


jsp java代码debug jsp中的java代码怎样调试_java_05


另外,下面这个是拿JSTL渲染列表的方式,不香吗?

jsp java代码debug jsp中的java代码怎样调试_java_06


jsp java代码debug jsp中的java代码怎样调试_web_07


下面是条件选择,不香吗?

jsp java代码debug jsp中的java代码怎样调试_web_08

另外要想使用JSTL,那就得引入两个jar,当然,你如果下载了Tomcat,那就自带!!!。有人不信,说:在哪?

webapps/examples/WEB-INF/lib下。引入就可以了,(另外,如果你参加了比赛,我想,一般是不直接提供这两个jar的,或许,你可以到这个路径看看)

jsp java代码debug jsp中的java代码怎样调试_jsp java代码debug_09

简单示例

把上述的两个jar包导入进去后,编写一个Servlet,在Servlet处理完之后把数据通过HttpServletRequest的setAttribute添加进去,然后转发给index.jsp。

@WebServlet("/TestServlet")
public class TestServlet extends HttpServlet {
    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException
        List<Book> list= new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add(new Book("书名"+i,"作者"+i));
        }
        req.setAttribute("data",list);
        req.getRequestDispatcher("index.jsp").forward(req,resp);
    }
}

但是要注意第一行,要通过@taglib引用核心标签库,其实还有格式化标签、SQL标签、XML 标签、JSTL函数。

<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>$Title$</title>
    <style>
        ul,li{
            list-style: none;
        }
        ul{
            width: 1000px;
            margin: 0 auto;
        }
        li{
            display: flex;
            padding: 13px 0px;

        }
        li span{
            flex: 1;
            text-align: center;
            font-size: 20px;
        }
        li:nth-child(odd){
            background: #f3f3f3;
        }
    </style>
</head>
<body>
    <c:choose>
        <c:when test="${data == null}">集合为空</c:when>
        <c:otherwise>
               <ul>
                   <c:forEach items="${data}" var="item">
                       <li>
                           <span>${item.getBookName()}</span>
                           <span>${item.getBookAuthor()}</span>
                       </li>
                   </c:forEach>
               </ul>
        </c:otherwise>
    </c:choose>
</body>
</html>

运行效果。

jsp java代码debug jsp中的java代码怎样调试_servlet_10