Cookie中存取email地址和特殊值的问题解决方法。

分类:Java, Web UI & Ajax, 服务器端技术, 程序设计, 计算机与互联网 作者: 秋天 on 24-10-2009

问题:在Cookie value中储存特殊字符并读取。

典型案例:email地址在cookie value中的存取。

解决方法:通过将Cookie value进行Base54编码后储存,读取,并解码。

环境:Java & Javascript

问题延伸:Javascript中读取Base64值错误的解决方法。

我个人认为使用email地址来作为用户帐户登录名称是一个比较不错的方法。首先email地址本身已经具备一定程度上的唯一性。通过一定的正则表达式判断或者直接使用现成的一些判断类和Service判断后可以使数据库中的该字段价值更高。其次在同一用户需要使用多个帐户的情况下,相比“用户名”来说,更加直接并且容易记忆。

使用传统的方式创建的cookie:

Cookie cookie = new Cookie(cookieName, cookieValue);
((BridgeExternalContext)context.getExternalContext()).addCookie(cookie); // icefaces中使用ExternalContext储存cookie

此时如果cookieValue的值是包含一些特定字符,比如空格,大括号,小括号,逗号,以及@等。用直接读取的方式将不能得到正确的值。

比如上面的代码中,String cookieValue = "sam@satech.com.au"

使用下面的代码直接读取:

Cookie[] cookies = ((HttpServletRequest)((BridgeExternalContext)FacesContext
	                .getCurrentInstance().getExternalContext()).getRequest()).getCookies();
for(int i=0;i<cookies.length;i++){
 if(cookies[i].getName().equals(loginCookieName)) {
 this.loginName = cookies[i].getValue();
}

你会发现,储存后在firefox的cookie查看器中能看到正常的值,而读取出来以后,值只剩下一个sam了。这显然不是我们所想要的。

最简单的解决方式,就是使用某种编码方式避开这些不能接受的字符,之后读取出来再进行解码。这里使用Base64编码来解决。其实使用任何编码方式都是可以的。

我的环境中有很多Base64类的继承类可以使用。比较常见的是

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

其他一些继承类中的加密和解码方法,可以直接作为静态方法调用,比如Icefaces自己也在utility包里面包含了。Base64类,需要的朋友可以尝试使用,原理是一样的。我这里列出使用基本的sun的misc包中的BASE64Encoder & Decoder的方法。

编码

if (log.isDebugEnabled()) {
 log.debug("Encoding string: " + this.loginName);
 }
 byte[] encodedBytes = this.loginName.getBytes(); // convert String into byte[]
 BASE64Encoder base64encoder = new BASE64Encoder(); // Create encoder
 this.base64LoginName = base64encoder.encode(encodedBytes);
 Cookie nameCookie = new Cookie(loginCookieName, this.base64LoginName);
 nameCookie.setMaxAge(SECONDS_PER_YEAR);
 nameCookie.setComment("This is the cookie to store username");
((BridgeExternalContext)context.getExternalContext()).addCookie(nameCookie); // save cookie to context

解码

Cookie[] cookies = ((HttpServletRequest)((BridgeExternalContext)FacesContext
 .getCurrentInstance().getExternalContext()).getRequest()).getCookies();
 for(int i=0;i<cookies.length;i++){
 if(cookies[i].getName().equals(loginCookieName)) {
 this.base64LoginName = cookies[i].getValue();
 BASE64Decoder decoder = new BASE64Decoder();
 try {
 byte[] decodedBytes = decoder.decodeBuffer(this.base64LoginName);
 this.loginName = new String(decodedBytes);
 } catch (IOException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }

现在这个cookie value就能接受大部分的字符集了。但是,又发现一个问题。大部分的Base64都是以"="结尾。在纯Java环境中读取和储存都没有问题,但是某些时候会需要在Javascript中储存和读取这个值。在Javascript中读取已储存的Base64值的时候,最后面的"="会丢失,导致读取错误。

解决方案有2,第一,使用URLCodec urlCodec再次编码。第二,自己写一个判断函数来加上最后的"=" or "=="

方案一:

 public class CookieDecoder {

 private static final Log log = LogFactory.getLog(CookieDecoder.class);

 /**
 * @param cookieValue The value of the cookie to decode
 * @return Returns the decoded string
 */
 public String decode(String cookieValue) {
 if (cookieValue == null || "".equals(cookieValue)) {
 return null;
 }

 if (log.isDebugEnabled()) {
 log.debug("Decoding string: " + cookieValue);
 }
 URLCodec urlCodec = new URLCodec();
 String b64Str;
 try {
 b64Str = urlCodec.decode(cookieValue);
 }
 catch (DecoderException e) {
 log.error("Error decoding string: " + cookieValue);
 return null;
 }
 Base64 base64 = new Base64();
 byte[] encodedBytes = b64Str.getBytes();
 byte[] decodedBytes = base64.decode(encodedBytes);
 String result = new String(decodedBytes);
 if (log.isDebugEnabled()) {
 log.debug("Decoded string to: " + result);
 }
 return result;
 }
}

JS部分:

Encode:
var encodedValue = this.base64.encode(value); document.cookie = name + "=" + escape(encodedValue) + "; expires=" + this.expires.toGMTString() + "; path=" + this.path;

Decode:
var nameEQ = name + "="; var ca = document.cookie.split(';'); for(var i = 0; i < ca.length; i++) { var c = ca[i]; while (c.charAt(0)==' ') { c = c.substring(1,c.length); } if (c.indexOf(nameEQ) == 0) { var encodedValue = c.substring(nameEQ.length,c.length); return this.base64.decode(unescape(encodedValue)); } } return null;

方案二:padString()来解决最后那个等号。

 private static final Log log = LogFactory.getLog(CookieDecoder.class);

/**
 * @param cookieValue The value of the cookie to decode
 * @return Returns the decoded string
 */
public String decode(String cookieValue) {
 if (cookieValue == null || "".equals(cookieValue)) {
 return null;
 }

 if (!cookieValue.endsWith("=")) {
 cookieValue = padString(cookieValue);
 }

 if (log.isDebugEnabled()) {
 log.debug("Decoding string: " + cookieValue);
 }

 Base64 base64 = new Base64();
 byte[] encodedBytes = cookieValue.getBytes();
 byte[] decodedBytes = base64.decode(encodedBytes);
 String result = new String(decodedBytes);
 if (log.isDebugEnabled()) {
 log.debug("Decoded string to: " + result);
 }
 return result;
}

private String padString(String value) {
 int mod = value.length() % 4;
 if (mod <= 0) {
 return value;
 }
 int numEqs = 4 - mod;
 if (log.isDebugEnabled()) {
 log.debug("Padding value with " + numEqs + " = signs");
 }
 for (int i = 0; i < numEqs; i++) {
 value += "=";
 }
 return value;
}

JS部分:现在在JS中就可以按照正常方法读取了

 var encodedValue = this.base64.encode(value);
document.cookie = name + "=" + encodedValue +
 "; expires=" + this.expires.toGMTString() +
 "; path=" + this.path;

至此,基本解决问题。

关心JDK7中将会出现的NIO.2 File system的朋友。

分类:Java, 计算机与互联网 作者: 秋天 on 23-06-2009

标签分类 : , , , ,

关心JDK7中将会出现的NIO.2 File system的朋友。

http://java.sun.com/developer/technicalArticles/javase/nio/

JAVA 7 and JAVA EE 6 发布日期在本次Javaone公布

分类:IDE开发环境, Java, 服务器端技术, 计算机与互联网 作者: 秋天 on 11-06-2009

标签分类 : , , ,

根据Jim White从本次JAVAONE带回来的报道。新的Java 7 以及Java EE 6将分别于,2010年二月和2009年10月发布。

在本次JAVAONE中同时公布了一些新的JAVA 7和JAVA EE6将要支持的新特性,包括:

  1. modules (allowing you to customize the features of Java you need for your app and finally killing the classpath)
  2. null check operator/conditional - "?:"
  3. Strings in switches
  4. multiple exception catches in the catch block (using "")
  5. diamond operator to allow the generics to be more easily used.
    //For example...
    HashMap> map = new HashMap>();
    //becomes
    HashMap> map = new HashMap<>();

没有在本次JAVAONE公布但是有传言将会支持的新特性:

  1. closures
  2. SQL expression checking

新的JAVA EE 6将会有如下的主要变更:

  1. JAX-RS (support for RESTful web services)
  2. JSF 2.0
  3. Asynch servlets
  4. Bean validation (adding validation to JavaBeans that can be used to validate property data anytime they are used).
  5. Web.xml is gone (at least it can be gone) with the use of annotations and/or web.xml fragments.
  6. Web beans - essentially session beans in the WAR file.

    JAVA 7将会在今年9月份结束最后一个Milestone版本,该版本将会包括正式版JAVA 7中的所有新特性。而JAVA EE 6的最后一个Milestone版本将会在今年9月份发布。

    另外,Jim White在本次JAVAONE中带回的新消息还包括,Eclipse IDE的下一个版本“Eclipse Galileo”将会在六月24日发布,该版本会有非常大的变动,支持了Eclipse社区新增的33-48个新的projects。

    并且Spring会公布一个全新的项目“Spring Roo”。

    Some recent j2ee materials

    分类:Java, Web UI & Ajax, 服务器端技术, 程序设计, 计算机与互联网 作者: 秋天 on 19-03-2008

    标签分类 :

    最近太忙了,资料堆积了看不完,暂时在这里列举一下,有空了会补上。

    OK,暂时这些。情绪是一种比较烦人的东西,但你又不能没有。

    Two interest technical articles

    分类:Java 作者: 秋天 on 21-01-2008

    标签分类 : ,

    Agile tools for Agile development By Jack Vaughan from SearchSoftwareQuality.com

    and an old article about Migrating JDBC data access objects to use EJB3, kinda old but maybe will helpful later, save it here for sometime.

    Book:Java EE 5 Development using GlassFish

    分类:Java 作者: 秋天 on 21-01-2008

    标签分类 : ,

    This seems like a nice one. “Java EE 5 Development using GlassFish Application Server” written by David R. Heffelfinger has recently been published by Packt Publishing and is intended to guide developers “through the development and deployment of Java EE 5 compliant applications on GlassFish version 2″.

    The book assumes that the reader has experience of Java but no previous knowledge of Java EE or J2EE. As such, this is a great book for developers who are new to this arena.

    The book starts with an overview of what GlassFish is, what its competitors are and why we should use GlassFish. The introduction continues to provide details of how to download, install and verify GlassFish and finishes by exploring some of the management tasks associated with GlassFish such as managing domains, creating connection pools and configuring datasources.

    Several sections of the book cover web development, including chapters on Servlets, JSPs, the JSP standard tag library and JSF. These chapters take the reader from initial concepts such as “What is a servlet?” and gradually build up on their knowledge by describing how to build JSF applications.

    Database connectivity is covered in the book, however this assumes that the reader has some experience of SQL. The book starts by covering JDBC and how this can be used from within Java EE applications, and continues to discuss the Java Persistence API (JPA). This includes details on how to configure entity relationships with JPA, such as one-to-one and many-to-many relationships. After details and examples on how to use JPA, the reader is shown how to integrate JSF and JPA.

    Moving away from web development, the book describes the Java Message Service (JMS) and how queues and topics can be defined within GlassFish and then accessed via Java code. This is taken further in the section on enterprise beans where the book discusses Message Driven Beans and how they interact with the application server. This section on enterprise beans also includes details about session beans and discusses life cycles, transactions and security.

    Security is discussed in detail and explanations are provided regarding what security realms are within GlassFish and how they can be configured. Details are included about the file, certificate, LDAP, Solaris, JDBC and custom realms.

    The final aspect of Java EE discussed within the book is web services. This chapter discusses how to create, deploy and test JAX-WS web services and includes details on sending attachments from web service methods and securing web services.

    The final chapter of the book takes the reader beyond the Java EE standard and describes additional 3rd party technologies, namely Facelets, Ajax4jsf and Seam and describes how applications developed with these technologies can be deployed to GlassFish.

    This is a highly recommended book for developers who are new to Java EE 5 development and the GlassFish Application Server.

    More about this book. here

    Change or customize the Toolbars in FCKeditor

    分类:Java 作者: 秋天 on 08-09-2007

    标签分类 :

    Since March 13, 2007, the FCKeditor has supported the new method setCustomConfigurationsPath(String url) that you can specify the url of the custom configuration .js file. You do not need to modify the fckconfig.js inside the fckez.jar any more. Please see FCKeditor Configurations File for details on what can be customized.So here is the new way to create a new toolbar set for the FCKeditor.
    点击浏览文章的全部内容 »

    The FCK editor configuration file

    分类:Java 作者: 秋天 on 08-09-2007

    Configurations File

    The editor comes with a rich set of configurations that makes it possible to customize its appearance, features and behaviors. The main configuration file is named “fckconfig.js“.

    You can either edit the main configuration file or just override the stuff you want to change in a separate file. JavaScript syntax is used to configure FCKeditor.

     

    点击浏览文章的全部内容 »

    Some references of today

    分类:IDE开发环境, Java 作者: 秋天 on 17-08-2007

    How to Get the Best Performance Out of a Java Persistence Implementation by Rahul Biswas

    A nice article of teach you tuning the performance of Java Persistence with Glassfish.

    Simplifying EJB Development with EJB 3.0 by Debu Panda

    Quite a out of date article, but illustrated some of the main differences between EJB3 and 2.1

    LaLiLuna - Tutorials of JavaEE

    Most of tutorials here are about using eclipse, xDoclet under a JBOSS enviroenment.

    MyEclipse Educational Material

    Got lots of nice video and text tutorials about features of MyEclipse IDE

    PetShop Example on Glassfish by Carol McDonald

    Sample Application using JSF, Seam, and Java Persistence APIs on Glassfish

    After investaged in a period of time, we realized that there is no easy way that can make hibernate becomes a replacement of the traditional Glassfish JPA.

    Reasons are listed from:

    When can I use hibernate as EJB3 persistence provider in GlassFish by Sahoo

    and a post from Java forum here.

    As a result, instead of move on to the popular Spring+hibernate architecture, we decided to stay with the basic JavaEE5(EJB3 + Toplink) at the first.

    Installation Guide – Java™ BluePrints Solution Catalog

    分类:Java 作者: 秋天 on 08-08-2007

    The installation guide of catalog sample. Some of the configurations are
    nice to a Java EE newbiew, like me, *grins*

    点击浏览文章的全部内容 »

    ZK Rich Client Framework

    分类:Java 作者: 秋天 on 07-08-2007

    Allen せんせい read this article when you have time~

    ZK is what we are about to use as the front-end technology in our
    project. This article compares some of the current ajax frameworks, offers a
    comprehensive analyse and tutorial of this ajax framework.


    ZK rich client framework and agile development

    The new Apache Myfaces 1.20 – JSF 1.2

    分类:Java 作者: 秋天 on 07-08-2007

    MyFaces Core 1.2.x is a JavaServer(tm) Faces 1.2 implementation as
    specified by JSR-252. MyFaces Core has passed Sun’s JSR-252 TCK and is 100%
    compliant with the JSR-252 specification.

    examples of the new version can be acquired from here:

    http://www.irian.at/myfaces/home.jsf

    Project home here:

    http://myfaces.apache.org/

    Still cannot see anything new.

    WebCream 6.0 released – AJAX for Swing applications

    分类:Java 作者: 秋天 on 07-08-2007

    provides a natural migration path for Swing applications by providing automatic conversion to AJAX. Virtually without modifications the existing Swing based front end can be deployed as a thin client. Our product supports every standard Swing component by providing an AJAX version that runs in the browser.

    Amazing stuff, never know if it really works for myself. It is also a nice evidence that the traditional SWING based client-side application can be implemented by browser-based web application functionally.

    点击浏览文章的全部内容 »

    OC4J – The Other Oracle Application

    分类:Java, 数据库 作者: 秋天 on 30-09-2006

    转篇文章,蛮不错的,仔细的说明了oc4j的很多结构和使用上的问题。
    By Steve Callan, stevencallan@hotmail.com

    How does extensible markup language relate to the J2EE standalone version of Application Server? If "extensible markup language" sounds unfamiliar to you, perhaps you know it better by its acronym of XML. XML matters not to just to the J2EE version of Application Server, but to all versions. The manner in which XML matters is fairly significant: many configuration files are XML-based. If your DBA responsibilities include administering J2EE applications based upon Application Server, you face the learning hurdles of XML, Java and J2EE, how Oracle interfaces with Java (OC4J, more on that later), and Application Server itself. Chances are you have seen XML in action and may not have even noticed it. Oracle 10g's staging information uses a file named products.xml instead of products.jar.

    If coming from a Forms and Reports Services standalone background, the J2EE version will be somewhat familiar, but even within this "known" territory, there are many differences. For example, using true or false: all versions of Application Server are installed using Oracle Universal Installer, so all you ever need to look for in the "Disk 1" directory is the setup.exe (or runInstaller) executable? As we will see later on, the answer is false.

    点击浏览文章的全部内容 »

    Game of Life

    分类:Java 作者: 秋天 on 10-09-2006

    这个星期的作业,自己改写了个Game of life,加入了以下内容:

    * Changes:
    * 1: Add screen buffer which makes each dot paint faster.
    * 2: Rotate the shape, re-display from other side when off-screen.
    * 3: Synchronized arrowkeys.
    * 4: Removed some deprecated java method, the programe now can be compiled and run more smooth in a newer javac (ex. 1.5.7.06).
    * 5: Speed can be controlled from the drop down list.
    * 6: Change dot into circle.
    * 6: Some non-crossing shape are deleted.
    * 7: And some little modifications.
    * 8: Color changed

    放在这里:http://qiutian.occm.cn/resource/gameoflife/GameOfLife.html

    感兴趣的来看看,IE叫警告点允许就是,不会有不良内容~:) 觉得这个算法蛮有趣,算法部分才几行而已,就出现那么有趣的结果。

    
    新主题为IE6专设CSS