使用Fireworks CS4中的切片输出功能,进行设计图形到CSS+DIV的转换。

分类:Web UI & Ajax, 多媒体技术, 网页&平面设计, 计算机与互联网 作者: 秋天 on 06-01-2010

下面这两篇文章进行了比较详细的讨论。 共享一下:

via Exporting CSS and images in Fireworks CS4. by. John Wylie

and

via Creating standards-compliant web designs with Fireworks CS4 by. Matt Stow

我个人对此功能进行测试后的一些看法。

  • 相比PS中原来的切片生成基于表格的html的功能,此功能是个长足的进步。
  • 虽然切片生成的代码仍然具有不少问题,但是以此作为一个起点,并在此基础上使用Dreamweaver进行代码微调,会大幅度的节省工作时间提高效率。
  • HTML切片对文本段落字体样式等的识别还比较弱,基本不可能拿来做为直接生产使用。对于该部分,切片留出位置,转换之后在Dreamweaver或者其他HTML编辑器中重新建立需要的文本字样段落样式。这一点上其实问题并不大,因为按照比较严格的设计标准来说,字体段落样式 (Typography) 部分,和图形分别设计本来也是设计流程的一部分。
  • 我们比较需要的其实是一种比较好的图形切片到CSS+DIV的转换。在这一点上Fireworks CS4其实已经做的比较好了。我测试了几种比较复杂的堆叠方式,只有在一些特别复杂的情况下,会产生堆叠错乱,以及间隙错乱的问题,大部分基本的图形设计模式切片,都没有太大的问题。
  • 完美的生成DIV堆叠,并且CSS化DIV的属性。可惜的是转化的过程中并没有给我们提供足够的参数进行CSS属性控制的选择,或者HTML控件的CSS class id设置。希望将来的版本能在这一点上进一步优化。

and oh anyway, happy new year everyone.

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;

至此,基本解决问题。

关于Icefaces的Facelet模式中使用Cookies

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

标签分类 : , , , ,

传统的JSF中读取和写入Cookie的方式是这样子的:

  // create cookies
  HttpServletResponse httpServletResponse =
   (HttpServletResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse();
  Cookie cookie = new Cookie("cookieKey", "cookieValue");
  cookie.setMaxAge(365);
  cookie.setComment("A Comment");
  httpServletResponse.addCookie(cookie);  

  // get cookies
  HttpServletRequest httpServletRequest =
   (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
  Cookie[] cookies = httpServletRequest.getCookies();
  if (cookies != null) {
   for(int i=0; i<cookies.length; i++){
    if (cookies[i].getName().equalsIgnoreCase("cookieKey")){
     String cookieValue = cookies[i].getValue();
    }
   }
  }

在Iceface 1.5以后的版本中,由于在整个生命周期中没有直接定义request和response类,以上方法不适用。

所以在Icefaces中使用cookies的方法如下:


((BridgeExternalContext) FacesContext.getCurrentInstance()
                          .getExternalContext()).addCookie(new Cookie("test", "test"));

将FacesContext的External instance强制转换成为Icefaces自己的BridgeExternalContext,然后再使用.addCookie方法就能正常的添加Cookie了,读取的时候也是一样的:


Cookies[] cookies = ((HttpServletRequest)((BridgeExternalContext)FacesContext
                       .getCurrentInstance().getExternalContext()).getRequest()).getCookies();

以上内容在Icefaces WIKI中有提到,我没有好好看WIKI,浪费了好几个小时在这里。

Javascript 字体大小动态调整解决方案

分类:Web UI & Ajax, 网页&平面设计, 计算机与互联网 作者: 秋天 on 08-04-2009

关于这个问题,我的解决方案如下:

JAVASCRIPT部分:

var prefsLoaded = false;
var defaultFontSize =100;
var currentFontSize = defaultFontSize;

function revertStyles(){

currentFontSize = defaultFontSize;
changeFontSize(0);

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

More about javascript font re-size or text size detection

分类:Web UI & Ajax, 网页&平面设计, 计算机与互联网 作者: 秋天 on 08-04-2009

关于javascript控制网页字体大小,更多的高级控制,检测当前字体大小的问题,在a List a Part的这篇文章中讲到

并且包含了实现方案,例子,讲解和源代码。

通过以上方案可以让用户对字体进行更多的控制。

Javascript resize font-size em FF IE

分类:Web UI & Ajax, 网页&平面设计 作者: 秋天 on 08-04-2009

标签分类 : , , , ,

通过JS来控制网页字体,全局用em定制。就能在网页需要的地方,明显位置放置一个字体大小控制按钮。能增长的地方用em控制,定大的地方用pt or px。

据说现在主流浏览器都已经支持全局缩放 (具体看这里),就是放大整个screen而不仅仅是字体,但是由于还是需要照顾那30%的IE6 或者低版本Safari Opera用户,所以仍然需要用到。并且,具体用JS如何实现全屏缩放,暂时没找到实现方案。

在em设计的具体运用中,IE7 和 FF在自身缩放上又会有一些个bug,后文有引用别人的描述和解决方案。

clagnut.com 这家伙说的:

Text for the screen is sized with CSS in terms of pixels, ems or keywords. As most of us know, sizing with pixels is easy: get your selector and give it a font-size – no more thought required. Sizing with keywords is more complicated and requires a few workarounds, but you’re in luck as the techniques are well documented. That leaves ems. At this point people often leg it. ‘Ems are too inconsistent,’ they say, ‘they’re too hard; they never work.’ Well that may be the received wisdom, but if ever the was a case of FUD then this is it. I will now attempt to show you how ems can be as quick and easy to use as pixels. 点击浏览文章的全部内容 »

Some recent j2ee materials

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

标签分类 :

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

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


如果你喜欢本站,请加入你的收藏夹以便随时回来