2、JSP实现数据传递和保存
前言
掌握request和response的使用
解决页面中出现的中文乱码
掌握转发和重定向的区别
掌握session存取数据
理解cookie
理解application
提示:以下是本篇文章正文内容,下面案例可供参考
1、九个内置对象
JSP已经准备好的,可以直接使用的对象
- 请求对象:request
- 输出对象:out
- 响应对象:response
- 应用程序对象:application
- 会话对象:session
- 页面上下文对象:pageContext
- 页面对象:page
- 配置对象:config
- 异常对象:exception
2、request
2.1 获取表单提交的数据
public String getParameter(String name)
示例
HTML代码:
<input type="text" name="userName" />
JSP代码:
String userName= request.getParameter("userName");
2.2 获取同名的多个参数
示例
<input type="checkbox" name="mailId" value="10001" />
<input type="checkbox" name="mailId" value="10002" />
<input type="checkbox" name="mailId" value="10003" />
<input type="checkbox" name="mailId" value="10004" />
<input type="checkbox" name="mailId" value="10005" />
解决方法:
通过getParameterValues()获取同名数组
```java
String[ ] mailIds=request.getParameterValues("mailId");
if(mailIds!=null&&mailIds.length!=0){
//循环mailIds访问提交的数据
}else{
//未提交与参数mailId相关的数据
}
2.3 get与post区别
比较项 | Get | post |
---|---|---|
参数出现在URL中 | 是 | 否 |
长度限制 | 有 | 无 |
安全性 | 低 | 高 |
URL可传播 | 是 | 否 |
2.3.1 初级回答:
1.get是从服务器上获取数据,post是向服务器传送数据,??
2.get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。
3.get安全性非常低,post安全性较高。但是执行效率却比Post方法好。
4.在进行文件上传时只能使用post而不能是get。
2.3.2 中级回答:【推荐】
- get是从服务器上获取数据,post是向服务器传送数据。??
- get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。post是通过HTTP post机制,将表单内各个 字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址。用户看不到这个过程。
- 对于get方式,服务器端用Request.QueryString获取变量的值,对于post方式,服务器端用Request.Form获取提交的数据
- get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。但理论上,IIS4中最大量为80KB,IIS5中为100KB。
- get安全性非常低,post安全性较高
2.4、 request对象常用方法
方法名称 | 说明 |
---|---|
String getParameter(String name) | 根据表单组件名称获取提交数据 |
String[ ] getParameterValues(String name) | 获取表单组件对应多个值时的请求数据 |
void setCharacterEncoding(String charset) | 指定每个请求的编码 |
RequestDispatcher getRequestDispatcher(String path) | 返回一个RequestDispatcher对象,该对象的forward( )方法用于转发请求 |
2.5、中文乱码解决
JSP中默认使用的字符编码方式:iso-8859-1,不支持中文
常见的支持中文的编码方式
编码方式 | 收录的字符 |
---|---|
gb2312 | 常用简体汉字 |
gbk | 简体和繁体汉字 |
utf-8 | 所有国家需要的字符 |
2.5.1 post:
设置请求和响应的编码方式
1. request.setCharacterEncoding("utf-8");
2. response.setCharacterEncoding("utf-8");
3. <%@ page language="java" contentType="text/html; charset=utf-8"%>
2.5.2 get:
- 治标的方法:new String( s.getBytes(“iso-8859-1”), “utf-8” );
- 治本的方法:配置tomcat\conf\server.xml文件
URIEncoding=“UTF-8”
useBodyEncodingForURI=“true”
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/>
2.5.3 Cookie中解决中文异常问题
- 对要添加cookie的字段进行设置编码格式使用(URLEncoder.encode(String s, String enc))
示例:
userName=URLEncoder.encode(userName,"utf-8");
- 以上可以解决异常问题,但在获取cookie时很有可能出现乱码,所以需在获取cookie值时设置解码方式(URLDecoder.decode(String s, String enc))
示例:
name = URLDecoder.decode(name,"utf-8");
2.6、 在请求中存取属性
2.6.1 在请求中保存属性(作用域:一次请求)
public void setAttribute(String name,Object o)
说明:
String name:属性名
Object o :属性值
示例:
request.setAttribute("mess", "注册失败");
2.6.2在请求中获取属性
public Object getAttribute(String name)
说明:
String name:属性名
注意:
1、在使用属性值的时候要做非空判断,否则会出现空指针异常
2、它的返回值类型是Object类型,需要做数据类型的转换
String mess=(String)request.getAttribute("mess");
if(mess!=null){
//在请求中取到"mess"属性对应的属性值,正常使用mess数据
}else{
//在请求中没有取到"mess"属性对应的属性值,使用备选方案
}
2.7、转发与重定向
2.7.1 转发
RequestDispatcher对象
forward()方法
语法:
1、request.getRequestDispatcher("url").forward(request, response)
2、<jsp:forward page="url" />
本质:
客户端第一次请求(URL1),服务端(URL1)转发请求到响应页面(URL2)进行处理。
所以是此时请求的URL在处理并响应。此时URL没有改变
转发的工作方式:
2.7.2重定向
将用户请求重新定位到一个新的URL
response.sendRedirect("url")
重定向的工作方式:
本质:将用户请求重新定位到一个新的URL
客户端第一次请求服务端(URL1),服务端(URL1)响应给客户端新的(URL2)
客户端第二次请求服务端,(URL2),服务端(URL2)进行处理并响应。
所以重定向后的URL发生了改变。
2.8、转发与重定向的区别
比较项 | 转发 | 重定向 |
---|---|---|
URL变化 | 否 是 | |
重新发出请求 | 不会 | 会 |
是否携带请求 | 是 | 否 |
目标URL要求 | 仅本Web应用 | 任意URL |
注意:重定向是客户端行为,转发是服务器行为
例子说明:
假设你去办理某个执照,
重定向:你先去了A局,A局的人说:“这个事情不归我们管,去B局”,然后,你就从A退了出来,自己乘车去了B局。
转发:你先去了A局,A局看了以后,知道这个事情其实应该B局来管,但是他没有把你退回来,而是让你坐一会儿,自己到后面办公室联系了B的人,让他们办好后,送了过来。
2.8.1 参数传递区别
2.8.1.1 转发:
public void setAttribute(String name,Object o)
使用转发进行属性转递时,转发给其他URL处理时仍然属于一次请求,所以可以获得参数
2.8.1.2 重定向:
重定向使用属性传递时,由于重定向的本质是2个请求,则第一次请求所携带的参数在的二次不会再次携带。
可用扩大作用域来进行携带参数,如下例子:
response.sendRedirect(request.getContextPath()+"/index.jsp");
2.8.2 路径
JSP头部引用如下:
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
用来表明当前页面的相对路径所使用的根路径,也就是项目名称
示例:http://localhost:8085/Info_System/user/user_info.jsp
1.request.getSchema();可以返回当前页面所使用的协议,就是”http”
2.request.getServerName();返回当前页面所在服务器的名字,就是上面例子中的”localhost”
3.request.getServerPort();返回当前页面所在服务器的端口号,就是上面例子中的”8085”
4.request.getContextPath();返回当前页面所在的应用的名字(项目名),就是上面例子中的”Info_System”
超链接的路径例子如下:
<base href="<%=basePath%>" />
2.8.3 Cookie使用的区别
2.8.3.1 转发
第一次请求到服务端时,客户端没有cookie,转发到其他页面处理时,此时都属于一次的请求范围,服务端并没有返回cookie。当服务端响应完成后,客户端拿到了cookie,所以刷新进行重新请求时可以拿到cookie的参数
2.8.3.2 重定向
第一次请求到服务端时,服务端返回cookie即服务端拿到cookie
第二次请求到服务端时,其request对象里已经包含了cookie
3、Session
3.1 session存储信息(作用域:一个会话)
- 一个会话就是浏览器与服务器之间的一次通话
- 会话可以在多次请求中保存和使用数据
设置语法:
public void setAttribute(String name, Object value);
示例
用法:session.setAttribute("userName", "张三丰");
获取信息语法:
public Object getAttribute(String name);
示例
用法:String userName=(String)session.getAttribute("userName");
说明:Object value的值可用request.getParameter()
获得session的工作方式
每个session都有一个唯一的sessionid
public String getId();
session.getId();
说明:
cookie禁用后,session是否能使用(摘录网络内容,供大家参考)
URL重写
表单提交隐藏域
cookie禁用后,session能否使用的问题
sessionid是存储在cookie中的,解决方案如下:
Session URL重写,保证在客户端禁用或不支持COOKIE时,仍然可以使用Session
session机制。session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否已包含了一个session标识(称为session id),如果已包含则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(检索不到,会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。 保存这个session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器。一般这个cookie的名字都是类似于 SEEESIONID。但cookie可以被人为的禁止,则必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。 经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面。还有一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。比如:
URL重写:
http://www.test.com/test;jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
3.2 session的清除和过期
session的数据是在服务器端的,服务器保存的会话数据量会越来越大,从而导致性能问题
若没有清理机制,会导致性能问题或服务器崩溃
程序主动清除session数据
服务器主动清除长时间没有再次发出请求的session
3.2.1 程序主动清除session数据
作用:
可用作注销
1、 设置会话失效:session.invalidate();
说明:直接使用
2、 移除会话的一个属性
语法:
public void removeAttribute(String name);
用法:session.removeAttribute("userName");
说明:需指定属性
3.2.2 定时清除session数据
服务器主动清除长时间没有再次发出请求的session
设置会话过期时间
方法一:
public void setMaxInactiveInterval(int interval);
说明:
int interval:单位:秒
方法二:
<session-config>
<session-timeout>30</session-timeout>
</session-config>
说明:
1、 在web.xml中设置session的有效期
2、 中间的单位是秒
注意:
1、设置session过期时间后,在同一个页面超过时间,进行刷新,此时sessionId发生改变,说明原来的会话已经过期,现获取的是新的session。
2、session是服务端的行为
4、cookie
作用:自动填写用户名
cookie以文件方式保存数据
4.1 添加数据
public void addCookie(Cookie cookie)
4.2获取数据
public Cookie[] getCookies()
4.3 设置有效期,单位秒,不设置则关闭浏览器失效
public void setMaxAge(int expiry)
4.4 用户可以禁用cookie和解决
解决方案:
Session URL重写,保证在客户端禁用或不支持COOKIE时,仍然可以使用Session
session机制。session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否已包含了一个session标识(称为session id),如果已包含则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(检索不到,会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。 保存这个session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器。一般这个cookie的名字都是类似于 SEEESIONID。但cookie可以被人为的禁止,则必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。 经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面。还有一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。比如:
<form name=”"testform”" action=”"/xxx”"> <input type=”"hidden”" name=”"jsessionid”" value=”"ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764″”> <input type=”"text”"> </form>
URL重写:
http://www.test.com/test;jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
4.5 设置有效路径:整个工程可用访问cookie,否则仅本路径和子路径访问
cookie.setPath("/");
4.6 示例
4.6.1 新建Cookie并设置
//给中文添加cookie编码(设置编码集为utf-8),且尽量不存中文
userName=URLEncoder.encode(userName,"utf-8");
//Cookie 新建对象,记录用户名,自动填写功能,键值对构造器
Cookie cookie = new Cookie("userName",userName);
//设置Cookie有效时间,单位秒,不设置则关闭浏览器失效
cookie.setMaxAge(20);
//整个工程可用访问cookie,否则仅本路径和子路径访问
cookie.setPath("/");
//给响应添加Cookie
response.addCookie(cookie);
注意:要采用重定向发生请求,即可“一次”拿到cookie。而转发需再刷新
4.6.2 获取cookie的方式
<%
//使用cookie获取数据,填充到文本框
String name = "";
//获取Cookie数组
Cookie[] cookies = request.getCookies();
//非空判断
if (cookies != null && cookies.length != 0) {
//遍历cookie
for (int i = 0; i < cookies.length; i++) {
//测试cookie的key值
System.out.println(cookies[i].getName());
if (cookies[i].getName().equals("userName")) {
//获取cookie的value值
name = cookies[i].getValue();
//对cookie的value值解码设置为utf-8
name = URLDecoder.decode(name,"utf-8");
}
}
}
%>
5、application
作用:统计页面的访问次数
分析
- 每个用户都需要使用访问次数
- application可在整个项目中共享使用数据
- 使用application实现计数器
- 每次访问该页面,计数器加1
方法
public void setAttribute(String name, Object object);
public Object getAttribute(String name);
示例:
<%
//通过application设置count属性,并获取值
Integer count = (Integer) application.getAttribute("count");
//非空判断,若为空,则是第一次访问,设置count=1
if (count == null) {
application.setAttribute("count", 1);
} else {
//非空设置count的值加一
application.setAttribute("count", count + 1);
}
//获取count的值,并输出
count = (Integer) application.getAttribute("count");
out.print("页面被访问了" + count + "次");
%>
6、三个对象对比
6.1 相同点
- 都可以存储属性
6.2 不同点
-
request中存储的数据仅在一个请求中可用
-
session中存储的数据在一个会话的有效期内可用
-
application中存储的数据在整个Web项目中可用