成就梦想

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  21 随笔 :: 22 文章 :: 6 评论 :: 0 Trackbacks

2012年4月18日 #

     摘要: 世界邦超级自由行,广募天下英雄豪杰 如果你想找的不仅仅是一个工作机会,不仅仅是一份薪水,而是一个共同为之奋斗的事业,如果你偏偏对旅行又情有独钟,从内心地热爱旅行,并拥有创业的激情,那么世界邦会是你不二的最佳选择。   一、旅游产品销售 (电话销售)  职位职责: 1、通过电话与客户进行有效沟通了解客户需求, 寻找销售机会; 2、对...  阅读全文
posted @ 2014-05-22 11:02 iamct 阅读(272) | 评论 (0)编辑 收藏

高工资后面意味着高能力,高付出,高责任感,高压力,高考核,高绩效。高产出
posted @ 2012-11-06 13:19 iamct 阅读(364) | 评论 (0)编辑 收藏

        web应用集成测试的时候,各位还需要启动web容器,然后打开浏览器,输入ulr,然后看到浏览器的输出吗?

下面我们用maven做到自动化!


 

我们利用maven的生命周期和jetty插件来实现。

 

下面描述下做的自动化web集成测试实现的原理。

1,在生命周期pre-integration-test启动jetty容器

2,在生命周期integration-test中测试我们写的***IT.java类

3,在post-integration-test shutdow jetty容器。

在pom.xml中加入代码如下:

<profiles>
        
<profile>
            
<id>ittest</id>
            
<build>
                
<plugins>
                    
<plugin>
                        
<groupId>org.apache.maven.plugins</groupId>
                        
<artifactId>maven-surefire-plugin</artifactId>
                        
<executions>
                            
<execution>
                                
<id>run-integration-test</id>
                                
<phase>integration-test</phase>
                                
<goals>
                                    
<goal>test</goal>
                                
</goals>
                                
<configuration>
                                    
<includes>
                                        
<include>**/*IT.java</include>
                                    </includes>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                    <plugin>
                        <groupId>org.mortbay.jetty</groupId>
                        <artifactId>maven-jetty-plugin</artifactId>
                        <version>6.1.26</version>
                        <configuration>
                            <contextPath>/</contextPath>
                            <stopPort>9966</stopPort>
                            <stopKey>stop-jetty-for-it</stopKey>
                            <connectors>
                                <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
                                    <port>6211</port>
                                </connector>
                            </connectors>
                        </configuration>

                        <executions>
                            <execution>
                                <id>start-it-jetty</id>
                                <phase>pre-integration-test</phase>
                                <goals>
                                    <goal>run</goal>
                                </goals>
                                <configuration>
                                    <daemon>true</daemon>
                                </configuration>
                            </execution>
                            <execution>
                                <id>stop-it-jetty</id>
                                <phase>post-integration-test</phase>
                                <goals>
                                    <goal>stop</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

 

然后就可以编写测试用例了

 

 步骤如下:

1,定义一个以此命名的****IT的测试类(integration test缩写), 在里面华丽的写好你的测试逻辑。

再此不举例了,主要一个思路可以用httpclint来实现里面的测试代码。

2,然后 执行 mvn clean post-integration-test -Pittest

好了 就可以看到我们测试用例是否通过。

建议:以上的代码可以加入到父类的pom中,以后继承此父pom后,只需要按以上2步,就可以做到web应用测试自动化了。

 



posted @ 2012-04-21 11:57 iamct 阅读(3089) | 评论 (0)编辑 收藏

     摘要: 在linux服务器上,因为gui显示的问题。我们直接jconsole时。就会报Exception in thread "AWT-EventQueue-0" java.awt.HeadlessException: No X11 DISPLAY variable was set, but this program performed an operation which requires it.&nb...  阅读全文
posted @ 2012-04-18 13:30 iamct 阅读(6860) | 评论 (3)编辑 收藏

    我们部门底层的web应用有一套处理编码的流程机制,主要处理因历史原因或者跨部门产品之间gbk和utf8剪不清理还乱的关系。
前2天同事有询问相关编码的问题,在此做个整理,希望能够对大家有所帮助。

首先是编码的历史,这是一个很有意思的解读 。写的很幽默,便于理解。

下面主要写于与java想关的编码,主要解读unicode ,utf8 和gbk。

JVM里面的任何字符串资源都是Unicode,就是说,任何String类型的数据都是Unicode编码。没有例外,因此我们可以这么说,JVM里面的String是不带编码的。因为他就有且只对应一种Unicode。
一个字符的Unicode编码是确定的。也就是说Unicode是一种字符集,里面字符与编码是一一对应的,这里有个码表可查,unicode 码表。但是在实际传输过程中,由于不同系统平台的设计不一定一致,以及出于节省空间的目的,对Unicode编码的实现方式有所不同。Unicode的实现方式称为Unicode转换格式(Unicode Transformation Format,简称为UTF)。我们常用的就是UTF8.
UTF8是如何存储一个Unicode编码的呢。也就是utf8作为一种Unicode Transformation Format是如何工作的呢?
首先utf8 是可变长的,UTF-8使用一至四个字节为每个字符编码。参照下表,我们把精力放在第1列,第3列,和注释。
对于ASCII字符,可以用七个bit位来表示,x6 x5 x4 x3 x2 x1 x0.第八个bit永远是0。
第128到2047个字节,要用10个bit来表示,110yyyyy(C0-DF) 10zzzzzz(80-BF)
第2048到65535个字节,要用16个bit来表示,Utf-8把这些字节编成下面这样的三个byte。1110xxxx(E0-EF) 10yyyyyy 10zzzzzz
大于65535其余用4个byte来表示。

举个例子:“中国”的中,unicode编码是“\u4e2d", 对应的编码除了查表,java可以用命令行,运行 native2ascii 进行转化。
用window 自带的附件中的计算器(查看->科学型),转化成10进制为20013,二进制是100111000101101 
通过上面的表,可知,转化成utf8后为三个字节。
只需要将刚才转化的二进制(上面标红的)将下面的xxxx,yyyyyy,zzzzzz补齐即可。
1110xxxx(E0-EF) 10yyyyyy 10zzzzzz,我们从低位开始补起,不够的用0补齐。
11100100 10111000 10101101  ,换成16进制为E4 B8 AD。
好了我们用java代码来验证下,是否正确。
public static void main(String[] args) {
        String ha 
= "";
        
byte b[] = null;
        
try {
            b 
= ha.getBytes("utf-8");
        } 
catch (Exception e) {
            System.exit(
-1);
        }

        
for (int i = 0; i < b.length; i++) {
            System.out.print(Integer.toHexString(b[i]).substring(
6+ " ");
        }

    }
输出果然是:e4  b8 ad。
utf8 wiki中有下描述:
  • 对于UTF-8编码中的任意字节B,如果B的第一位为0,则B为ASCII码,并且B独立的表示一个字符;
  • 如果B的第一位为1,第二位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的一个字节,并且不为字符的第一个字节编码;
  • 如果B的前两位为1,第三位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由两个字节表示;
  • 如果B的前三位为1,第四位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由三个字节表示;
  • 如果B的前四位为1,第五位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由四个字节表示;

因此,对UTF-8编码中的任意字节,根据第一位,可判断是否为ASCII字符;根据前二位,可判断该字节是否为一个字符编码的第一个字节; 根据前四位(如果前两位均为1),可确定该字节为字符编码的第一个字节,并且可判断对应的字符由几个字节表示;根据前五位(如果前四位为1),可判断编码 是否有错误或数据传输过程中是否有错误。


反过来,我们还是拿刚才的”中“为例,11100100 10111000 10101101 ,第一个字节开始为110,则读第二个字节为10,第三个字节为10,则认为是utf8字符。
于是就有了一个那个经典的“联通"干不过”移动“的经典段子。
我们在xp下,随便建立一个文件,输入"联通",保存,这时你在打开是,发现”联通"2个字符不见了。奇怪吗??????
我们知道默认保存的编码是ANSI,实际也是类GBK的编码。
对应16进制为c1 aa cd a8, 转化成二进制为11000001 10101010 11001101 10101000 ,我们来看,110xxxxx,10xxxxxx 正好符合utf8的形式。
这时候文件编写器以为你的文件是utf8的文件,然后默认已utf8的形式给你打开展示。于是就出现乱码了。如果你在”联通“后面随便加几个字符。就不出出现灵异事件了。

那么我们继续讨论 GBK和Unicode是什么关系呢?
实际上GBK我们可以看做是字符集,他也有自己一一对应的码表。google一下,很容易查到。这里有个Unicode和GBk对应的表Unicode-GBk
在java中,
"我爱你莎莎".getBytes("gbk");
进行转化,其实就是类似查一个Unicode和GBk对应表进行转化的。大家看一下Charset这个抽象类的那些子类就明白了。
通过上面的描述GBk和UTF8关系也就很明朗了,完全可以通过Unicode进行中转。

同事在询问编码的问题时,一开始对类似如下代码,相互转变不太理解。
byte b1[] = null;
        b1 = "我爱你莎莎".getBytes("gbk");
        System.out.println(new String(b1,"gbk"));
        byte b2[] = null;
        b2 = "我爱你莎莎".getBytes("utf8");
        System.out.println(new String(b2,"utf8"));
        System.out.println(new String (new String (b2,"gbk").getBytes("gbk"),"utf8"));
其实我们可以把getBytes("gbk"),这个函数当做将unicode用gkb加密的过程,而new String(”xxx“,"编码”)看成是解密的一个过程。

大家思考一下最后面的那个输出可以得到正确的结果吗?为什么?

下面我们来讨论 ,通过http协议下的url传输后,编码转化问题。
首先说明的是本人本地默认编码是gbk。
我们只用Servlet,不使用任何框架比如spring(因为使用框架时,框架也有一套自己自己的机制)如下代码
public class HttpEncode extends HttpServlet {
    @Override
    
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String str 
= req.getQueryString();
        System.out.println(req.getCharacterEncoding());

        String encode 
= null;
        
try {
            encode 
= req.getParameter("encode");
        } 
catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println(str);
        System.out.println(encode);

    }

}
我们分别用jetty(版本6.1)和resin(版本3.1.8)下容器,测试如下请求     127.0.0.1/test?encode=%B9%FE  其中%B9%FE为GBk的编码的汉字”哈“
jetty容器下输出为
null
encode=%B9%FE
?
resin下为:
null
encode=%B9%FE
null

换做127.0.0.1/test?encode=%E5%93%88   ,utf8编码的”哈“
jetty和resin下都输出如下
null
encode=%E5%93%88

为什么会是这样?
我们拿jetty分析,在jetty的源码中,
   public String getParameter(String name)
    {
        
if (!_paramsExtracted) 
            extractParameters();
        
return (String) _parameters.getValue(name, 0);
    }

对应的
extractParameters(); 部分代码
 if (_queryEncoding==null)
                _uri.decodeQueryTo(_baseParameters);
         
然后
   public void decodeQueryTo(MultiMap parameters)
    {
        if (_query==_fragment)
            return;
        _utf8b.reset();
        UrlEncoded.decodeUtf8To(_raw,_query+1,_fragment-_query-1,parameters,_utf8b);
    }






也就是如果_queryEncoding为null时,默认是用utf8进行解码的。而resin也不例外。
jetty中_queryEncoding的值可以通过org.mortbay.jetty.Request.queryEncoding 这个属性给赋值而resin采用的是req.getCharacterEncoding()中的值为标准。
要想在jetty下 127.0.0.1/test?encode=%B9%FE,获取到正确的字符,代码如下
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String str 
= req.getQueryString();
        System.out.println(req.getCharacterEncoding());
        req.setAttribute(
"org.mortbay.jetty.Request.queryEncoding""gbk");
        String encode 
= null;
        
try {
            encode 
= req.getParameter("encode");
        } 
catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println(str);
        System.out.println(encode);

    }

resin下只需要
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String str 
= req.getQueryString();
        req.setCharacterEncoding(
"gbk");
        System.out.println(req.getCharacterEncoding());
        String encode 
= null;
        
try {
            encode 
= req.getParameter("encode");
        } 
catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println(str);
        System.out.println(encode);

    }

通过上面想说明的是,不同的容器,默认编码的策略是不一致的。只要我们了解编码的基础知识。通过一些封装就很容易掌控这个局面。





参考资料:
Unicode wiki:   http://zh.wikipedia.org/wiki/Unicode
jetty 源码
posted @ 2012-04-18 11:38 iamct 阅读(1699) | 评论 (0)编辑 收藏