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指令见都没见过,不说啦~
- J2EE学习笔记(一)之JSP原理详解
- J2EE学习笔记一之JSP
- J2EE学习笔记之JSP内置对象
- J2EE学习笔记(四)之Servlet原理
- J2EE学习笔记(六)之Spring原理
- J2EE:JSP 学习笔记
- J2EE之JSP学习
- J2EE 学习笔记 一
- J2EE学习笔记之JSP常用三个指令元素
- J2EE学习笔记之常用JSP动作元素
- J2EE学习(JSP的工作原理)
- [WebWork]学习笔记之(一) - [Java/J2EE]
- Servlet笔记一之J2EE基本学习路线
- J2EE系列之Hibernate4学习笔记(一)--Hibernate简介
- J2EE系列之Spring4学习笔记(一)--Spring介绍
- J2EE系列之SpringMVC学习笔记(一)--SpringMVC简介
- J2EE系列之MyBatis学习笔记(一)-- 简介
- JAVAWeb之JSP学习笔记一
- 多校联合赛第一场 Balala Power
- opencv3.0+VS2015+64位win7配置
- Spring注入集合值
- 编写可维护的javascript(五):UI层的松耦合
- 最简单的IOS
- J2EE学习笔记(一)之JSP原理详解
- 有趣的树
- Anaconda使用总结(转载)
- Android使用Minio对象存储服务API
- c语言for循环变量i,i的定义位置不同会导致错误
- hadoop源码解析一之hadoop jmx 监控
- python中的urlencode与urldecode
- angularJS中cookies的使用
- Android_Web的目录结构