【Java】学习笔记3——从入门到菜鸡(Web编程&JSP篇)

写在前面

【Java】学习笔记2——从小白到入门(技术提升篇)里记录了Java中的接口、继承、类包、异常处理、I/O流、线程、数据库的一些知识。现在自学Java也快半个月了,为了更好地和小学期的课程对接,是时候开始进军Java网络编程以及更高级的JSP技术了。本篇博客也将继续记录我学习Java网络编程以及JSP技术的学习历程和心得体会。
————————————————————————————————————————————————————

2020.7.5 【Day15】

网络程序设计编写的是与其他计算机进行通信的程序,可以实现两台计算机之间的通信,我们必须用一个网络线路连接两台计算机。网络的两端分别是服务器和客户机,服务器指的是提供信息的计算机或程序,而客户机是指请求信息的计算机或程序,二者之间通过网络相连接实现相互通信。

局域网(LAN)是一群通过一定形式连接起来的计算机,将局域网延伸便得到了广域网(WAN),而因特网(Internet)正是由无数个LAN和WAN连接而成的。

IP协议

IP(Internet Protocol)协议是最常见的网络协议之一。而协议指的是定义计算机如何通信的一组明确的规则。Internet网络上有几亿台主机,每台主机都有一个独有的IP地址与之对应,其代表了其在网络上的地址。IPv4通过32位的二进制数来表示IP地址,通常取用每个字节的十进制数,并且每个字节之间用“.”隔开。但是随着IPv4地址即将全部耗尽,更加先进的IPv6也正在逐步取代传统的IPv4。IPv6则是通过128位的二进制数来表示IP地址,它的各方面性能也优于IPv4。(比如,知乎已经支持IPv6了)

这不是广告
 
TCP&UDP协议

TCP(Transmission Control Protocol)意为传输控制协议,其是一种以固接连线为基础的协议,运用于两台计算机之间的数据传送。TCP协议保证了从一端数据送至连接的另一端时,数据能够准确无误地送达,因此TCP的安全可靠性很高,缺点是只能向一个目标发送数据,传输速度也较慢。

UDP(User Datagram Protocol)意为用户数据报协议,其是一种无连接通信协议,其能向若干个目标发送数据或接收来自若干个源的数据,因此UDP协议适用于对传输速度和时效性要求高的场景,但缺点是不保证数据传输的可靠性。

将TCP协议和IP协议结合便得到了TCP/IP模式,其是一种层次结构。从顶层到底层分别是:应用层、传输层、互联网层、网络层。各层实现特定的功能,提供特定的服务和访问接口,具有独立性。图示如下:
在这里插入图片描述
端口和套接字

网络程序设计中的端口并非真实存在的物理端口,而是一个0~65535之间的整数。HTTP服务使用80端口,FTP服务使用21端口。如果计算机提供了多种服务,则客户机会通过不同的端口来确定连接到服务器的哪项服务上。

通常0~1023之间的端口数用于一些知名的网络服务和应用,普通的用户端口则使用的是1024 ~65535之间的端口,以避免端口冲突。

套接字用于将应用程序与端口连接起来,其是一个抽象的连接装置。Java通常将套接字抽象化为类,我们只需要创建Socket类的对象即可使用套接字。

TCP程序设计

TCP程序设计说白了就是利用Socket类编写服务器和客户机之间通信的程序。由于服务器和客户机有所不同,所以对它们进行编写的方法也不一样。

服务器与客户机的交互过程如下:

1.服务器程序先创建一个服务器端套接字ServerSocket,之后调用accept()方法等待客户机来连接。

2.之后客户机端程序创建一个Socket类,并请求与服务器建立连接。

3.服务器接收客户机的连接请求,同时创建一个新的Socket类与客户建立连接。

4.服务器端继续等待新的请求。

在开始TCP程序设计之前,我们还要了解一个和IP地址相关的java.net.InetAddress类。利用这个类,我们可以获取IP地址、主机地址等等。常用方法如下图所示:
在这里插入图片描述
例如,获取本地主机的本机名、本机IP地址的程序为:

import java.net.*;  //导入包

public class Address
{
	public static void main(String args[])
	{
		InetAddress ip;  //创建对象
		try
		{
			ip=InetAddress.getLocalHost();  //实例化对象
			String localname=ip.getHostName();  //获取本机名
			String localip=ip.getHostAddress();  //获取本机IP地址
			System.out.println("本机名:"+localname);
			System.out.println("本机IP地址:"+localip);
		}
		catch(UnknownHostException e)  //若主机不存在或网络连接错误时会发生异常
		{
			e.printStackTrace();
		}
	}
}

程序输出:

本机名:LAPTOP-XXXXXXXX
本机IP地址:192.168.0.XXX

可以看出,InetAddress类十分重要,可以说是网络程序设计的基础类之一。
————————————————————————————————————————————————————

2020.7.6 【Day16】

ServerSocket类

ServerSocket类用于表示服务器套接字,其功能是等待接收客户机的请求,并通过指定的端口来等待连接的套接字。服务器的套接字一次只能与一个套接字连接如果同时由多个请求,则套接字会将客户机存入队列(大小为50)中,再逐个连接。如果请求的连接数大于服务器套接字的最大容纳数,则多余的客户机请求会被拒绝,无法进行连接。

ServerSocket类有四种构造方法:

ServerSocket():
创建非绑定服务器套接字。

ServerSocket(int port):
创建绑定到特定端口的服务器套接字。

ServerSocket(int port,int backlog):
利用指定的backlog创建服务器套接字,并将其绑定到指定的本地端口号上。

ServerSocket(int port,int backlog,InetAddress bindAddress):
使用指定的端口、侦听backlog和要绑定到的本地IP地址创建服务器。

ServerSocket类的常用方法如下表所示:
在这里插入图片描述
服务器端的Socket对象使用getOutputStream()方法获得的输出流,将指向客户端Socket对象使用getInputStream()方法获得的那个输入流;服务器端的Socket对象使用getInputStream()方法获得的输入流,将指向客户端Socket对象使用getOutputStream()方法获得的那个输出流。简而言之就是:当服务器向输出流写入信息时,客户端通过相应的输入流就能获取,反之亦然。

在网络编程中,如果只是客户机向服务器发送信息,则为单向通信。单向通信中,当客户机和服务器套接字连接成功后,客户机通过输出流发送数据,服务器通过输入流接收数据。服务器端的代码示例如下:

import java.io.*;
import java.net.*;

public class MyTCP
{
    //创建对象
    private BufferedReader reader;
    private ServerSocket server;
    private Socket socket;
    
    void getserver()
    {
        try
        {
            server=new ServerSocket(8998);  //实例化Socket对象
            System.out.println("服务器的套接字已经创建成功!");
            while(true)  //如果套接字是连接状态
            {
                System.out.println("等待客户机的连接。");
                socket=server.accept();
                reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));  //实例化BufferedReader对象
                getClientMessage();
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
    
    private void getClientMessage()
    {
        try
        {
            while(true)  //如果套接字是连接状态
            {
                System.out.println("客户机:"+reader.readLine());  //获得客户端信息
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        try
        {
            if(reader!=null)
            {
                reader.close();  //关闭流
            }
            if(socket!=null)
            {
                socket.close();  //关闭套接字
            }
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
    }
    
    public static void main(String []args)
    {
        MyTCP tcp=new MyTCP();
        tcp.getserver();
    }
}

程序输出:

服务器的套接字已经创建成功!
等待客户机的连接。

大家可能发现了,这个程序并没有输出“客户机:”字样,这说明了客户机压根就没有成功连接到服务器端。这是为什么呢?

查阅资料后,发现这是因为系统的防火墙拦截了这个连接的过程,毕竟这个服务器端的安全性未知,这样做也是为了保护客户机的信息安全。

2020.7.7 【Day17】

UDP程序设计

与TCP不同,UDP是网络信息传输的另一种形式,其可以提供更多更快的信息传输,但是不能提供可靠的保证。因此,在使用UDP传递数据时,我们无法知道数据能否正确到达主机,也不知道其顺序是否发生改变。虽然UDP如此不可靠,但是为了追求更快地传递信息并能够允许小错误,UDP将是不二之选。

UDP通信的基本模式分为两步:第一步是将数据打包为数据包,然后将数据包发往目的地。第二步是接收别人发来的数据包,然后查看数据包。

关于数据包的操作需要用到DatagramPacket类和DatagramSocket类,这两个类也是UDP程序设计中最为核心的两个类。

发送数据包分为三个步骤:

1.使用DatagramSocket()创建一个数据包套接字。

2.使用DatagramPacket(byte[] buf,int offset,int length,InetAddress address,int port)创建要发送的数据包。

3.使用DatagramSocket类的send()方法发送数据包。

接收数据包也分为三个步骤:

1.使用DatagramSocket(int port)创建数据包套接字,绑定到指定的端口。

2.使用DatagramPacket(byte[] buf,int length)创建字节数组来接收数据包。

3.使用DatagramPacket类的receive()方法接收UDP包。

DatagramPacket类

DatagramPacket类用来表示数据包,其有两种构造函数:

DatagramPacket(byte[] buf,int length)
此种构造方法在创建对象时指定了数据包的内存空间和大小。

DatagramPacket(byte[] buf,int length,InetAddress address,int port)
此种构造方法不仅仅指定了数据包的内存空间和大小,还指定了数据包的目标地址和端口。

DatagramPacket类

DatagramPacket类用来表示发送和接收数据包的套接字,其有三种构造方法:

DatagramSocket()
创建对象后,构造数据报套接字,并将其绑定到本地主机任何可用的端口上。

DatagramSocket(int port)
创建对象后,构造数据报套接字,并将其绑定到本地主机的指定端口上。

DatagramSocket(int port,InetAddress addr)
创建对象后,构造数据报套接字,并将其绑定到指定的本地地址上。

此外,在接收程序的时候必须指定一个端口号(使用第二种构造方法
),否则系统不知道地址,就达不到信息接收的目的。而发送程序的时候可以使用第一种构造方法,此时端口号由系统随机产生。

我们用广播数据报程序来体会UDP程序设计:

import java.net.*;

public class Weather extends Thread  //多线程程序
{
    String weather="注意,未来几日多地有持续性暴雨天气,请相关单位严防中小河流洪水、突发地质灾害和城市内涝。";  //声明广播内容
    int port=9898;  //定义端口
    InetAddress iaddress=null;    //创建InetAddress对象,初始为空
    MulticastSocket socket=null;  //创建MulticastSocket对象,初始为空
    
    Weather()  //构造方法
    {
        try
        {
            iaddress=InetAddress.getByName("224.255.10.0");  //实例化InetAddress对象,指定地址
            socket=new MulticastSocket(port);  //实例化广播套接字
            socket.setTimeToLive(1);  //指定发送范围和本地网络
            socket.joinGroup(iaddress);  //加入广播组
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
    public void run()  //运行方法
    {
        while(true)
        {
            DatagramPacket packet=null;  //声明DatagramPacket对象,初始为空
            byte data[]=weather.getBytes();  //声明字节型数组
            packet=new DatagramPacket(data,data.length,iaddress,port);  //打包数据
            System.out.println(new String(data));  //输出广播信息
            try
            {
                socket.send(packet);  //发送数据
                sleep(3000);  //线程休眠3秒
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }
    }
    public static void main(String []args)  //主方法
    {
        Weather w=new Weather();  //创建本类对象
        w.start();  //启动线程
    }
}

程序输出:

注意,未来几日多地有持续性暴雨天气,请相关单位严防中小河流洪水、突发地质灾害和城市内涝。
注意,未来几日多地有持续性暴雨天气,请相关单位严防中小河流洪水、突发地质灾害和城市内涝。
注意,未来几日多地有持续性暴雨天气,请相关单位严防中小河流洪水、突发地质灾害和城市内涝。

......(每隔3秒输出一条广播信息)

2020.7.8 【Day18】

今天正式开始学习JSP技术了!

JSP(Java Server Page)是一种基于Java Servlet和整个Java体系的Web开发技术,利用JSP可以建立安全、跨平台的先进动态网站。简而言之,JSP就是做动态网站的。

在网络应用中,最常见的交互模式(B/S模式)是这样的:用户想要获取某些信息,所以他打开浏览器,与此同时浏览器向服务器发出相关请求,为了满足用户通过浏览器发来的需求,服务器就需要通过很多Web应用程序来完成这个过程。这些Web应用程序需要一个统一的软件来统一管理和运行,如果这些Web应用程序都是基于JSP技术的,那么这样的软件就称为JSP引擎。而安装了JSP引擎的计算机则被称为支持JSP的一个Web服务器,支持JSP的Web服务器负责运行JSP,同时把运行的结果向用户呈现。

要想把自己的计算机变成支持JSP的Web服务器,首先要安装JDK和JSP引擎。我用的JSP引擎是Tomcat,下载安装步骤可以参考这篇博文:

TomCAT安装以及使用详细解释

和当初配置JDK一样,配置Tomcat的过程也是让我煞费苦心。一开始出现的问题是点击stsrtup.bat之后就出现闪退,七搞八弄地操作了一番之后,startup.bat总算是成功打开了。
在这里插入图片描述
按照常理,只要保证这个startup.bat的小黑窗一直开启,我在浏览器输入http:\localhost:8080就可以成功进入Tomcat服务器的测试界面。但是,我在浏览器输入地址之后却出现了无法访问页面的字样,简直要崩溃了啊!

在这里插入图片描述
后来又经过一番查询,发现是浏览器的问题,我用的是谷歌浏览器chrome,但是chrome自带防火墙,它会阻止一些可能有隐患的操作。之后我换用了微软的Microsoft Edge浏览器,终于成功了!


之后又测试了IE浏览器Internet explore,也可以成功进入测试界面。
在这里插入图片描述

通过这个地址我们可以看出,Tomcat服务器默认占用8080端口。当然,如果不想用这个端口,或者这个端口已经连接了其他服务器,我们也可以重新配置端口。只要打开安装文件目录下的conf\server.xml,找到下面这段代码,将port后面的值修改为目标端口值即可(比如8848什么的/滑稽)。

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

JSP页面

JSP页面是多种标记语言和Java编程语言的集合,JSP文件的扩展名是.jsp。一个JSP页面中可以有HTML标记和JSP标记,也有通过<% %>括起来的Java程序片。我们可以使用记事本来编辑JSP页面,在保存时必须将保存类型设置成所有类型,编码选择ANSI。但是系统默认保存文件为.txt格式,如果想要保存为.jsp格式,只需将文件名和扩展名两边用双引号括起来即可。
————————————————————————————————————————————————————

2020.7.9 【Day19】

我们来写第一个JSP程序。

首先在netbeans 8.1里面创建一个Java Web项目,选择Web应用程序。
在这里插入图片描述
在创建的第三步,是选择服务器的界面:
在这里插入图片描述
当然,在第一次创建Web应用程序的时候服务器是用netbeans 8.1自带的Glassfish服务器,要想换用Tomcat服务器,可以点击旁边的添加,找到Tomcat服务器的安装目录,设置好用户名和密码,就可以将服务器换成Tomcat了。

对了,这个地方有一个小插曲。我昨天装的Tomcat服务器是最新的10.0版本,但是由于小学期用的IDE是比较老的netbeans 8.1,所以两者并不兼容,如果用的是Tomcat 8.0以上的版本,在添加服务器的时候netbeans 8.1无法识别,所以会报错说没有找到服务器啥的。所以,我不得不把Tomcat换成了7.0版本,这下netbeans 8.1就可以找到服务器了。版本之间不兼容的问题最近可是把我弄昏了。

在这里插入图片描述
把服务器安排妥当之后,我的第一个Web应用程序便创建完成了。
在这里插入图片描述
由于之前稍微学过一点HTML,所以这些标记还是基本能够轻松看懂。上方的< title >< /title >之间的文字是网页的名称,可以加以修改。< body >< /body >之间则是用来写我们的JSP相关代码,比如说HTML标记、JSP标记和Java程序片,我在Hello World!之后又加了两条不同大小的标题,最后运行的结果是一个IE浏览器的网页:
在这里插入图片描述
我们再在这个页面中插入Java程序片,使得页面能够输出程序的运行结果。代码如下:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>这是我做的第一个JSP页面</title>
    </head>
    <body>
        <h1>Hello World!</h1>
        <h2>Today is a nice day.</h2>
        <h3>The rain has stopped.</h3>
        
        <%
            int i,sum=0;
            for(i=1;i<=100;i++)
            {
                sum+=i;
            }
        %>
        <h3>1加到100的连续和是:<% out.println(sum); %> </h3>
    </body>
</html>

页面显示:
在这里插入图片描述
————————————————————————————————————————————————————

2020.7.10 【Day20】

JSP的运行原理

当服务器上的一个JSP页面被第一次请求执行时,服务器上的JSP引擎首先会将.jsp文件转译成一个.java文件,经过编译之后形成字节码文件,之后执行字节码文件满足客户的需求。当这个JSP页面再次被执行的时候,JSP引擎则省去了转译步骤,直接执行字节码文件满足客户的需求。这样一来就大大加快了JSP页面的加载速度,也算是JSP的优点之一。

说到字节码文件,它的主要工作是:把JSP页面中用HTML标记的静态部分交给浏览器显示。再处理JSP标记,并将有关的处理结果发到用户的浏览器。之后执行用<%%>括起来的Java程序片(动态部分),并将结果交给浏览器显示。当有多个用户请求一个JSP页面时,服务器会为每一个用户启动一个线程,该线程负责执行字节码文件来响应客户的需求。

JSP与Java Servlet的关系

Java Servlet翻译过来就是Java小应用程序,其提供了用于服务器编程的API,也是Java语言的一部分,我们习惯上将其称为Servlet类,其对象称为servlet。Java Servlet作为一个单独的存在,其无法有效地管理页面的逻辑部分和页面的输出部分。JSP技术正是以Servlet类为基础,并几乎涵盖了Servlet所有功能的更高级的建立动态网站的技术,其可以算作Servlet类的一个成功应用。

今天主要还是复习一下之前学过一部分的HTML标记语句。有关知识过多,就不在此一一列举了。

HTML学习网站链接:

HTML学习网站

————————————————————————————————————————————————————

2020.7.11 【Day21】

今天学习JSP指令。

声明变量和方法

JSP通过在<%!和%>标记符之间声明变量,即在这两个标记符之间放置Java的变量声明语句。变量的类型可以是Java语言允许的任何数据类型,这些变量也被称为JSP页面的成员变量。JSP页面的成员变量在整个JSP页面内都有效,我们习惯把它写在JSP页面的前面。

例如,计算网页访客量的JSP程序为:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <%!
        int i=0;
    %>
    <%
        i++;
    %>
    <body>
        <p>您是第<%=i%>个访问本站的客户!</p>
    </body>
</html>

第三次运行的页面显示为:
在这里插入图片描述
利用<%!和%>这一对标记符号还可以定义方法,这些方法在整个JSP页面都有效,也可以在Java程序片中被调用。方法内声明的变量只在该方法内有效,当方法被调用时,方法内声明的变量被分配内存,方法被调用完毕即可释放这些变量所占的内存。

例如下面这个JSP程序:

<%@ page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    
    <body>
        <%!
        double addition(double x,double y)  //定义加法方法
        {
            return x+y;
        }
        double subtraction(double x,double y)  //定义减法方法
        {
            return x-y;
        }
        double multiplication(double x,double y)  //定义乘法方法
        {
            return x*y;
        }
        double division(double x,double y)  //定义除法方法
        {
            return x/y;
        }
        %>
        
        <%
            double x=16.5,y=3.3;
            out.println("16.5与3.3的和为"+addition(x,y)+"<br>");
            out.println("16.5与3.3的差为"+subtraction(x,y)+"<br>");
            out.println("16.5与3.3的积为"+multiplication(x,y)+"<br>");
            out.println("16.5与3.3的商为"+division(x,y));
        %>
    </body>
</html>

页面显示:
在这里插入图片描述

Java程序片

我们可以在<%和%>标记之间插入Java程序片。一个JSP页面可以有多个程序片,这些程序片将被JSP引擎按照顺序执行。在程序片中声明的变量称为JSP页面的局部变量,局部变量的有效范围与其声明的位置有关,局部变量在同一个页面中的所有后继程序片中都有效。正因如此,我们可以将一个大的Java程序片拆分为几个小的Java程序片,然后在这些小的程序片之间加入HTML标记,这样灵活使用可以更好地显示页面。

如果同时有多个用户调用同一个成员变量或成员方法,这个时候就存在用户信息泄露的风险,为了避免这种情况发生,我们可以使用synchronized关键字进行修饰。这样一来,当有用户调用这个方法时,其余用户必须等该用户使用完之后才能再次使用该方法,这也同多线程的原理一致。

Java表达式

我们可以在<%=和%>之间插入一个表达式,但不可以插入一个语句。这个表达式必须能够求值,表达式的值由服务器负责计算,并将计算结果以字符串的形式发送到客户端显示。

例如,计算一个表达式的值的JSP程序如下:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        
        <%
            int a=2,b=5;
            out.println("2+5*2-5的值为:");
        %>
        
        <%= a+b*a-b %>
        
    </body>
</html>

页面显示:
在这里插入图片描述
JSP中的注释

JSP页面中的注释有两种:HTML注释和JSP注释。

HTML注释:

<!--  注释内容  -->

JSP注释:

<%--  注释内容  --%>

JSP引擎把HTML注释交给用户,因此用户通过浏览器查看JSP页面的源文件时,能够看到HTML注释。而JSP引擎会直接忽略JSP注释,即在编译JSP页面的时候忽略JSP注释。
 
JSP指令标记

1.page指令标记

page指令用来定义整个JSP页面的一些属性和这些属性的值,属性值用引号括起来,同一个page指令可以指定多个属性的值。page指令的作用对整个JSP页面均有效,我们习惯上将page指令写在JSP程序的最前面。

page指令可以指定的属性有:contentType、import、language、session、buffer、autoFlush、isThreadSafe、info。

contentType属性用来确定JSP页面响应的MIME类型和JSP页面字符的编码。其一般形式为:

"MIME类型;charset=编码"

如果我们希望用户的浏览器以网页形式打开所接收到的信息,我们可以这么设置contentType属性的值:

<%@ page contentType="text/html;charset=gb2312" %>

我们可以发现,在Netbeans里面新建一个Web应用的时候,系统会自动地将contentType属性的值设置成"text/html",这也是默认的属性值。

language属性用来设置JSP页面所使用的脚本语言,其有且仅有一个值“java”。由于这个属性有唯一固定的值,所以通常在JSP程序当中忽略这个属性,直接使用默认值。

import属性的作用是为JSP页面引入Java运行环境提供的包中的类,这样一来就能够在JSP页面的程序片部分、变量及方法定义部分以及表达式部分使用包中的类。JSP页面默认import属性已有"java.lang.*"、“java.servlet. *”、“javax.servlet.jsp. *”、"javax.servlet.http. *"四个值。除此之外,我们还可以导入其他类,例如:

<%@ page import="java.util.*"

session属性用于设置是否需要内置的session对象,其值有“true”和“false”两种,默认值为true。

buffer属性用来指定输出流对象out设置的缓冲区的大小或不使用缓冲区。其默认值为8KB,其也可取空值none。

autoFlush属性用于指定out的缓冲区被填满时,缓冲区是否自动刷新。其值有“true”和“false”两种,默认值为true。

isThreadSafe属性用来指定JSP页面可否被多线程访问,其值有“true”和“false”两种,默认值为true。为true时,可以被多线程访问,否则不能被多线程访问。

info属性的属性值是一个字符串,其目的是为JSP页面准备一个常用但可能要经常修改的字符串,有些类似于C语言当中的宏定义。

page指令标记的属性众多,很难全部记忆,掌握像contentType属性等常用属性的用法即可。

2.include指令标记

include指令标记用于在JSP页面中某处静态嵌入一个文件。其语法格式为:

<%@ include file="URL地址" %>

使用include指令可以实现代码复用。例如,一个JSP页面上可能需要一个导航条,以便用户在各个JSP页面之间方便地切换,那么每个JSP页面都可以使用include指令在页面的适当位置整体嵌入一个相同的文件。
 
JSP动作标记

动作标记是一种特殊的标记,它影响着JSP运行时的功能。JSP动作标记分为include、param、forward、useBean四种动作标记。

include动作标记告诉JSP页面动态包含一个文件,即JSP页面运行时才将文件加入。与静态插入的include指令标记不同,当JSP引擎把JSP页面转译成Jav文件时,其不把JSP页面中动作指令include所包含的文件与原JSP页面合并为一个新的JSP页面,而是告诉编译器这个文件在JSP页面运行的时候才能内包含进来。include动作标记的语法格式为:

<jsp:include page="URL地址" />

param标记以“名字——值”对的形式为其他标记提供附加信息,其无法独立使用,必须作为其他标记的子标记来使用,其语法格式为:

<jsp:param name="名字" value="指定给param的值">

forward动作标记的作用是,从该指令处停止当前页面的执行,而转向执行page属性指定的JSP页面。其语法格式为:

<jsp:forward page="要转向的页面" />

需要注意的是,当前页面使用forward动作标记转向后,尽管用户看到了转向后的页面的效果,但是浏览器显示的地址仍然是之前页面的URL地址。

useBean动作标记用来创建一个Javabean,此标记甚为重要,其与我明天将要学习的Javabean息息相关。简单地说就是:

Javabean用来负责存储数据,JSP页面显示Javabean中的数据,servlet负责管理Javabean中的数据。
————————————————————————————————————————————————————

2020.7.12 【Day22】

今天学习Javabean相关的知识。

Javabean是一个可重复使用的软件组件,其本质是一个Java类,其封装属性和方法之后可以实例化为一个bean对象。Javabean有三个特点:可以实现代码的重复利用;易编写、易维护、易使用;可以在任何安装了JDK的环境下使用,不需要编译。

JSP页面可以将数据的处理过程指派给若干个bean来完成,并将有关处理结果存放到bean中,由此观之JSP页面只需负责显示结果即可,无需承担存储功能。

Javabean分为可视组件和非可视组件,在JSP页面中常用的是非可视组件。由于JSP页面需要使用Javabean类,所以bean类中所有的方法属性必须为public,bean中的构造方法也必须无参数。我们在编写Javabean类的时候需要加入两个成员方法:getXxx()和setXxx()。前者用来获取属性Xxx,后者用来修改属性Xxx,这样一来使用这个bean的程序就可以知道bean里面的属性和方法。当然,对于boolean类型的属性,我们可以使用isXxx()方法来命名。

我们在myJavabeans包里面写一个Javabean类Circle:

package myJavabeans;

import static java.lang.Math.*;

public class Circle 
{
    double r;
    public Circle()
    {
        r=1;
    }
    public double getR()
    {
        return r;
    }
    public void setR(double new_r)
    {
        r=new_r;
    }
    public double circleArea()
    {
        return PI*r*r;
    }
    public double circleLength()
    {
        return 2*PI*r;
    }
}

之后将这个.java文件保存至服务器的webapps目录下,让服务器可以使用。

在写完Javabean类的代码之后,我们就可以用动作标记useBean来使用bean,其语法格式为:

<jsp:useBean id="bean的名字" class="创建bean的字节码" scope="bean的有效范围"/><jsp:useBean id="bean的名字" class="创建bean的类" scope="bean的有效范围">
</jsp:useBean>

其中的scope属性限定了bean的有效范围。如果其值为page,那么其有效范围为当前页面,当页面执行完毕,bean也就会被释放掉。如果其值为session,那么其有效范围就是仅在与用户交互期间有效。如果其值为requeat,则其也在当前页面有效,但是其有效时间略长于page,其内部原因比较复杂。如果其值为application,则此时任何一个用户对自己的bean的属性的改变都会影响到其他用户。

接着我们写一个使用Circle这个Javabean的JSP页面:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    
    <body>
        <jsp:useBean id="circle" class="myJavabeans.Circle" scope="page"/>
        <p>
            圆的初始半径为:<%=circle.getR()%>
            <%
                double new_r=100;
                circle.setR(new_r);
            %>
            <br>
            修改后的半径为:<%=circle.getR()%>
            <br>
            当前圆的周长为:<%=circle.circleLength()%>
            <br>
            当前圆的面积为:<%=circle.circleArea()%>              
        </p>
    </body>
</html>

页面显示:
在这里插入图片描述
从上面这个例子可以看出,使用useBean动作标记获得一个bean之后,这个bean就可以在Java程序片中调用Javabean类的方法。我们还可以利用getProperty和setProperty两种动作标记来获取和修改bean中的属性。

getProperty动作标记可以获得bean的属性值,并将这个值以串的形式发送到用户的浏览器,其语法格式为:

<jsp:getProperty name="bean的id名" property="bean的属性"/>

这个式子与下面这个式子等价:

<%=bean.getXxx()%>

setProperty动作标记可以通过两种方法设置bean的属性值,一是将bean属性的值设置为一个表达式的值或字符串,二是通过HTTP表单的参数的值来设置bean的相应属性的值。

我们再来通过一个三角形bean来理解JSP和Javabean之间的关系:

先写Javabean类:

package myJavabeans;

public class Triangle
{
    double a,b,c,s;
    boolean t;
    public void setA(double aa)
    {
        a=aa;
    }
    public void setB(double bb)
    {
        b=bb;
    }
    public void setC(double cc)
    {
        c=cc;
    }
    public double getA()
    {
        return a;
    }
    public double getB()
    {
        return b;
    }
    public double getC()
    {
        return c;
    }
    public double getS()
    {
        double p=(a+b+c)/2;
        if(t)
        {
            s=Math.sqrt(p*(p-a)*(p-b)*(p-c));
        }
        return s;
    }
    public boolean isT()
    {
        if(a+b>c && a+c>b && b+c>a)
        {
            t=true;
        }
        else
        {
            t=false;
        }
        return t;
    }
}

再写JSP页面:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<jsp:useBean id="tri" class="myJavabeans.Triangle" scope="request"/>

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    
    <body bgcolor="#AAFF99">
        <font size=3>
            <form action="" method="post">
                请输入三角形三边:
                边A:<input type=text name="a" value=0 size=5>
                边B:<input type=text name="b" value=0 size=5>
                边C:<input type=text name="c" value=0 size=5>
                <input type=submit value="确认">
            </form>
            <br>
            <jsp:setProperty name="tri" property="*"/>
                三角形的三边分别是:
                <jsp:getProperty name="tri" property="a"/>,
                <jsp:getProperty name="tri" property="b"/>,
                <jsp:getProperty name="tri" property="c"/>.
            <br>
            <b>
                这三边可以构成一个三角形吗?
                <jsp:getProperty name="tri" property="t"/>
                <br>
                该三角形的面积为:
                <jsp:getProperty name="tri" property="s"/>
            </b>
        </font>
    </body>
</html>

运行之后的页面显示如下:
在这里插入图片描述
输入一组数据之后,点击“确认”按钮,页面显示如下:
在这里插入图片描述
————————————————————————————————————————————————————
因为作业任务繁重,所以中断了几天没有更新。

2020.7.17 【Day27】

今天学习JSP中关于Servlet的知识。

写一个创建Servlet的类就是写javax.servlet.http.HttpServlet类的子类。HttpServlet类可以实现Servlet接口,其可以响应用户的方法,HttpServelt类 的子类被称为Servlet类,Servlet类的对象称为servlet。

为了让服务器能够使用字节码创建一个servlet,我们必须将字节码文件保存到某个Web服务器目录中特定的子目录中。保存成功后,还必须在服务器中编写一个部署文件,否则服务器无法创建对象。

所谓的部署文件,就是一个XML文件,其由服务器进行管理。XML文件是由标记组成的文件,编写的web.xml文件需要保存到Web服务目录的WEB-INF子目录中。

servlet由服务器负责创建,我们只需要为服务器准备好Servlet的字节码文件,并编写好相应的配置文件web.xml,用户就可以根据部署文件来请求服务器创建并运行一个servlet。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jeron Zhou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值