注释:<%-- 注释 --%>
JSP中一共有3种Scriptlet代码。支持与HTML的代码混编。
第一种:<%%> 定义局部变量,编写语句。
第二种:<%!%> 全局变量,方法,类
第三种:<%=%> 表达式输出一个变量或者一个具体的常量
<jsp:scriptlet></jsp:scriptlet>标签与使用<%%>的效果是一样的。
page指令:可以定义一个JSP页面的相关属性,包括设置MIME类型,定义需要导入的包,错误页的指定等。
page指令语法 <%@page 属性=“内容”%>
page指令包含属性,比较常用的是contentType,pageEncoding,errorPage/isErrorPage和import这4个属性所代表的page指令。
设置contentType设置MIME(Multipurpose Internet Mail Extensions,多功能Internet右键扩充服务)编码
<%@page language="java" contentType="text/html;charset=GBK"%> //默认的charset是utf-8
以上设置表示页面是按照HTML文本文件(text.html)进行显示,页面的编码(charset)是GBK。
<%@page language="java" contentType="application/msword;charset=GBK"%> //将该页面显示为一个word文档,
设置文件编码
<%@page language="java" contentType="text/html;" pageEncoding="GBK"%>
pageEncoding指的是JSP文件本身的编码,而contentType中的charset指的是服务器发送给客户端的内容编码。
在JSP中,如果pageEncoding存在,那么JSP的编码将由apgeEncoding决定,否则将由contentType中的charset属性决定;如果两者都不存在,则将使用ISO-8859-1的编码方式。
错误页的设置
<%@ page errorPage="error.jsp"%> <%-- 一旦出现错误将跳转到error.jsp中 --%>
<%@ page isErrorPage="true"%> <%-- 表示此页可以处理错误 --%>
注:错误页的跳转属于服务端跳转。也可在Tomcat的web.xml配置文件中直接配置错误的跳转页面。
在page指令中可以使用import导入所需要的Java开发包,如导入java.sql包后,即可进行数据库的开发操作。
<%@ page import="java.sql.*"%>
包含指令
1)静态包含:包含的文件可以是JSP文件,HTML文件,文本文件,或是一段Java程序。
<%@include file="info.html"%>
2)动态包含:<jsp:include page="info.jsp"/>,若要对被包含的页面传入参数,可以这样:
<jsp:include page="receive_param.jsp">
<jsp:param name="name" value="<%=username%>">
<jsp:param name="info" value="www.cnblogs.com">
</jsp:include>
静态包含属于先包含后处理,而动态包含属于先处理后包含。
跳转指令<jsp:forward>,将一个用户的请求(rquest)从一个页面传递到另外一个页面,即完成跳转操作。
<jsp:forward page="forward_demo.jsp"/>
如果要传入参数,则可以:
<jsp:forward page="forward_demo.jsp">
<jsp:param name="name" value="<%=username%>">
<jsp:param name="info" value="www.cnblogs.com">
</jsp:forward>
在接收参数页,可以使用request.getParameter("name")来接收参数。
JSP中的9个内置对象
NO. | 内 置 对 象 | 类 型 | 描 述 |
1 | pageContext | javax.sevlet.PageContext | JSP页面的容器 |
2 | request | javax.sevlet.http.HttpServletRequest | 得到用户的请求信息 |
3 | response | javax.sevlet.http.HttpServletResponse | 服务器向客户端的回应信息 |
4 | session | javax.sevlet.http.http.HttpSession | 用来保存每一个用户的信息 |
5 | application | javax.sevlet.http.ServletContext | 表示所有用户的共享信息 |
6 | config | javax.sevlet.http.ServletConfig | 服务器配置,可以取得初始化参数 |
7 | out | javax.sevlet.http.JspWriter | 页面输出 |
8 | page | java.lang.Object | 表示从页面中表示出来的一个Servlet实例 |
9 | exception | java.lang.Throwable | 表示JSP页面所发生的异常,在错误页中才起作用 |
标红的5个对象是比较常用的对象。
out.println()方法直接输出信息在页面;System.out.println()方法输出信息到控制台。
属性范围
在JSP中提供了4种属性范围的保存范围。所谓属性的保存范围,指的就是一个内置的对象,可以在多少个页面中保存并继续使用。
page: 只在一个页面中保存属性,跳转之后无效。
request: 只在一次请求中保存属性,服务器跳转后依然有效。
session: 在一次会话范围中保存,无论何种跳转都可以使用,但是新开浏览器无法使用。
application: 在整个服务器上保存,所有用户都可以使用。
page属性范围:使用PageContext表示,但是一般都习惯于将这种范围称为page范围,表示讲一个属性设置在本页上,跳转之后无法取得。
pageContext.setAttribute("name","lily");
pageContext.setAttribute("birthday",new Date());
String username = (String)pageContext.getAttribute("name");
Date userbirthday = (Date)pageContext.getAttribute("birthday");
request属性范围:request属性范围表示在服务器跳转后,所有设置的内容依然会被保留下来。
request.setAttribute("name","lily");
request.setAttribute("birthday",new Date());
String username = (String)request.getAttribute("name");
Date userbirthday = (Date)request.getAttribute("birthday");
注意:要把request.getAttribute()与request.getParameter()区分开来。后者支持客户端跳转,而前者只支持服务端跳转。对于前者而言,可以这么理解:
request表示客户端的请求。正常情况下,一次请求服务器只会给予一次回应,那么这时如果是服务器端跳转,请求的地址栏没有改变,所以也就相当于回应了一次;而如果地址栏改变了,就相当于是发出了第二次请求,则第一次请求的内容肯定就已经消失了,所以无法取得。
session属性范围
如果希望一个属性在设置后,可以在任何一个与设置页面相关的页面中取得,则可以使用session属性范围。使用session设置属性后,不管是客户端跳转还是服务器端跳转,只要属性设置了就都可以取得。
session.setAttribute("name","lily");
session.setAttribute("birthday",new Date());
String username = (String)session.getAttribute("name");
Date userbirthday = (Date)session.getAttribute("birthday");
application属性范围
如果希望设置一个属性,可以让所有用户(每一个session)看得见,则可以将属性范围设置成application,这样属性即可保存在服务器上。
application.setAttribute("name","lily");
application.setAttribute("birthday",new Date());
String username = (String)application.getAttribute("name");
Date userbirthday = (Date)application.getAttribute("birthday");
以上程序无论打开多少个浏览器都可以访问到,但是如果服务器重新启动,则之前所设置的全部属性将消失。
深入研究page属性范围
public void setAttribute(String name, Object value, int scope) 设置属性并指定保存范围
四种属性范围:
public static final int PAGE_SCOPE 表示page属性范围,默认
public static final int REQUEST_SCOPE 表示page属性范围
public static final int SESSION_SCOPE 表示page属性范围
public static final int APPLICATION_SCOPE 表示page属性范围
pageContext.setAttribute("name","lily", PageContext.REQUEST_SCOPE);
pageContext.setAttribute("birthday",new Date(), PageContext.REQUEST_SCOPE);
request对象是使用最多的一个对象,其主要作用是接收客户端发送而来的请求信息,如请求的参数,发送的头信息等。request是javax.servelet.http.Http.SeveletRequest接口(public interface HttpSevletRequest extends SevletRequest)的实例化对象,表此对象主要应用在HTTP协议上。
request.setCharacterEncoding("UTF-8")方法设置一个统一的编码格式(UTF-8)。
request.getParameter()方法可以接收一个表单的文本框中输入的内容,而接收一组参数要用request.getParamaterValues()。二者都是针对表单中的name属性作为接收参数,且可以同时接收文本框和隐藏域的内容。
接收头信息:
Enumeration enu = request.getHeaderNames();
while(enu.hasMoreElements()){
String headername = (String)enu.nextElement();
String headerValue = request.getHeader(headerName);
}
因为没有指定泛型,所以nextElement()每次的返回结果都是Object,需要进行向下转型操作。
当服务器端需要得到请求客户端的相关信息时就会使用request对象完成。
String method = request.getMethod(); //GET 取得提交方式
String ip = request.getRemoteAddr(); //127.0.0.1 取得客户端的IP地址
String path = request.getServeletPath(); //aa/bb/cc/hello.jsp 取得访问路径
String contextPath = request.getContextPath(); //test 取得上下文资源名称
response对象的主要作用是对客户端的请求进行回应,将Web服务器处理后的结果发回给客户端。response对象属于javax.sevlet.http.HttpSevletResponse接口(public interface HttpServletResponse extends ServletResponse)的实例。
定时刷新功能的实现方式:
response.setHeader("refresh","2"); //设置两秒一刷新
response.setHeader("refresh","3;URL=hello.html"); //3秒后跳转到hello.html
response.setHeader(“refresh”,...)属于客户端跳转,地址栏同样会发生改变。
实际上设置头信息的做法,在HTML中也可以直接使用。以上的跳转指令等同于以下的HTML代码:
<META HTTP-EQUIV="refresh" CONTENT="3;URL=hello.html">
如果一个请求的页面是动态页,则肯定要经过Web Container进行代码的拼凑操作;而如果是静态请求,则直接读取文件系统。所以,只有一个页面中没有JSP代码而又想执行定时跳转时才使用HTML形式设置跳转头信息的操作。
<jsp:forward>是无条件跳转的,只要执行到此语句,则后面的代码都不再执行;而response.sendRedirect()则不然,即便跳转,也会在跳转之前把后续的语句执行一遍。
也就是说,如果是服务器端跳转,则执行到跳转语句时会立刻进行跳转;如果使用的是客户端跳转,则是在整个页面执行完之后才执行跳转。
response跳转属于客户端跳转,使用response.sendRedirect()跳转之后,地址栏的页面地址改变了,所以此种跳转与之前设置的头信息的跳转一样,都属于客户端跳转。
一定要在使用<jsp:forward>语句执行之前关闭数据库连接,否则数据库连接将再也无法关闭。直到“数据库连接已经达到最大异常”,此次就只能重新启动服务器了。
使用<jsp:forward>可以通过<jsp:param>方便的进行参数的传递;如果使用了response.sendRedirect()传递参数,则只能通过地址重写的方式完成参数传递。
使用Cookie保存信息可以减少客户端的部分操作,Cookie是javax.sevlet.http.Cookie类。
通过头信息设置Cookie:
response.setHeader("Set-Cookie","cookie_name=cookie_value");
向客户端增加Cookie:
Cookie c1 = new Cookie("first_cookie","first_cookie_value");
c1.setMaxAge(100);//有效时间100秒
response.addCookie(c1);//如果不设置有效时间,则关闭浏览器Cookie自动销毁
JSESSIONID的来源
在每一个客户端访问服务器时,服务器为了明确区分每一个客户端,都会自动设置一个JSESSIONID的Cookie,表示用户的唯一身份识别。注意,默认的属性和过期时间是session,也就是说,关闭浏览器之后,当前的Cookie中的JSESSIONID便会销毁,下次重新打开浏览器访问服务器时,会重新分配一个新的JSESSIONID。
获取全部Cookie
Cookie c[] = request.getCookies();
获取Cookie的名称和值
c[i].getName() c[i].getValue()
session对象
session对象是javax.servlet.http.HttpSession接口的实例化对象,所以session只能用在HTTP协议中。每一个session对象都表示不同的访问用户。
String id = session.getId(); // 取得Session Id
id.length()
session.invalidate(); //销毁所有SESSION_ID
session.isNew(); //判断一个用户是否是第一次访问页面。isNew()是通过Cookie的方式进行判断 的
long start = session.getCreationTime(); // 取得创建时间
long end = session.getLastAccessedTime(); //取得最后一次操作时间
long time = (end - start) / 1000; //取得操作的秒
application对象
application对象是javax.servlet.ServletContext接口的实例化对象
String path = application.getRealPath("/"); //得到虚拟目录对应的绝对路径
等价于:String path = this.getServletContext().getRealPath("/") ;
Enumeration enu = this.getServletContext().getAttributeNames() ; // 取得全部的属性
public String getContextPath(); //取得当前的虚拟路径名称
config对象
是javax.servlet.ServletConfig接口的实例化对象,主要的功能是取得一些初始化的配置信息(web.xml中的信息)。
String dbDriver = config.getInitParameter("driver") ;
String dbUrl = config.getInitParameter("url") ;
out对象
是javax.servlet.jsp.JspWriter类的实例化对象,主要功能就是完成页面的输出操作,使用println()或print()方法输出信息,但是从实际的开发来看,直接使用out对象的几率较小,一般使用表达式完成输出的操作。
int buffer = out.getBufferSize() ; //缓冲区大小
int avaliable = out.getRemaining() ; //可用的缓冲区大小
int use = buffer - avaliable ; //使用中的缓冲区大小
pageContext对象
是javax.servlet.jsp.PageContext类的实例,主要表示一个JSP页面的上下文
pageContext.forward("pagecontext_forward_demo02.jsp?info=info_value") ;
String info = pageContext.getRequest().getParameter("info") ; // 直接从pageContext对象中取得了request 最终获取参数值info_value
<h3>realpath = <%=pageContext.getServletContext().getRealPath("/")%></h3>
JavaBean
Web开发的标准目录结构
WEB ROOT:web的根目录,web.xml中的虚拟目录指向该目录
WEB-INF:Web目录中最安全的文件夹,保存各种类,第三方jar包,配置文件等
web,xml:Web的部署描述符
classes:保存所有的JavaBean
lib:保存所有第三方jar文件
tags:保存所有的标签文件
jsp:存放*.jsp文件,一般根据功能再建立子文件夹
js:存放*.js文件
css:样式文件
images:存放图片
<jsp:useBean>标签定义一个JavaBean
导入cn.mldn.lxh.demo包
<%@ page import="cn.mldn.lxh.demo.*"%>
<jsp:useBean id="simple" scope="page" class="cn.mldn.lxh.demo.SimpleBean"/>
以上id代表实例化对象名称,这里利用了反射机制自动完成了实例化,class表示对象所对应的包.类名称。scope表示对象的保存范围,一共有page,request,session和application4种属性范围
<jsp:setProperty>标签为JavaBean中的属性设置内容
<jsp:useBean id="simple" scope="page" class="cn.mldn.lxh.demo.SimpleBean"/>
<jsp:setProperty name="simple" property="*"/>
其中包含两个属性:name,对应着<jsp:useBean>中声明的id属性,表示使用指定的 JavaBean。property,表示要操作的属性,"*"表示自动匹配。
相当于:
<%
SimpleBean simple = new SimpleBean();
simple.setName(request.getParameter("name"))
simple.setAge(Integer.parseInt(request.getParameter("age")))
%>
<jsp:getProperty>取得属性,此标签会自动调用JavaBean的getter()方法
<h3>姓名:<jsp:getProperty name="simple" property="name"/></h3>
<h3>年龄:<jsp:getProperty name="simple" property="age"/></h3>
<jsp:getProperty>相当于:
<%simple.getName()%>
<%simple.getAge()%>
JavaBean的保存范围
<jsp:useBean>指令上存在一个scope属性,表示一个JavaBean的保存范围。保存的范围一共有以下4钟:
page:保存在一页的范围中,跳转后此JavaBean无效。
request:一个JavaBean对象可以保存在一次服务器跳转的范围中。
session:在一个用户的操作范围中保存,重新打开浏览器时才会声明新的JavaBean。
application:在整个服务器上保存,服务器关闭时才会消失。
JavaBean的删除
删除page范围的JavaBean可以使用pageContext.removeAttribute(JavaBean名称);
删除request范围的JavaBean可以使用request.removeAttribute(JavaBean名称);
删除session范围的JavaBean可以使用session.removeAttribute(JavaBean名称);
删除application范围的JavaBean可以使用application.removeAttribute(JavaBean名称);
<% session.removeAttribute("cou"); %>
request.getRemoteAddr() 获取的值为0:0:0:0:0:0:0:1的解决办法:本机访问的时候用127.0.0.1或本机ip代替localhost即可解(在浏览器中输入127.0.0.1/test)