J2EE学习笔记(一)之JSP原理详解

来源:互联网 发布:js 更改表单action 编辑:程序博客网 时间:2024/06/05 10:39

一、构建Web应用

(一)“徒手”建立一个空的Web应用

1.任意选取一个目录,新建项目文件夹

这里写图片描述

2.在上述文件夹中新建WEB-INF文件夹

这里写图片描述

3.从tomcat的应用中随便复制一个web.xml到刚才新建的WEB-INF文件夹中

这里写图片描述

这里写图片描述

4.打开复制过来的web.xml并将其修改成只有一个根元素的xml文件。

这里写图片描述

5.在上述所建的WEB-INF文件夹下新建两个文件夹,classes和lib。

这两个文件夹的作用完全相同,都是用于保存Web应用所需要的Java类文件,区别是classes保存单个*.class文件;lib保存打包后的JAR文件。

6.新建一个简单的jsp文件。

这里写图片描述

<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %><html><head>     <title>Helloworld</title></head><body>     This is a test.</body></html>

经过上述步骤,就建立了一个Web应用。将该应用复制到Tomcat的webapps路径下,就会自动部署到Tomcat中。

双击startup.bat,启动Tomcat
http://localhost:8080/20170710_webDemo/a.jsp
浏览器访问上述地址
这里写图片描述
访问成功。

(二)配置描述符web.xml

这里写图片描述

1.web.xml的根元素是

<web-app></web-app>

2.metadata-complete

该属性有true跟false两个值。
为true时,该Web应用不会自动加载Annotation配置的Web组件(如Servlet、Filter、Listener等)。

3.welcome-file-list

用来配置首页。

<welcome-file-list>  <welcome-file>a.html</welcome-file>  <welcome-file>a.htm</welcome-file>  <welcome-file>a.jsp</welcome-file></welcome-file-list>

就是先找a.html充当首页,如果没有a.html就找a.htm,以此类推。

二、JSP基本原理


1.JSP的本质是Servlet。

每个JSP页面就是一个Servlet实例,JSP页面由系统编译成Servlet,Servlet再负责响应用户请求。

JSP实际上是一种简化的Servlet,使用JSP其实还是使用的Servlet,因为Web应用中的每个JSP页面都会由Servlet容器生成对应的Servlet。

Servlet跟JSP是完全统一的,二者在底层的运行原理是完全一样的。
JSP必须被WEB服务器编译成Servlet提供HTTP服务的是Servlet。JSP可以视为一个“草稿”文件,WEB服务器根据其生成servlet,真正提供HTTP服务的是Servlet。
所以广义的servlet包括JSP和Servlet。

那既然是一样的,为什么要有这两种东西呢?
当用户向指定的Servlet发送请求的时候,Servlet利用输出流动态的生成HTML页面,包括每一个静态的HTML标签和所有在HTML页面中出现的内容。复杂的内容降低了Servlet的开发效率。
而JSP是一种动态页面技术,主要目的就是将表示逻辑从Servlet中分离出来。
它实现了HTML页面的Java扩展(<%…%>),封装了产生动态网页的处理逻辑。

2.JSP的结构

静态部分:标准的HTML标签、静态的页面内容,与静态的HTML页面相同。
动态部分:受Java程序控制的内容,由Java程序动态产生。

3.举个栗子

<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %><html><head>     <title>Helloworld</title></head><body>     This is a test.     现在时间是:     <%out.println(new java.util.Date());%></body></html>

这里写图片描述

打开了这个页面后
tomcat的这个路径\work\Catalina\localhost\20170710_webDemo\org\apache\jsp下

这里写图片描述

就会发现tomcat根据JSP页面生成了对应Servlet的Java文件和class文件。
这里写图片描述

三、JSP注释


JSP注释不会输出到客户端。

(1)JSP注释

(2)HTML注释

<!--注释内容-->
<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %><html><head>     <title>Helloworld</title></head><body><!--HTML注释--><%--JSP注释--%>     This is a test.     现在时间是:     <%out.println(new java.util.Date());%></body></html>

这里写图片描述

页面上只能看到HTML注释,不能显示JSP注释。

四、JSP声明


<%!–声明部分–%>
用于声明变量跟方法

<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %><html><head>     <title>Helloworld</title></head><!--JSP声明定义变量和方法--><%!public int count = 0;public String info(){    return "hello";}%><body><%out.println(count++);%><%out.println(++count);%><%=count++%><%=++count%></body></html>

注意这里的声明是写在标签外面的,写在里面就不对,可执行的Java代码是写在标签里面的。
这里输出结果是0 2 2 4.

然后我们可以再到D:\java\save\apache-tomcat-8.0.24\work\Catalina\localhost\20170710_webDemo\org\apache\jsp这个目录下看看刚才生成的Servlet对应的Java文件

这里写图片描述

这里写图片描述

五、JSP执行数据库查询


<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %><%@ page import="java.sql.*"%><html><head>     <title>Helloworld</title></head><body><%    Class.forName("oracle.jdbc.driver.OracleDriver");    Connection conn = DriverManager.getConnection(        "", "", "");    Statement statm = conn.createStatement();    ResultSet rs = statm.executeQuery("select * from test_student");%><table>    <%        while(rs.next()){        %>    <tr>        <td><%=rs.getString(1)%></td>        <td><%=rs.getString(2)%></td>        <td><%=rs.getString(3)%></td>    </tr>    <%}%></table></body></html>

在这里出现了一个小错误,报错Connection cannot be resolved to a type
这个是因为开始忘记在JSP中导入数据库包了,就是在tomcat的lib目录下加一个oracle的jar包,再在jsp文件的开头加上这一句话
<%@ page import=”java.sql.*”%>就好啦。

六、JSP的3个编译指令


编译指令是通知JSP引擎的消息,是有默认值的,无需为每个设定值。

(1)page指令

上面已经用过啦。
page指令通常位于页面顶端,一个JSP页面可以有多个page指令。
这里就说一下errorPage这个属性,它的实质是JSP的异常处理机制,在运行中出现异常的话,系统将自动跳转到errorPage指定的页面,如果不指定,就会在客户端浏览器上直接显示错误信息,以前我就做过这样的蠢事情,这样是不好的。
那用法就是这样啦。

<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="error.jsp" %>

(2)include:用于指定包含另一个页面

(3)taglib:用于定义和访问自定义标签

七、JSP的7个动作指令


动作指令跟编译指令的区别
编译指令是通知Servlet引擎的处理消息;
动作指令只是运行时的动作。
编译指令在JSP编译成Servlet时起作用,处理指令通常可替换成JSP脚本,只是JSP脚本的标准化写法。

1.forward指令

用于将页面响应转发到另外的页面
举个栗子

<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %><html><head>     <title>jsp_forward原始页</title></head><body><jsp:forward page="20170726_jsp_forward_res.jsp">     <jsp:param name="age" value="18"></jsp:param></jsp:forward></body></html>

结果页

    <%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>        <html>        <head>        <title>jsp_forward结果页</title>        </head>        <body>            <%=request.getParameter("age")%>        </body>        </html>

结果页面直接显示18
但是地址栏还是http://localhost:8080/20170710_webDemo/20170726_jsp_forward.jsp没有改变。
从这里可以看出执行forward指令转发请求时,客户端的请求参数不会丢失。

    <%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>        <html>        <head>        <title>jsp_forward表单提交</title>        </head>        <body>        <form id="login" method="post" action="20170726_jsp_forward.jsp">            <input type="text" name="username">            <input type="submit" value="login">        </form>        </body>        </html>

刚才那个结果页文件里加一句话啦。

<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>        <html>        <head>        <title>jsp_forward结果页</title>        </head>        <body>            <%=request.getParameter("age")%>            <%=request.getParameter("username")%>        </body>        </html>

这里写图片描述

这里写图片描述

2.include指令

include指令只会将被导入页面的body内容插入到本页面。
它跟forward指令十分相似,下面用一个简单的栗子来对比一下

  <%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>        <html>        <head>        <title>jsp_include原始页</title>        </head>        <body>        <jsp:include page="20170726_jsp_forward_res.jsp">            <jsp:param name="age" value="18"></jsp:param>        </jsp:include>        </body>        </html>

注:20170726_jsp_forward_res.jsp中注释掉

<%=request.getParameter("username")%>

这句话

结果跟刚才的forward一样,都是18
现在我们来对比一下两个指令的Servlet代码,到tomcat的这个目录下
\work\Catalina\localhost\20170710_webDemo\org\apache\jsp

这里写图片描述

这里写图片描述
可以发现一个是用forward()方法来引入目标页面,另一个则是通过include()方法来引入,区别在于,执行forward时,目标页面将完全代替原有页面,执行include时,目标页面只是插入了原有的页面。

3.useBean、setProperty、getProperty指令

这三个指令都跟JavaBean有关
其中,useBean用于在jsp页面中初始化一个Java实例;
setProperty用于为JavaBean实例设置属性值;
getProperty用于输出JavaBean实例的属性值。

如果我们有很多的jsp页面都需要使用重复的某段代码,就可以将其写成Java代码来调用该方法。

又要来举一个小栗子啦。
Person类

package com.yolanda.fun.temp;public class Person {    private String name;    private int age;    public Person(String name, int age) {        this.name = name;        this.age = age;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }}

上面的是一个Person.java文件,但是Web应用对它是不起作用的,所以我在外面用sts编译了一下这个文件,将得到的二进制文件Person.class放入WEB-INF\classes路径下。
好哒,接下来就来写jsp啦。

    <%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="" %>        <html>        <head>        <title>jsp三个JavaBean相关指令</title>        </head>        <body>            <jsp:useBean id="p1" class="com.yolanda.fun.temp.Person" scope="page"></jsp:useBean>            <jsp:setProperty name="p1" property="name" value="Anna"></jsp:setProperty>            <jsp:setProperty name="p1" property="age" value="12"></jsp:setProperty>            <jsp:getProperty name="p1" property="name"></jsp:getProperty>            <jsp:getProperty name="p1" property="age"></jsp:getProperty>        </body>        </html>

这里的scope属性用于指定JavaBean实例的作用范围,里面的参数有四个
page:该JavaBean实例仅在该页面有效;
request:该JavaBean实例在本次请求有效;
session:该JavaBean实例在本次session有效;
application:该JavaBean实例在本应用内一直有效。

在这里要注意几点,

第一,我在源文件里用了包名,所以在jsp中也要写,不然就会报500的错误;
第二,包名写对了还是出现了
The value for the useBean class attribute com.yolanda.fun.temp.Person is invalid.这个错误
这是为什么呢?
因为没有找到这个类,如果本来有包名的话,在WEB-INF\classes路径下也要建个一样的目录出来,也就是说这个文件要放在\WEB-INF\classes\com\yolanda\fun\temp目录下,就好啦

这里写图片描述

有的坑真的是不踩都想象不出来~

4.plugin指令和param指令

param前面都用过啦,单独的param指令没有实际意义,跟jsp:include、jsp:forward还有jsp:plugin结合使用。
plugin指令见都没见过,不说啦~