阳光男孩

Never give up!

Entries Tagged ‘J2ME’

Cookie技术在J2ME平台的应用

0顶一下本文向大家简单介绍一下cookie技术在J2ME平台的应用与实现,首先,我们来看一下cookie的原理。当服务器需要和浏览器维持某一状态的时候,例如需要记录用户的购物车中已经购买的商品。这时候服务器可以新建一个Cookie并把它写入到响应中,浏览器从响应中接收到cookie并保存起来。 cookie技术在J2ME平台的应用与实现 Cookie在Web应用程序中被广泛采用,维护浏览器和服务器之间的状态。遗憾...[阅读全文]

0
顶一下

本文向大家简单介绍一下cookie技术在J2ME平台的应用与实现,首先,我们来看一下cookie的原理。当服务器需要和浏览器维持某一状态的时候,例如需要记录用户的购物车中已经购买的商品。这时候服务器可以新建一个Cookie并把它写入到响应中,浏览器从响应中接收到cookie并保存起来。

cookie技术在J2ME平台的应用与实现

Cookie在Web应用程序中被广泛采用,维护浏览器和服务器之间的状态。遗憾的是这一特性在JavaME平台中并没有得到支持。因此,要想维持客户端和服务器端的状态则必须使用URL重写的方式。URL重写操作起来比较麻烦,所以研究一下cookie的原理并在JavaME平台上实现cookie是不错的尝试。

首先,我们来看一下cookie的原理。当服务器需要和浏览器维持某一状态的时候,例如需要记录用户的购物车中已经购买的商品。这时候服务器可以新建一个Cookie并把它写入到响应中,浏览器从响应中接收到cookie并保存起来。当浏览器再次向服务器发送请求的时候,浏览器会根据域(domain)和路径(path)检查是否有匹配的cookie,如果有则把cookie以“名称=值”的形式发送给服务器,服务器从请求中解析出cookie就知道用户的状态了。

那么,浏览器根据什么规则来决定向服务器发送cookie呢,首先要匹配domain,如果cookie的域属性是。google.com,那么请求指向j2medev.com的时候,cookie就不会被发送。如果域匹配的条件满足,则判断path是否匹配,如果cookie的path属性是请求的uri的父目录的话,那么cookie就会被发送给服务器。Cookie是有存活周期的,到期的cookie会被浏览器自动清除。如果服务器创建cookie的时候不设置生命周期,那么在会话结束后浏览器就会删除cookie.如果不为cookie指定path属性,那么默认就是这次请求的路径。

cookie在很多web应用程序中都有应用,比如记住密码,购物车等。在开发MIDlet的时候,你也可以让你的应用程序支持cookie,这样维持客户端与服务器端的状态将变得简单,为你集中精力解决其他业务方法奠定了基础。既然已经知道了cookie的工作原理,那么就应该考虑一下在JavaME平台如何实现cookie,这个想法是否可行。我将从下面三个方面进行分析。

第一:获得cookie

当服务器端的响应到来的时候,我们应该能够读取cookie。如果服务器向客户端写入Cookie的时候,响应中的HTTP头“Set-Cookie”中会包含一个字符串,代表了cookie的信息。幸运的是我们是用HttpConnection.getHeaderFiled(“Set-Cookie”)方法即可获得cookie,但是需要注意这里只是读取了一个cookie,如果响应中包含了多个cookie,那么你需要循环读取。类似于下面的代码:

StringsCookie=null;
Stringkey=null;
inti=0; //如果key存在,则查询header的key,如果key等于SET_COOKIE,则存储
while((key=connection.getHeaderFieldKey(i))!=null)
{
if(key.equals(SET_COOKIE)||key.equals(SESSIONID))
{
sCookie=connection.getHeaderField(i);
saveCookie(sCookie,url);
}
i++;
}

上面的代码把header是Set-Cookie和SesssionID的cookie内容读取下来。

第二:保存cookie

已经获得了cookie之后,就需要把cookie存储下来,存储分为两个部分,首先需要解析cookie,我们定义一个JavaBean来代表cookie.

packagecom.j2medev.lomol.model;
importcom.j2medev.lomol.util.StringUtil;
importjava.io.DataInputStream;
importjava.io.DataOutputStream;
importjava.io.IOException;
importjava.util.Date;
/**  *acookiestoredonthemobiledevice,
cookieisusedtomaintainthestatesbetweenclientandserver
*@authormingjava
*@version0.105/06/2006
*/
publicclassCookie{
privateStringpath=”";
privateStringname=”";
privateStringvalue=”";
privatelongexpire=SESSION_COOKIE;
publicstaticlongSESSION_COOKIE=0;
//sessioncookie,onlyvalidthissession
publicCookie(){  }
publicStringgetPath(){  returnpath;  }
publicvoidsetPath(Stringpath){  this.path=path;  }
publicStringgetName(){  returnname;  }
publicvoidsetName(Stringname){  this.name=name;  }
publicStringgetValue(){  returnvalue;  }
publicvoidsetValue(Stringvalue){  this.value=value;  }
publicvoidserialize(DataOutputStreamdos)
throwsIOException{
dos.writeUTF(name);
dos.writeUTF(value);
dos.writeUTF(path);
dos.writeLong(expire);
}
publicstaticCookiedeserialize(DataInputStreamdis)throwsIOException{
Cookiecookie=newCookie();
cookie.name=dis.readUTF();
cookie.value=dis.readUTF();
cookie.path=dis.readUTF();
cookie.expire=dis.readLong();
returncookie;
}
publiclonggetExpire(){
returnexpire;
}
publicvoidsetExpire(longexpire){  this.expire=expire;
}
//fordebug
publicStringtoString(){
returnname+”=”+value+”;expires=”+newDate(expire)。
toString()+”;path=”+path;
}
publicbooleanisExpired(longnow){
returnexpire-now<0;
}
publicbooleanisExpired(){
returnexpire-(newDate()。getTime())<0;
}
publicstaticCookieparseCookie(Strings,Stringuri){
Cookiecookie=newCookie();
StringUtilsu=newStringUtil(s,”;”);
while(su.hasMoreTokens()){
Stringstr=su.nextToken()。trim();
inti=str.indexOf(”=”);
if(i==-1){
//securedonothing  continue;
}else{
Stringname=str.substring(0,i);
Stringvalue=str.substring(i+1,str.length());
if(”path”.equals(name)){
cookie.setPath(value);
}elseif(”expires”.equals(name)){
cookie.setExpire(StringUtil.getData(value));
}elseif(”domain”.equals(name)){
//donothing  }else{
cookie.setName(name);
cookie.setValue(value);
}  }
if(cookie.getPath()。equals(”"))
cookie.setPath(uri);  }  returncookie;  }
publicbooleanequals(Objectobj){
if(objinstanceofCookie){  Cookieo=(Cookie)obj;
if(o.getName()。equals(name)&&o.getPath()。equals(path))
returntrue;  }  returnfalse;  }
publicinthashCode(){  intresult=17;
resultresult=result*37+path.hashCode();
resultresult=result*37+name.hashCode();
returnresult;  }  }

提供了一个parseCookie方法来解析cookie,具体的原理就不再介绍了。然后需要把这个Cookie对象存储到RMS中。cookie并不大,所以不会占用太多的空间,在RMS中存储非常合适。注意对于会话期间的cookie没有必要存储在rms中,因为会话结束后就失效了,不如在内存中声明一个Map来存储会话类型的cookie。

第三:发送cookie

发送cookie也是需要两个步骤,首先检索rms和内存看是否有满足条件的cookie,如果有读取出来。

然后通过下面的方法向服务器端发送:

//检查是否有cookie需要发送给服务器端
String_cookie=collectCookie(url);
if(_cookie!=null)
connection.setRequestProperty(COOKIE,_cookie);

如果能够顺利解决上面的三个步骤,基本可以实现cookie在javame平台的应用。在《JavaME核心技术与最佳实践》一书中,本人编写了一个httpme联网框架,其中包括了cookie在javame平台的实现,供大家参考。

 

Comments (53)

J2ME中KXML与NanoXML解析XML总结

0顶一下Java认证:J2ME中KXML与NanoXML解析XML总结,XML全称为EXtensible Markup Language,中文称为可扩展标记语言,是一种计算机所能理解的信息符号语言。计算机之间可以通过此种标记语言处理包含各种信息的文章等功能。由于XML是一种允许相关人士自由决定的标记语言,所以称语言的可扩展性。   XML作为一个标准,而且由于XML是一种纯文本格式存储文件,从而使得XML本身具备了很好的跨平台...[阅读全文]

0
顶一下

Java认证:J2ME中KXML与NanoXML解析XML总结,XML全称为EXtensible Markup Language,中文称为可扩展标记语言,是一种计算机所能理解的信息符号语言。计算机之间可以通过此种标记语言处理包含各种信息的文章等功能。由于XML是一种允许相关人士自由决定的标记语言,所以称语言的可扩展性。

 

XML作为一个标准,而且由于XML是一种纯文本格式存储文件,从而使得XML本身具备了很好的跨平台的特点,因此被广泛应用于网络数据交换的各个领域,包括网络通讯、不同程序语言平台之间的数据交流等方面。

要使用XML作为网络中传输通讯,势必在传输双方的发送方跟接收端都具备对XML文件的解析能力才能实现正常的数据交换并完成通讯过程。由于在移动设备硬件中的CPU跟内存的不足,跟网络传输速率的欠缺,而且解析XML需要消耗更多的资源,因此使得XML在移动设备中的使用收到了限制,在更多时候我们采用的是采用基于基本数据流的形式(如J2ME中的DataInputStream和DataOutputStream)在读取和发送数据。然而,随着智能手机硬件的提高跟普及以及3G网络的落实,使得在不久我们将能无顾虑地在移动通讯中使用XML了。

在J2ME体系中,对xml的解析有比较有名的第三方解析API,分别为KXML和NanoXML,他们都提供了对解析xml的支持。KXML在解析XML过程中会对文件内容一层一层进行解析,因此成为增量式解析器,比较适合大文件的解析。而NanoXML是一次性解析器,在一次时间里就把整个xml文档解析完,因此不适合大文件的解析,会造成内存不足的现象。有关这两种解析器网上都有介绍过,在这里对它们的使用进行总结。

一、创建实例对象

1、使用NanoXML时由于是一次性机制,因此将xml数据流一次性封装创建解析实例对象kXMLElement

/**

HttpConnection conn;

String xml;

Reader r;

*/

//……获取网络连接对象或者其他形式数据对象

InputStreamReader isrDoc =

new InputStreamReader(conn.openInputStream());//获取输入流,这里以HttpConnection为例

kXMLElement kXMLeroot = new kXMLElement();//创建实例对象

try {

kXMLeroot.parseFromReader(isrDoc);

}

catch( kXMLParseException kpe ){

kpe.printStackTrace();

}

catch( IOException ie ){

ie.printStackTrace();

}

2、使用kxml时首先需要得到一个XmlParser实例对象,在构造方法中传入Reader参数

/**

HttpConnection conn;

String xml;

Reader r;

*/

InputStreamReader isrDoc =

new InputStreamReader(conn.openInputStream());//获取输入流,这里以HttpConnection为例

XmlParser parser = new XmlParser(isrDoc);//创建实例对象

二、KXML解析XML

boolean parsing = true;//判断是否到达最后一个document标签

while()

{

ParseEvent event = parser.read();

swith(event.getType())

{

case Xml.START_TAG:

….//处理开始标签tag

break;

case Xml.END_TAG:

…//处理结束标签tag

break;

…….//其他标签处理

case Xml.END_DOCUMENT:

…//最末tag

parsing = false;

break;

}

}

三、NanoXML解析XML

Vector list = kXMLeroot.getChildren();//获取子节点列表

Vector contents = new Vector();//用于获取节点内容

for(int i = 0; i < list.size(); ++i){

kXMLElement node = (kXMLElement) list.elementAt(i);

String tag = node.getTagName();

if(tag == null) continue;

if(!tag.equals( “item” )) continue;

contents.addElement(node.getContents());

}

String[] contentStrs = new String[contents.size()];//转化为字符串数组

NanoXML是一个能在CLDC 环境下运行的开放源代码,NanoXML是非常小(6KB)的一步XML解析器;KXML是一个只占很小存储空间的XML语法分析程序,对于J2ME应用程序非常适合。

 

Comments (91)

J2ME里面的一些未实现的三角函数

2顶一下package com.ken.math; /** * 通过计算公式实现反正切、反正弦、反余弦<br> * Tan(X)=Sin(X)/Cos(x) <br> * ArcSin(X)=ArcTan(X/Sqrt(1-Sqr(X)))<br> * ArcCos(X)=ArcTan(Sqrt(1-Sqr(X))/X)<br> * * @author <a href=”mailto:xzknet@gmail.com”>Ken_xu</a> * @version 1.0 Copyright 2008-5-4 下午04:09:04 */ public class SuperMath { /** * 反...[阅读全文]

2
顶一下

package com.ken.math;

/**
* 通过计算公式实现反正切、反正弦、反余弦<br>
* Tan(X)=Sin(X)/Cos(x) <br>
* ArcSin(X)=ArcTan(X/Sqrt(1-Sqr(X)))<br>
* ArcCos(X)=ArcTan(Sqrt(1-Sqr(X))/X)<br>
*
* @author <a href=”mailto:xzknet@gmail.com”>Ken_xu</a>
* @version 1.0 Copyright 2008-5-4 下午04:09:04
*/
public class SuperMath {
/**
* 反正切<br>
* radian为正切值,这个函数的值域为-π/2~π/2
*
* @param radian
*             弧度为单位的角度
* @return 该角度所对应的反正切
* @author Ken_xu
*/
public static double actTan(double radian) {
System.out.println(radian);
double retval = 0d;
if (Math.abs(radian) <= 1.0d) {
retval = radian / (1.0D + 0.28d * sqr(radian));
} else {
retval = -radian / (sqr(radian) + 0.28d);
if (radian < -1.0d) {
retval = retval – Math.PI / 2;
} else {
retval = retval + Math.PI / 2;
}
}
return retval;
}

/**
* 反正切<br>
* 正切值为y/x,因此该函数求的是y/x所对应的角,这个函数的值域为-π~π
*
* @param y
* @param x
* @return 该角度所对应的反正切
* @author Ken_xu
*/
public static double actTan(double y, double x) {
if (y == 0.0d && x == 0.0d)
return 0.0d;
if (x > 0.0d)
return actTan(y / x);
if (x < 0.0F)
if (y < 0.0d)
return (-(Math.PI – actTan(y / x)));
else
return (Math.PI – actTan(-y / x));
return y >= 0.0F ? Math.PI / 2 : Math.PI / 2;
}

/**
* 反正弦
*
* @param radian
*             弧度为单位的角度
* @return 该角度所对应的反正弦
* @author Ken_xu
*/
public static double actSin(double radian) {
// ArcSin(X)=ArcTan(X/Sqrt(1-Sqr(X)))
double retval = actTan(radian / Math.sqrt(1 – sqr(radian)));
return retval;
}

/**
* 反余弦
*
* @param radian
*             弧度为单位的角度
* @return 该角度所对应的反余弦
* @author Ken_xu
*/
public static double actCos(double radian) {
// ArcCos(X)=ArcTan(Sqrt(1-Sqr(X))/X)
double retval = actTan(Math.sqrt(1 – sqr(radian)) / radian);
return retval;
}

/**
* 平方函数
*
* @param x
* @return 平方值( x * x )
* @author Ken_xu
*/
public static double sqr(double x) {
return x * x;
}

Comments (8)