前言
第一次接触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、也有对应目录。
class就不看了,也看不懂,来看看java文件。从中可以看到他是继承org.apache.jasper.runtime.HttpJspBase的,
下面是HttpJspBase的继承结构,他是HttpServlet的子类。
下面这段是输出内容,大量的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代码的痕迹。
但是,我在今天又重新找了一遍,结果,却还真发现一个,下面这段是截图其中的一段,就问你炸不炸,反正我是很讨厌。
另外,下面这个是拿JSTL渲染列表的方式,不香吗?
下面是条件选择,不香吗?
另外要想使用JSTL,那就得引入两个jar,当然,你如果下载了Tomcat,那就自带!!!。有人不信,说:在哪?
在webapps/examples/WEB-INF/lib
下。引入就可以了,(另外,如果你参加了比赛,我想,一般是不直接提供这两个jar的,或许,你可以到这个路径看看)
简单示例
把上述的两个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>
运行效果。