都2020年了 还要学JSP吗?

2022-10-09,,

前言

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?

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,那下周再肝一个系列出来。想要看什么,可以留言告诉我

涵盖java后端所有知识点的开源项目(已有6 k star):https://github.com/zhongfucheng3y/3y

如果大家想要实时关注我更新的文章以及分享的干货的话,微信搜索java3y

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

《都2020年了 还要学JSP吗?.doc》

下载本文的Word格式文档,以方便收藏与打印。