目录
前言
HTTP通信协议是用户与服务器之间一种提交(请求)信息与响应信息(request/response)的通信协议。在JSP中,内置对象request封装了用户提交的信息,那么该对象调用相应的方法可以获取封装的信息,即使用该对象可以获取用户提交的信息。 内置对象request对象是实现了ServletRequest接口类的一个实例,可以在Tomcat服务器的webapps\tomcat-docs\servletapi中查找ServletRequest接口的方法
4.1request对象
4.1.1 获取用户提交的信息
用户通常使用HTML的form表单:
<form action= "请求访问的页面或Servlet" method= get | post > 提交手段 </form>
例如:
<form action="tom.jsp" method= "post" >
<input type="text" name="boy" value= "ok" />
<input type="submit" name="submit" value="提交"/>
</form>
请求服务器上的资源并提交信息
request对象获取用户提交信息的最常用的方法是getParameter(String s)
例子4_2中,example4_2.jsp通过表单向当前页面提交购物小票,当前页面自己负责计算购物小票的价格总和。
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<%@ page import="java.util.regex.Pattern" %>
<%@ page import="java.util.regex.Matcher" %>
<style>
#tom{
font-family:宋体;font-size:22;color:blue
}
</style>
<HTML><body id ="tom" bgcolor = #ffccff>
输入购物小票内容(显示的是默认内容):
<%
String content = "牛奶:12.68元,面包:6.6元,"
+"苹果:28元,香皂:6.58元";
%>
<form action ="" method="post" id ="tom">
<textArea name="shopping" rows=5 cols=32 id ="tom">
<%= content %>
</textArea>
<input type="submit" id ="tom" name="submit" value="提交"/>
</form>
<% String shoppingReceipt=request.getParameter("shopping");
if(shoppingReceipt==null) {
shoppingReceipt="0";
}
Pattern pattern; //模式对象
Matcher matcher; //匹配对象
String regex="-?[0-9][0-9]*[.]?[0-9]*" ;//匹配数字,整数或浮点数的正则表达式。
pattern = Pattern.compile(regex); //初试化模式对象。
matcher =
pattern.matcher(shoppingReceipt); //matcher检索shoppingReceipt。
double sum = 0;
while(matcher.find()) {
String str = matcher.group();
sum += Double.parseDouble(str);
}
out.print("购物小票消费总额:"+sum);
%>
</body></HTML>
注意:使用request对象获取当前页面提交的信息时要格外小心,在上面的例子4_2中,当用户在浏览器中输入页面地址请求页面时,用户还没有机会提交数据,那么页面在执行 String shoppingReceipt=request.getParameter("shopping"); 时得到的shoppingReceipt就是空对象。如果程序使用了空对象,Java解释器就会提示出现了NullPointerException异常。因此,在上述例子2中为了避免在运行时出现NullPointerException异常,使用了如下代码:
String shoppingReceipt=request.getParameter("shopping");
if(shoppingReceipt==null) {
shoppingReceipt="0";
}
4.1.2 处理汉字信息
用户提交的信息中如果含有汉字字符或其他非ASCII字符的信息,就必须进行特殊的处理方式,防止出乱码现象。
JSP页面文件的编码为utf-8编码。 内置对象request在获取信息之前调用setCharacterEncoding方法设置编码为utf-8(默认是iso-8859-1)就可以避免乱码现象
代码如下:
request.setCharacterEncoding("utf-8");
4.1.3 常用方法举例
request的getParameter方法获取form表单提交的有关信息,但实际上,request对象调用相关方法可以获取请求的许多细节信息。内置对象request常用方法如下:
1) String getProtocol() 获取用户向服务器提交信息所使用的通信协议,比如http/1.1等。
2) String getServletPath() 获取用户请求的JSP页面文的名字(带目录符号\,例如\hello.jsp)。
3) String getContextPath() 获取用户请求的当前Web服务目录(例如ch4)。
4) int getContentLength() 获取用户提交的整个信息的长度。
5) String getMethod() 获取用户提交信息的方式,比如:post或get.
6) String getRemoteAddr() 获取用户的IP地址。
7) String getRemoteHost() 获取用户机的名称(如果获取不到,就获取IP地址)。
8) String getServerName() 获取服务器的名称。
9) String getServerPort() 获取服务器的端口号。
例:
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<HTML><body bgcolor = #ffccff>
<p style="font-family:宋体;font-size:36;color:blue">
<% request.setCharacterEncoding("utf-8");
String jsp=request.getServletPath(); //请求的JSP页面
jsp = jsp.substring(1); //去掉JSP页面名称前面的目录符号/
String webDir = request.getContextPath();//获取当前Web服务目录的名称
webDir = webDir.substring(1); //去掉Web服务目录的名称前面的目录符号/
String clientIP=request.getRemoteAddr();//用户的IP地址
int serverPort=request.getServerPort(); // 服务器的端口号
out.print("<br>shenme:"+request.getServerName());
%>
用户请求的页面:<%= jsp %>
<br>Web服务目录的名字:<%= webDir %>
<br>用户的IP地址:<%= clientIP %>
<br>服务器的端口号:<%= serverPort %>
</p></body></HTML>
4.1.4 处理HTML标记(不区分大小写)
1.form 标记(form表单)
<form action= "请求访问的页面或servlet" method = get | post > 各种提交手段 提交键 </form>
例如:
<form action="tom.jsp" method="post" >
<input type="text" name="boy" value= "ok" />
<input type="submit" name="submit" value="提交"/>
</form>
form表单标记经常将下列标记作为form表单的子标记,以便提供提交数据的手段,这些标记都以GUI形式出现,方便用户输入或选择数据,比如,文本框、下拉列表、滚动列表等。
input …../> <select … ></select> <option …..> </option> <textArea ….> </textArea>
2.input标记
<input type="GUI对象" name= "GUI对象的名子" value="GUI中的默认值"/>
Tom服务器的内置对象request通过name指定的名字来获取GUI对象中提交的数据.
(1)文本框
text <input type="text" name="m" value="h" size="8" algin="left" maxlength="9"/>
如果用户没有在text输入任何信息,就单击form表单中的submit提交键,request对象调用getParameter方法将获取由value指定的默认值(text中显示的默认值),如果value未指定任何值,getParameter方法获取的字符串的长度为0,即该字符串为""。
2)单选框radio
<input type="radio" name="hi" value="男" algin= "top" checked="ok" />男生
<input type="radio" name="hi" value="女" algin= "top" />女生
其中value指定radio的值,如果几个单选键的name取值相同,那么同一时刻只能有一个被选中。 request对象调用getParameter方法获取被选中的radio中value属性指定的值。
checked如果取值是一个非空的字符串,那么该单选框的初始状态就是选中状态。
<input type="radio" name="R" value="on" />打开
<input type="radio" name="R" value="off" checked="default">关闭
(3)复选框checkbox
<input type="checkbox" name= "item" value="A" algin= "top" checked="ok" />足球
<input type="checkbox" name= "item" value="B" algin= "top" />围棋
<input type="checkbox" name= "item" value="C" algin= "top" checked="ok" />乒乓球
<input type="checkbox" name= "item" value="D" algin= "top" />篮球
其中value指定checkbox的值。复选框与单选框的区别就是可以多选,即如果几个checkbox的name取值相同,那么同一时刻可有多个chekbox被选中。这时,request对象需调用getParameterValues方法(不是getParameter方法)获取被选中的多个checkbox中value属性指定的值。checked如果取值是一个非空的字符串,那么该复选框的初始状态就是选中状态。
(4)口令框password
<input type= "password" name= "me" size= "12" maxlength="30" />
用户在口令框中输入tiger,单击提交键,tiger将被提交给form表单请求的页面,请求的页面的内置对象request调用getParameter方法获取password提交的值tiger(password仅仅起着不让别人偷看的作用,不提供加密措施)。
(5)隐藏hidden
<input type= "hidden" name="nogui" value= "hello" />
用户单击form表单中的submit提交键,那么form表单所请求的页面的内置对象request调用getParameter方法将获取由value指定的值hello。
6)提交键submit 为了能把form表单的数据提交给服务器,一个form表单至少包含一个提交键(可以有多个提交键,见稍后的例子10),例如:
<input type= "submit" name="me" value="确定" size="12" />
单击提交键后,form表单请求的页面才有机会获取form表单提交的各个数据。
(7)重置键:reset 重置键将表单中输入的数据清空,以便重新输入数据,例如:
<input type="reset" value="重置"/>
3.select、option标记(下拉列表或滚动列表)
<select name="myName">
<option value="item1">文本描述</option>
<option value="item2">文本描述</option>
… …
</select>
例:
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<style>
#tom{
font-family:宋体;font-size:26;color:blue
}
</style>
<% String music = request.getParameter("music");
String pic = request.getParameter("pic");
String onOrOff=request.getParameter("R");
if(music==null) music = "";
if(pic==null) pic = "";
if(onOrOff==null) onOrOff = "off";
%>
<HTML><body id=tom background="image/<%= pic %>" >
<form action="" method=post >
<b>选择音乐:<br>
<select id=tom name="music" >
<Option selected value="back1.mp3">绿岛小夜曲
<Option value="back2.mp3">我是一片云</option>
<Option value="back3.mp3">红河谷</option>
</select>
<input type="radio" name="R" value="on" />打开
<input type="radio" name="R" value="off" />关闭
<br><b>选择背景图像:<br>
<select id=tom name="pic" size = 2>
<option value="back1.jpg">荷花图</option>
<option value="back2.jpg">玫瑰图</option>
<option value="back3.jpg">校园图</option>
</select> <br>
<input id=tom type="submit" name="submit" value="提交"/>
</form>
<% if(onOrOff.equals("on")) {
%> <br><embed src="sound/<%= music %>" height=50 />
<% }
%>
</body></HTML>
4.textArea标记
<textArea name="名字" rows= "文本可见行数" cols= "文本可见列数" > 提交或显示的数据 </textArea>
5.style样式标记
style标记可用于定义HTML其他标记中的字体样式,如,style标记给出样式:
<style>
#textStyle{
font-family:宋体;font-size:18;color:blue
}
#tom{
font-family:黑体;font-size:16;color:black
}
</style>
其中,#字符之后的字符序列是样式名称,例如#textStyle给出的样式名称是textStyle(起一个自己喜欢且容易理解的名字),其它html标记可以让其id属性值是样式名称来使用这个样式。例如,段落标记p就可以如下使用textStyle样式:
<p id = "textStyle">你好</p>
textArea标记如下使用tom样式:
<textArea name="english" id = "tom" rows=5 cols=38>大家好 </textArea>
input标记如下使用textStyle样式:
<input type="submit" name="submit" id = "textStyle" value="提交"/>
6.table标记(主要用于显示数据,不能提交数据)
<table border ="边框的宽度">
<tr width="该行的宽度">
<th width="单元格的宽度" >单元格中的数据
</th> …
<td width= "单元格的宽度" >单元格中的数据</td> …
</tr> … ….
</table>
7.<image>标记
不能用于提交数据,用于显示图像。 <image src="图像文件的URL" >描述文字</image>
8.embed标记
不能用于提交数据。使用embed标记可以播放音乐和视频,当浏览器执行该标记时,会把浏览器所在机器上的默认播放器嵌入到浏览器中,以便播放音乐或视频文件。
embed标记的基本格式为:
<embed src="音乐或视频文件的URL" >描述文字</embed > 或 <embed src="音乐或视频文件的URL" />
9. 属性值格式的说明
许多HTML标记的中都有属性,并指定属性的值,例如: <input type="text" name="testAmount" value=10 /> 中的type,name ,value都是input标记的属性, 属性值可以用双引号括起, 也可以用单引号括起, 或者不用任何符号. 比如type属性的值可以用双引号括起"text",也可以用单引号括起'text'或者不用任何符号text,一个好的习惯是用单引号括起。
4.1.5处理超链接
超链接标记 <a href=链接的页面地址 >文字说明</a> 是一个常用标记。例如:
<a href ="example4_9_receive.jsp>购买</a>
用户单击超链接标记的文字说明,可以访问超链接给出的链接页面。
使用超链接标记时还可以增加参数,以便向所链接的页面传递值,格式如下:
<a href=链接的页面地址?参数1=字符串1&参数2=字符串2… >文字说明</a> 例如: <a href ="example4_9_receive.jsp?id=A1001&price=8765">购买</a>
超链接所链接的页面,使用request调用getParameter("参数")获得超链接的参数传递过来的参数的值,即字符串。例如: String idStr = request.getParameter("id"); 需要注意的是,超链接标记向所链接的页面传递的参数的值,即字符串中不允许含有非ASCII字符(例如汉字等)。
4.2response对象
与request对象相对应的对象是response对象。可以用response对象对用户的请求作出动态响应,向用户端发送数据。
4.2.1 动态响应contentType属性
例:
<%@ page contentType="text/html" %>
<%@ page pageEncoding = "utf-8" %>
<%@ page import="java.awt.*" %>
<%@ page import="java.io.OutputStream" %>
<%@ page import="java.awt.image.BufferedImage" %>
<%@ page import="java.awt.geom.*" %>
<%@ page import="javax.imageio.ImageIO" %>
<style>#textStyle
{ font-family:宋体;font-size:36;color:blue
}
</style>
<%! void drawCircle(double r,HttpServletResponse response) { //定义绘制圆的方法
int width=320, height=300;
BufferedImage image =
new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
g.fillRect(0, 0, width, height);
Graphics2D g_2d=(Graphics2D)g;
Ellipse2D ellipse=new Ellipse2D.Double(160-r,150-r,2*r,2*r);
g_2d.setColor(Color.blue);
g_2d.draw(ellipse);
try {
OutputStream outClient= response.getOutputStream();//指向用户端的输出流
boolean boo =ImageIO.write(image,"jpeg",outClient);
}
catch(Exception exp){}
}
double getArea(double r) { //定义求面积的方法
return Math.PI*r*r;
}
%>
<% request.setCharacterEncoding("utf-8");
String submitValue = request.getParameter("submit");
String radius = request.getParameter("radius");
double r =Double.parseDouble(radius);
if(submitValue.equals("提交看圆形")){
response.setContentType("image/jpeg");//response更改相应用户的MIME类型
drawCircle(r,response) ; //绘制圆
}
%>
<HTML><body bgcolor = #EEEEFF>
<p id ="textStyle">
<%
double area=getArea(r);
String result = String.format("%.2f",area);
%>
半径:<%= radius %><br>
<b>面积(保留2位小数)<br><%= result %>
</p></body></HTML>
例子中用户在example4_10.jsp页面输入圆半径,然后单击名字“提交看面积”提交键,请求访问example4_10_show.jsp页面,该页面显示圆的面积。 但是,如果用户输入圆半径单击名字“提交看圆形”提交键,那么example4_10_show.jsp的内置对象response将默认的MIME类型text/html改变成image/jpeg,以便用户的浏览器启用相应的图形解码器显示服务器发来的图形。
4.2.2 response的HTTP文件头
response对象可以使用方法 addHeader(String head,String value); 或 setHeader(String head ,String value); 动态添加新的响应头和头的值,将这些头发送给用户的浏览器。如果添加的头已经存在,则先前的头被覆盖。
4.2.3 response重定向
response的sendRedirect(URL url)方法实现用户的重定向,即让用户从一个页面跳转到sendRedirect(URL: url)中url指定的页面。
■当使用sendRedirect(URL url)方法将用户从当前页面重定向另一个页面时,Tomcat服务器还是要把当前JSP页面执行完毕后才实施重定向(跳转)操作,但Tomcat服务器不再给用户看当前页面的执行效果。
■如果在执行sendRedirect(URL url)方法后,紧接着执行了return返回语句,那么Tomcat服务器会立刻结束当前JSP页面的执行。
4.3session对象
HTTP协议是一种无状态协议。一个用户向服务器发出请求(request),然后服务器返回响应(response),在服务器端不保留用户的有关信息,因此当下一次发出请求时,服务器无法判断这一次请求和以前的请求是否属于同一用户。
Tomcat服务器可以使用内置session对象(会话)记录用户的信息。内置对象session由Tomcat服务器负责创建.
4.3.1 session对象的id
当一个用户首次访问web服务目录中的一个JSP页面时,Tomcat服务器产生一个session对象,这个session对象调用相应的方法可以存储用户在访问该web服务目录中各个页面期间提交的各种信息。
■这个session对象被分配了一个String类型的id号,Tomcat服务器同时将这个id号发送到用户端,存放在用户(浏览器)的Cookie中。这样,session对象和用户之间就建立起一一对应的关系,即每个用户都对应着一个session对象(称作用户的会话),不同用户(不同浏览器)的session对象互不相同,具有不同的id号码。
■当用户再访问该Web服务目录的其它页面时,Tomcat服务器不再分配给用户的新session对象,而是使用完全相同的一个,直到session对象达到了最大生存时间或用户关闭自己的浏览器或Tomcat服务器关闭,Tomcat服务器将销毁用户的session对象
★简单地说,用户(浏览器)在访问一个Web服务目录期间,服务器为该用户分配一个session对象(称作和该用户的会话),服务器可以在各个页面使用这个session记录当前用户的有关信息。而且服务器保证不同用户的session对象互不相同。
注--- 同一个用户在不同的Web服务目录中的session是互不相同的。
4.3.2 session对象与URL重写
session对象能和用户建立起一一对应关系依赖于用户浏览器是否支持Cookie。 ■如果用户不支持Cookie,JSP页面可以通过URL重写来实现session对象的唯一性。
String str=response.encodeRedirectURL("example4_13_b.jsp");
然后将连接目标写成<%= str %>
例如:
<form action="example4_13_b.jsp" method=post >
更改为:
<form action=<%= str %> method=post >
4.3.3 session对象存储数据
(1)public void setAttribute (String key ,Object obj)。 session对象可以调用该方法将参数Object指定的对象obj添加到session对象中,并为添加的对象指定了一个索引关键字,如果添加的两个对象的关键字相同,则先前添加的对象被清除。
(2)public Object getAttribute(String key)。获取session对象索引关键字是key的对象。由于任何对象都可以添加到session对象中,因此用该方法取回对象时,应显式转化为原来的类型。
4.3.4 session对象的生存期限
session对象的生存期限依赖于session对象是否调用invalidate()方法使得session无效或session对象达到了设置的最长的“发呆”状态时间以及用户是否关闭浏览器或服务器被关闭。
▲所谓“发呆”状态时间是指用户对某个Web服务目录发出的两次请求之间的间隔时间(默认的发呆时间是30分钟)。
▲打开Tomcat安装目录中conf文件下的配置文件web.xml,找到
<session-config>
<session-timeout>30</session-timeout>
</session-config>
将其中的30修改成所要求的值即可(单位为分钟)。。
4.4application对象
application对象也是由Tomcat服务器负责创建,但与session对象不同的是,application对象被访问该Web服务目录的所有的用户共享,但不同Web服务目录下的application互不相同。
4.4.1 application 对象的常用方法
(1)public void setAttribute(String key ,Object obj)。application对象可以调用该方法将参数Object 指定的对象 obj添加到application对象中,并为添加的对象指定了一个索引关键字,如果添加的两个对象的关键字相同,则先前添加对象被清除。
(2)public Object getAttibute(String key)。获取application对象含有的关键字是key的对象。由于任何对象都可以添加到application对象中,因此用该方法取回对象时,应显式转化为原来的类型。
由于application对象对所有的用户都是相同的,因此,在某些情况下,对该对象的操作需要实现同步(synchronized)处理。
4.4.2 application 留言板
可以使用application内置对象,让其担当留言板的角色,并设置留言板上最多可留言99999条
4.5out对象
out对象是一个输出流,用来向用户端输出数据。在前面的许多例子里曾多次使用out对象进行数据的输出。out对象可调用如下的方法用于各种数据的输出, 例如:
out.print(boolean)或out.println(boolean) 用于输出一个布尔值。
out.print(char) 或out.println(char) 输出一个字符。
out.print(double) 或out.println(double)输出一个双精度的浮点数。
out.print(fload) 或out.println(float)用于输出一个单精度的浮点数。
out.print(long) 或out.println(long)输出一个长整型数据。
out.print(String) 或out.println(String)输出一个String对象的字符序列。
方法println和print的区别是:println会向缓存区写入一个换行,而print不写入换行。但是浏览器的显示区域目前不识别println写入的换行,如果希望浏览器显示换行,应当向浏览器写入"<br>"实现换行。