打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
ASIHTTPRequest系列(四):Cookies

六、使用 Cookies

Cookies 是重要的服务器状态保持策略。Web 服务器常使用 Cookies 技术来实现用户免登录功能和存储用户状态信息。ASIHTTPRequest支持客户端 Cookies 的存取。

1、服务器端

Session 是服务器端技术,虽然 Cookies 是保存在客户端的。因此我们需要一个服务器端环境。打开Eclipse,新建 Web 工程,随便写几个简单的 jsp 页面:

<%@page contentType="text/html; charset=GBK" %>

<html>

<head>

<%

String lastUrl=(String)request.getParameter("lastUrl");

%>

<title>login.jsp</title>

<!--meta http-equiv="Content-Type"content="text/html; charset=iso-8859-1"-->

<!--meta http-equiv="Content-Type"content="text/html; charset=gb2312"-->

</head>

<FORM name="form1" METHOD="POST"ACTION="LoginServlet">

<p><input name="username" type= "text"value=""><br>

<p><input name="pass" type="text"value="" > <br>

<p><input name="ok" type= "submit"value="提交">

<p><input name="lastUrl" type="text"value="<%=lastUrl%>">

</form>

</html>

这是login.jsp,仅仅有一个用户登录表单。因为在 Web 中,往往只有经过合法登录的用户才需要保持状态。

<%@page contentType="text/html; charset=GBK" %>

<html>

<head>

<%

String uid=(String )session.getAttribute("uid");

String sessionid=(String)session.getId();// 获取 sessionid

String lastUrl="index.jsp";

if(uid==null){

%>

<jsp:forward page="login.jsp">

<jsp:param name="lastUrl" value="index.jsp"/>

</jsp:forward>

<%} %>

<title>index.jsp</title>

<!--meta http-equiv="Content-Type"content="text/html; charset=iso-8859-1"-->

<!--meta http-equiv="Content-Type"content="text/html; charset=gb2312"-->

</head>

<body>

hello<%=","+uid+"!" %>

<p>

session id=<%=sessionid%>

<p>

<a href="second_page.jsp">goto>></a>

</body>

</html>

这个是 index.jsp 页面,头部加入了一段 java 代码,要求用户必需登录,否则会自动转向登录页面。另外还把本页URI 作为请求参数 lastUrl ,这样在登录成功后,会自动跳转到等路前请求的页面。

<%@page contentType="text/html; charset=GBK" language="java"%>

<html>

<head>

<%

String uid=(String )session.getAttribute("uid");

String sessionid=(String)session.getId();// 获取 sessionid

if(uid==null){

%>

<jsp:forward page="login.jsp">

<jsp:param name="lastUrl" value="second_page.jsp"/>

</jsp:forward>

<%} %>

<title>second page</title>

<!--meta http-equiv="Content-Type"content="text/html; charset=iso-8859-1"-->

<!--meta http-equiv="Content-Type" content="text/html;charset=gb2312"-->

</head>

<body>

seconde page<%=","+uid+"!" %>

<p>

session id=<%=sessionid%>

</body>

</html>

这个是 second_page.jsp 页面。跟 index.jsp的意思差不多,只不过想演示一下 sessionid 在多个页面中的传递。

public class LoginServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

  protected void doGet(HttpServletRequest request, HttpServletResponseresponse) throws ServletException, IOException {

String username=request.getParameter("username");

String pass=request.getParameter("pass");

String lastUrl=request.getParameter("lastUrl");

if("".equals(username))

username=null;

if("".equals(pass))

pass=null;

boolean loginSuccess=false;

PrintWriter out=response.getWriter();

if(username!=null && pass!=null){

loginSuccess=true;

}

if(loginSuccess){

// 获取session,如果requestsession id不存在,则新建

HttpSession session=request.getSession();

// 不设置MaxInactiveInterval,则浏览器一关闭就过期

// session.setMaxInactiveInterval(12*60*60);

session.setAttribute("uid",username);

// 重写url,带上 session id

 

String redirectUrl;

if(lastUrl!=null && !"".equals(lastUrl)){

redirectUrl=response.encodeURL(lastUrl);

}else{

redirectUrl=response.encodeURL("index.jsp");

}

System.out.println("redirectUrl :"+redirectUrl);

// forward,不要用redirect。因为后者是服务端转发,没有客户端请求,不会发送cookie

RequestDispatcher rd=request.getRequestDispatcher(redirectUrl);

rd.forward(request, response);

}else{

// 获取session,但requestsession id不存在时,不新建

HttpSession session=request.getSession(false);

if(session!=null)

session.invalidate();// 使session失效

out.println("login failed");

}

}

protected voiddoPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {

doGet(request,response);

}

这是 servlet,用于用户登录。这里我偷了个懒,只要用户名不为空,我们就通过验证,仅仅为了演示。需要注意的就是两点:

  1、response.encodeURL(),这个方法服务器会检测客户端是否支持接收Cookies,如果客户端(比如IE)禁用了Cookies,则服务器会通过重写URL的方式向客户端发送 sessionid。比如,客户端请求 index.jsp 页面,encodeURL()之后服务器会把 URL 地址改写为: index.jsp;jsessionid=FC076B0E1F0763CFE7BFAFEBA2E0287C

  2、页面转发。页面跳转有多种方式。比如 request.sendRedirect。在servlet中,千万不要使用 sendRedirect ,这样会使用服务器跳转,servlet会把原来的 request 参数和 attributes 全部抛弃(包括 Cookies)。所以sendRedirect 之前和之后的请求使用的不是同一个sessionid。因此在servlet中,我们采用的是 RequestDispatcher.forward()方法,它是客户端跳转,即服务器会让客户端(浏览器)重新请求另一个地址来转发,保证session 状态不被丢失。

进行测试,打开浏览器,访问 http://localhost:8080/test/second_page.jsp,页面会自动跳到 login.jsp。因为 java 脚本检测不到用户的 session 信息(未进行登录)。当你登录后,浏览器返回你原先请求的页面second_page.jsp。

2、iPhone 客户端

ViewController的界面很简单,1个UIWebView,1个UIToolBar,3个UIBarButtonItem:

 

接下来是 ViewController 的 interface 代码:

#import <UIKit/UIKit.h>

#import "ASIHTTPRequest.h"

#define URL @"http://220.163.103.23/interface/GetSmsList?Accounts=sa&Password=ydtf@95598"

 

 

@interface CokieSessionViewController : UIViewController {

UIBarItem* button,*indexButton,*secondPageButton;

UIWebView* webView;

ASIHTTPRequest *request;

NSURL* url;

 }

@property(retain,nonatomic)IBOutlet UIBarItem* button,*indexButton,*secondPageButton;

@property(retain,nonatomic)IBOutlet UIWebView* webView;

-(IBAction)login;

-(IBAction)gotoIndexPage;

-(IBAction)gotoSecondPage;

@end

将所有IBOutlet 和 IBAction 对象,在 IB 中建好连接。下面是implement代码:

@implementation CokieSessionViewController

@synthesize button,indexButton,secondPageButton,webView;

- (void)didReceiveMemoryWarning {

   // Releases the view if itdoesn't have a superview.

   [super didReceiveMemoryWarning];

}

 

- (void)viewDidUnload {

   [super viewDidUnload];

}

 

 

- (void)dealloc {

   [super dealloc];

}

-(IBAction)login{

BOOL success;

url = [[[NSURL alloc] initWithString:@"http://localhost:8080/test/LoginServlet?username=dd&pass=1"] autorelease];

request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];

// 设置 cookie 使用策略:使用(默认)

[request setUseCookiePersistence:YES];

[request startSynchronous];

NSString* html=[request responseString];

NSRange range=[htmlrangeOfString:@"loginfailed" options:NSCaseInsensitiveSearch];

if (range.location==NSNotFound) {// 如果登录成功

[webView loadHTMLString:@"loginsuccess" baseURL:url];

}else {// 如果登录失败

[webView loadHTMLString:@"loginfailed" baseURL:url];

}

 

// 获得本地 cookies 集合(在第一次请求时服务器已返回cookies,

//  虽然其中很可能只有一个cookie: sessionid )

NSArray *cookies =[request responseCookies];

// 打印 sessionid

NSHTTPCookie *cookie = nil;

for (cookie in cookies) {

if ([[cookie name]isEqualToString:@"JSESSIONID"]) {

NSLog(@"sessionname:%@,value:%@",[cookie name],[cookie value]);

}

}

}

-(IBAction)gotoIndexPage{

url = [[[NSURL alloc] initWithString:@"http://localhost:8080/test/index.jsp"] autorelease];

request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];

// 设置 cookie 使用策略:使用(默认)

[request setUseCookiePersistence:YES];

[request startSynchronous];

[webView loadHTMLString:[request responseString] baseURL:url];

}

-(IBAction)gotoSecondPage{

url = [[[NSURL alloc] initWithString:@"http://localhost:8080/test/second_page.jsp"] autorelease];

request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];

// 设置 cookie 使用策略:使用(默认)

[request setUseCookiePersistence:YES];

[request startSynchronous];

[webView loadHTMLString:[request responseString] baseURL:url];

}

@end

编译运行,你可以看到,当点击 index.jsp 和second_page.jsp 按钮时,webView 中显示的始终是登录界面 login.jsp。因为我们没有获得合法的 session。当然,第一次请求始终可以获得一个sessionid,然而和登录后的sessionid 不一样,这个 sessionid中不保存任何用户信息。

而点击 login 按钮后,再来点击那两个按钮,则可以显示相应的页面。因为服务器已经在那个sessionid所对应的session 中放入了用户的ID。我们只需在对应的 jsp 页面中检测用户ID 就可知道用户是否已登录。

 

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
重定向与跳转的区别
什么是jsp以及JSP运行原理
php 解决和避免form表单重复提交的方法 | HLMBlog
HTTP协议图示详解
cookie与session的关系
Cookie、Session、Token那点事儿
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服