都2020年了 还要学JSP吗?

前言

2020年了,还须要学JSP吗?我相信如今仍是在大学的同窗确定会有这个疑问。html

其实我在18年的时候已经见过相似的问题了「JSP还应该学习吗」。我在18年发了几篇JSP的文章,已经有很多的开发者评论『这不是上个世纪的东西了吗』『梦回几年前』『这么老的的东西,怎么还有人学』前端

如今问题来了,JSP放在2020年,是真的老了吗?对,是真的老了java

如今问题又来了,为何在几年前已经被定义『老』的技术,到2020年了仍是有热度,每一年仍是有人在问:『还须要学习JSP吗』。我认为理由也很简单:JSP在以前用的是真的多git

在我初学Java的时候,就常常听到:JSP和PHP是可以写动态网页的---《个人老师》。github

当咱们去找相关的学习资料时,发现处处都是JSP的身影,会给我一种感受:好像不懂JSP就压根无法继续往下学习同样express

若是你是新手,若是你还没学习JSP,我建议仍是能够了解一下,不须要深刻去学习JSP的各类内容,但能够了解一下。至少别人提及JSP的时候,你能知道什么是JSP,能看懂JSP的代码apache

额外说一句:你去到公司,可能还能看到JSP的代码。虽然JSP是『老东西』,但咱们去到公司可能就是维护老的项目。JSP可能不用你本身去写,但至少能看得懂,对不对。后端

问题又来了,那JSP若是是『老东西』,那被什么替代了呢?要么就是用常见的模板引擎『freemarker』『Thymeleaf』『Velocity』,用法其实跟『JSP』差不太多,只是它们的性能会更好。要么先后端分离,后端只须要返回JSON给前端,页面彻底不须要后端管。浏览器

说了这么多,我想说的是:“JSP仍是有必要了解一下,不须要花不少时间,知道便可,这篇文章我就能带你认识JSPtomcat

什么是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

重复一句: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须要学什么

JSP咱们要学的其实两块就够了:JSTL和EL表达式

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>

在2.jsp中获取Session设置的属性

<%@ 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表达式的!

在2.jsp中读取Session设置的属性

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

${name}

</body>
</html>

只用了简简单单的几个字母就能输出Session设置的属性了!而且输出在浏览器上!

使用EL表达式能够方便地读取对象中的属性、提交的参数、JavaBean、甚至集合

JSTL

JSTL全称为 JSP Standard Tag Library 即JSP标准标签库。JSTL做为最基本的标签库,提供了一系列的JSP标签,实现了基本的功能:集合的遍历、数据的输出、字符串的处理、数据的格式化等等!

为何要使用JSTL?

EL表达式不够完美,须要JSTL的支持!在JSP中,咱们前面已经用到了EL表达式,体会到了EL表达式的强大功能:使用EL表达式能够很方便地引用一些JavaBean以及其属性,不会抛出NullPointerException之类的错误!可是,EL表达式很是有限,它不能遍历集合,作逻辑的控制。这时,就须要JSTL的支持了

Scriptlet的可读性,维护性,重用性都十分差!JSTL与HTML代码十分相似,遵循着XML标签语法,使用JSTL让JSP页面显得整洁,可读性很是好,重用性很是高,能够完成复杂的功能!

以前咱们在使用EL表达式获取到集合的数据,遍历集合都是用scriptlet代码循环,如今咱们学了forEach标签就能够舍弃scriptlet代码了。

向Session中设置属性,属性的类型是List集合

<%
        List list = new ArrayList<>();
        list.add("zhongfucheng");
        list.add("ouzicheng");
        list.add("xiaoming");
    
        session.setAttribute("list", list);
    %>

遍历session属性中的List集合,items:即将要迭代的集合。var:当前迭代到的元素

<c:forEach  var="list" items="${list}" >
        ${list}<br>
    </c:forEach>

效果:

生成结果

放干货

如今已经工做有一段时间了,为何还来写JSP呢,缘由有如下几个:

  • 我是一个对排版有追求的人,若是早期关注个人同窗可能会发现,个人GitHub、文章导航的read.me会常常更换。如今的GitHub导航也不合我心意了(太长了),而且早期的文章,说实话排版也不太行,我决定从新搞一波。
  • 个人文章会分发好几个平台,但文章发完了可能就没人看了,而且图床极可能由于平台的防盗链就挂掉了。又由于有不少的读者问我:”你能不能把你的文章转成PDF啊?“
  • 我写过不少系列级的文章,这些文章就几乎不会有太大的改动了,就很是适合把它们给”持久化“。

基于上面的缘由,我决定把个人系列文章汇总成一个PDF/HTML/WORD文档。说实话,打造这么一个文档花了我很多的时间。为了防止白嫖,关注个人公众号回复「888」便可获取。

PDF的内容很是很是长,干货很是很是的硬,有兴趣的同窗能够浏览一波。记住:JSP咱们只须要了解便可,不须要深刻去学习每一个知识点,由于在现实开发中极可能用不上。

文档的内容均为手打,有任何的不懂均可以直接来问我(公众号有个人联系方式)。

上一期的「排序和数据结构」的PDF在公众号反响仍是挺不错的,目标是180个在看,超出了预期,因此我提前更新了

若是此次点赞超过180,那下周再肝一个系列出来。想要看什么,能够留言告诉我

img

涵盖Java后端全部知识点的开源项目(已有6 K star):https://github.com/ZhongFuCheng3y/3y

若是你们想要实时关注我更新的文章以及分享的干货的话,微信搜索Java3y

PDF文档的内容均为手打,有任何的不懂均可以直接来问我(公众号有个人联系方式)。

相关文章
相关标签/搜索