2020年了,还需要学JSP吗?我相信现在还是在大学的同学肯定会有这个疑问。
其实我在18年的时候已经见过类似的问题了「JSP还应该学习吗」。我在18年发了几篇JSP的文章,已经有不少的开发者评论『这不是上个世纪的东西了吗』『梦回几年前』『这么老的的东西,怎么还有人学』
现在问题来了,JSP放在2020年,是真的老了吗? 对,是真的老了
现在问题又来了,为什么在几年前已经被定义『老』的技术,到2020年了还是有热度,每年还是有人在问:『还需要学习JSP吗』。我认为理由也很简单: JSP在之前用的是真的多 !
在我初学Java的时候,就经常听到:JSP和PHP是能够写 动态网页 的---《我的老师》。
当我们去找相关的学习资料时,发现到处都是JSP的身影,会给我一种感觉: 好像不懂JSP就压根没法继续往下学习一样 。
如果你是新手,如果你还没学习JSP,我建议还是可以 了解 一下,不需要深入去学习JSP的各种内容,但可以了解一下。至少别人说起JSP的时候, 你能知道什么是JSP,能看懂JSP的代码 。
额外说一句: 你去到公司,可能还能看到JSP的代码 。虽然JSP是『老东西』,但我们去到公司 可能 就是维护老的项目。JSP可能不用你自己去写,但至少能看得懂,对不对。
问题又来了,那JSP如果是『老东西』,那被什么替代了呢? 要么就是用常见的模板引擎 『freemarker』『Thymeleaf』『Velocity』,用法其实跟『JSP』差不太多,只是它们的性能会更好。 要么前后端分离 ,后端只需要返回 JSON 给前端,页面完全不需要后端管。
说了这么多,我想说的是: “JSP还是有必要了解一下,不需要花很多时间,知道即可,这篇文章我就能带你认识JSP ”
JSP全名为Java Server Pages,java服务器页面。JSP是一种基于文本的程序, 其特点就是HTML和Java代码共同存在 !JSP是为了简化Servlet的工作出现的替代品,Servlet输出HTML非常困难, JSP就是替代Servlet输出HTML的 。
在Tomcat博客中我提到过: Tomcat访问任何的资源都是在访问Servlet !,当然了,JSP也不例外! JSP本身就是一种Servlet 。为什么我说JSP本身就是一种Servlet呢? 其实JSP在第一次被访问的时候会被编译为HttpJspPage类(该类是HttpServlet的一个子类)
比如我随便找一个JSP,编译后的JSP长这个样:
package org.apache.jsp; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*; import java.util.Date; public final class _1_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent { private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory(); private static java.util.List<String> _jspx_dependants; private javax.el.ExpressionFactory _el_expressionfactory; private org.apache.tomcat.InstanceManager _jsp_instancemanager; public java.util.List<String> getDependants() { return _jspx_dependants; } public void _jspInit() { _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig()); } public void _jspDestroy() { } public void _jspService(final HttpServletRequest request, final HttpServletResponse response) throws java.io.IOException, ServletException { final PageContext pageContext; HttpSession session = null; final ServletContext application; final ServletConfig config; JspWriter out = null; final Object page = this; JspWriter _jspx_out = null; PageContext _jspx_page_context = null; 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("/r/n"); out.write("/r/n"); out.write("<html>/r/n"); out.write("<head>/r/n"); out.write(" <title>简单使用JSP</title>/r/n"); out.write("</head>/r/n"); out.write("<body>/r/n"); String s = "HelloWorda"; out.println(s); out.write("/r/n"); out.write("</body>/r/n"); out.write("</html>/r/n"); } catch (Throwable t) { if (!(t instanceof SkipPageException)){ out = _jspx_out; if (out != null && out.getBufferSize() != 0) try { out.clearBuffer(); } catch (java.io.IOException e) {} if (_jspx_page_context != null) _jspx_page_context.handlePageException(t); } } finally { _jspxFactory.releasePageContext(_jspx_page_context); } } }
编译过程是这样子的: 浏览器第一次请求1.jsp时,Tomcat会将1.jsp转化成1_jsp.java这么一个类,并将该文件编译成class文件。编译完毕后再运行class文件来响应浏览器的请求 。
以后访问1.jsp就不再重新编译jsp文件了,直接调用class文件来响应浏览器。当然了, 如果Tomcat检测到JSP页面改动了的话,会重新编译的 。
既然JSP是一个Servlet, 那JSP页面中的HTML排版标签是怎么样被发送到浏览器的 ?我们来看下上面1_jsp.java的源码就知道了。原来就是用write()出去的罢了。 说到底,JSP就是封装了Servlet的java程序罢了。
out.write("/r/n"); out.write("/r/n"); out.write("<html>/r/n"); out.write("<head>/r/n"); out.write(" <title>简单使用JSP</title>/r/n"); out.write("</head>/r/n"); out.write("<body>/r/n");
有人可能也会问: JSP页面的代码服务器是怎么执行的 ?再看回1_jsp.java文件, java代码就直接在类中的service()中。
String s = "HelloWorda"; out.println(s);
JSP内置了9个对象!内置对象有:out、session、response、request、config、page、application、pageContext、exception。
重要要记住的是: JSP的本质其实就是Servlet 。只是JSP当初设计的目的是为了简化Servlet输出HTML代码。
重复一句: JSP的本质其实就是Servlet 。只是JSP当初设计的目的是为了简化Servlet输出HTML代码。
我们的Java代码还是写在Servlet上的,不会写在JSP上。在知乎曾经看到一个问题:“如何使用JSP连接JDBC”。显然, 我们可以这样做,但是没必要 。
JSP看起来就像是一个HTML,再往里边增加大量的Java代码,这是不正常,不容易阅读的。
所以,我们一般的模式是: 在Servlet处理好的数据,转发到JSP,JSP只管对小部分的数据处理以及JSP本身写好的页面。
例如,下面的Servlet处理好表单的数据,放在request对象,转发到JSP
//验证表单的数据是否合法,如果不合法就跳转回去注册的页面 if(formBean.validate()==false){ //在跳转之前,把formbean对象传递给注册页面 request.setAttribute("formbean", formBean); request.getRequestDispatcher("/WEB-INF/register.jsp").forward(request, response); return; }
JSP拿到Servlet处理好的数据,做显示使用:
JSP我们要学的其实两块就够了: JSTL和EL表达式
表达式语言(Expression Language,EL),EL表达式是用 ${}
括起来的脚本,用来更方便的读取对象! EL表达式主要用来读取数据,进行内容的显示!
为什么要使用EL表达式?我们先来看一下 没有EL表达式是怎么样读取对象数据的吧 !在1.jsp中设置了Session属性
<%@ page language="java" contentType="text/html" pageEncoding="UTF-8"%> <html> <head> <title>向session设置一个属性</title> </head> <body> <% //向session设置一个属性 session.setAttribute("name", "aaa"); System.out.println("向session设置了一个属性"); %> </body> </html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title></title> </head> <body> <% String value = (String) session.getAttribute("name"); out.write(value); %> </body> </html>
效果:
上面看起来,也没有多复杂呀,那我们试试EL表达式的!
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title></title> </head> <body> ${name} </body> </html>
使用EL表达式 可以方便地读取对象中的属性、提交的参数、JavaBean、甚至集合 !
JSTL全称为 JSP Standard Tag Library 即JSP标准标签库。JSTL作为最基本的标签库, 提供了一系列的JSP标签,实现了基本的功能:集合的遍历、数据的输出、字符串的处理、数据的格式化等等!
EL表达式不够完美,需要JSTL的支持!在JSP中,我们前面已经用到了EL表达式,体会到了EL表达式的强大功能: 使用EL表达式可以很方便地引用一些JavaBean以及其属性,不会抛出NullPointerException之类的错误! 但是,EL表达式非常有限, 它不能遍历集合,做逻辑的控制。这时,就需要JSTL的支持了 !
Scriptlet的可读性,维护性,重用性都十分差!JSTL与HTML代码十分类似,遵循着XML标签语法, 使用JSTL让JSP页面显得整洁,可读性非常好,重用性非常高,可以完成复杂的功能!
之前我们在使用EL表达式获取到集合的数据,遍历集合都是用scriptlet代码循环,现在我们学了forEach标签就可以舍弃scriptlet代码了。
<% List list = new ArrayList<>(); list.add("zhongfucheng"); list.add("ouzicheng"); list.add("xiaoming"); session.setAttribute("list", list); %>
<c:forEach var="list" items="${list}" > ${list}<br> </c:forEach>
效果:
现在已经工作有一段时间了,为什么还来写 JSP
呢,原因有以下几个:
read.me
会经常更换。现在的 GitHub 导航也不合我心意了(太长了),并且早期的文章,说实话排版也不太行,我决定重新搞一波。 基于上面的原因,我决定把我的系列文章汇总成一个 PDF/HTML/WORD
文档。说实话,打造这么一个文档 花了我不少的时间 。为了防止 白嫖 ,关注我的公众号回复「 888 」即可获取。
文档的内容 均为手打 ,有任何的不懂都可以直接 来问我 (公众号有我的联系方式)。
上一期的「 排序和数据结构 」的 PDF 在公众号反响还是挺不错的,目标是 180 个在看, 超出了预期,所以我提早更新了 。
如果 这次点赞超过180 ,那下周再肝一个系列出来。 想要看什么,可以留言告诉我
如果大家想要 实时 关注我更新的文章以及分享的干货的话,微信搜索 Java3y 。
PDF文档的内容 均为手打 ,有任何的不懂都可以直接 来问我 (公众号有我的联系方式)。