论坛首页 Java企业应用论坛

开源项目XWorker介绍。(增加了编码解码示例)

浏览 14275 次
精华帖 (1) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (5)
作者 正文
   发表时间:2012-01-16  
lgstarzkhl 写道
觉得还是思路上,定位问题?能不能用一句通俗点的话描述一下。
还有到你网站上源码为啥下载不了啊?


现在已经可以下载了。

目前的情况的确是如此的,让人一下子无法明白XWorker是做什么的,不过这种情况将会好转,不过还需要一个过程。

对于此种现实,我还是想吐槽一下的,以释放心中几年的闷气,如果真有上帝存在,我真想捅他两刀子(呵呵,玩笑)。

1. XWorker最重要的东西,在众人的眼中是最不值钱的东西,故没人关注也不知道它是什么,并且使用XWorker还真没必要知道。
    以前这方面我介绍太多了,也导致各种混乱,现在这部分介绍了少了,所以一切将会清晰。

2. 今后将主要介绍XWorker的编程开发,这些应该是比较容易懂的。
0 请登录后投票
   发表时间:2012-01-16  

有的时候在编程中需要一些很小的测试工具,比如定时向服务器发送http请求等。本示例演示使用Timer和Apache HttpClient(目前只集成了最基本的功能)。

 

编辑TimerTest的界面。

对应TimerTest的事物转换为XML表示如下:

<TimerTask period="5000" timer="xworker:java:test.util.ATimer" name="aTask">
    <actions name="actions">
        <Log message="Timer Task Run." name="doTimerTask"/>
    </actions>
</TimerTask>

 其中<log message... name="doTimerTask"/>是Timer的执行动作,打印一个Timer Task Run.日志,动作可以有Java、Groovy、Javascript等各种语言编写。

 

HttpClient测试的编辑界面:

HttpClient事物转换为XML标识为:

<HttpGet uri="&quot;http://cn.bing.com/&quot;" proxy="true" name="HttpGet">
    <actions name="actions">
        <EntityUtils name="toString" defaultCharset="utf-8">
            <Result condition="_return != null" name="Result">
                <Log message="结果:" varName="_return" name="Log"/>
            </Result>
        </EntityUtils>
    </actions>
</HttpGet>

 此代码访问cn.bing.com网站并把结果通过日志输出。

 

总结:

   使用XWorker可以编辑各种各样的小工具,并且使用这些小工具时都有编辑界面,可有效减少对要调用的API的不熟而不知道该怎么写的情况,比如HttpClient的测试里几乎就不需要了解Apache HttpClient的API了,并且通过以上方法调用HttpClient的资源释放等也不需要考虑了。

 

0 请登录后投票
   发表时间:2012-01-16   最后修改:2012-01-16
xworker 有过实际应用的项目吗?是完全基于xworker开发,还是只用xworker做一些小工具。
反正就是应用场景吧。
希望能看到lz实际应用的案例。

还有上面那个Timer httpClient的demo也没看明白,
ATimer的动作需要定义吗 ,你是如何定义的?
0 请登录后投票
   发表时间:2012-01-16  
mazzystar 写道
xworker 有过实际应用的项目吗?是完全基于xworker开发,还是只用xworker做一些小工具。
反正就是应用场景吧。
希望能看到lz实际应用的案例。

还有上面那个Timer httpClient的demo也没看明白,
ATimer的动作需要定义吗 ,你是如何定义的?



1. 关于XWorker的实际应用。
    实际应用是有的,比如XWorker的主页www.xworker.org和XWoker自身(从视频和示例里可以看到一些XWorker的情况)。

    是不是觉得有点怪怪的?XWorker自身怎么是使用XWorker开发的呢,但这就是XWorker的特别之处,希望慢慢的大家能够理解这一点。

  

2. 关于Timer和HttpClient的demo。

   

<TimerTask period="5000" timer="xworker:java:test.util.ATimer" name="aTask">
    <actions name="actions">
        <Log message="Timer Task Run." name="doTimerTask"/>
    </actions>
</TimerTask>

 

其中xworker:java:test.util.ATimer的作用是保持一个Timer的实例,它有一个getTimer方法。

 在这里TimerTask是反向注册到Timer中的,以上整个XML的TimerTask也是一个动作(程序),它的执行过程是:

 a. 通过timer="xworker:java:test.util.ATimer"获取java.util.Timer的实例。

 b. 根据自身的属性初始化一个java.util.TimerTask的实例并注册到Timer实例中,其中这个任务的run方法执行的是TimerTask的doTimerTask方法,就是<log ..../>那个。

 

3. 关于事物的动作。

    按照面向对象的思路来说,上面好像很混乱,比如<TimerTask.../>到底是对象还是方法(行为)呢?实际上它既是对象也是方法。

    XWorker的所谓面向事物中:事物和动作是统一的,即任何事物都是动作,任何动作都是使用事物表示的

    在客观物理世界中这好像很容易理解,物质和能量是统一的。

    其实在面向对象中也是如此的,比如对象的类Class也是一个对象,对象的方法Method也是一个对象,只不过这种说法好像比较少,不过想想看Java中的反射机制就知道把类、行为和属性也当作对象是多么重要。

0 请登录后投票
   发表时间:2012-01-16   最后修改:2012-01-16

那个demo明白了,还有你说的事物也大体明白了。
开发模式应该是颠覆性的,有实践会实践一下。

 

 

 

public static void main(String[] args) throws ClassNotFoundException {
		try {
			//初始化世界(World)的路径。
			World.getInstance().init("D:\\download\\xworker_alpha1.2\\alpha");
			//使用事物
			Thing worldExplorer = World.getInstance().getThing(
					"xworker:ui:worldExplorer.swt.WorldExplorerRunner");
			worldExplorer.doAction("run");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
 

 

运行时 弹出一个窗口卡在这里不动了


 

错误信息



2012-01-16 17:49:48,000 ERROR (xworker.ui.swt.util.SwtRunner:197) - run error
java.lang.ClassCastException: java.lang.String cannot be cast to org.eclipse.swt.widgets.Shell
	at xworker.ui.swt.util.SwtRunner$SwtRunnable$1$1.run(SwtRunner.java:178)
	at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
	at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134)
	at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3885)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3506)
	at xworker.ui.swt.util.SwtRunner$SwtRunnable.run(SwtRunner.java:207)
	at java.lang.Thread.run(Thread.java:662)
 

 

 

  • 大小: 37.9 KB
0 请登录后投票
   发表时间:2012-01-17  
mazzystar 写道

 

我需要完整的错误堆栈信息。

 

另外XWorker需要动态编译Java代码,需要使用JDK运行Exclipse,或者把JDK的rt.jar拷贝到alpha\lib目录下。一般还是使用jdk运行方便些。

0 请登录后投票
   发表时间:2012-01-17  
现在可以了 我重新建个项目 再运行我之前那个mian函数就好了。
0 请登录后投票
   发表时间:2012-01-18  



 数据对象的查询统计介绍

    该查询统计可以应付一般查询统计查询,支持各种数据对象的查询,如DbDataObject、CsvDataObject等。对复杂的查询,如多表的关联查询目前还不支持(可能要通过HibernateDataObject来做了)。

 

本示例说明

    本示例在使用Derby数据库(吐槽一下Derby没有类似to_char(date,xxx)和date_format()的函数么?),建立一个简单的表和测试数据,用于演示按条件按查询、聚合和分组等。

    使用数据对象查询的步骤是:

    1. 定义查询数据对象(查询定义也属于一种数据对象)。

    2. 定义查询条件,在查询条件里可以定义查询的操作符(>、=等)以及连接类型(and、or)和分组(父子事物等同括号等)。

    3. 在具体应用中使用。

1. 定义查询数据对象

    本示例的查询数据对象转化为XML后如下:

<DbQueryConfig showSql="true" label="订单查询" dataSource="xworker:app:examples.useradmin.datasource.UseradminDataSource" storeSortDir="ASC" tableName="TBLORDER" name="OrderQuery">
    <attribute type="int" fieldName="tid" key="true" label="标识" name="tid"/>
    <attribute fieldName="userName" label="订单用户" name="userName"/>
    <attribute fieldName="productName" label="产品" name="productName"/>
    <attribute type="int" fieldName="amount" label="数量" name="amount"/>
    <attribute type="float" fieldName="price" label="价格" name="price"/>
    <attribute type="date" fieldName="orderDate" label="日期" name="orderDate"/>
    <aggregate type="int" fieldName="count(*)" label="交易单数" name="orderCnt"/>
    <aggregate type="float" fieldName="sum(price)" label="总价格" name="totalPrice"/>
    <group fieldName="VARCHAR(orderDate)" label="日期" name="date"/>
    <group fieldName="productName" label="产品" name="productName"/>
</DbQueryConfig>

 

2. 定义查询条件

    查询条件事物转化为XML后表示如下:

<Condition label="OrderQueryCondition" name="OrderQueryCondition">
    <Condition dataName="productName" attributeName="productName" name="productName"/>
    <Condition operator="4" dataName="startOrderDate" attributeName="orderDate" name="startOrderDate"/>
    <Condition operator="5" dataName="endOrderDate" attributeName="orderDate" name="endOrderDate"/>
</Condition>

   productName是等于,startOrderDate是>=,endOrderDate是<=。

 

3. 查询表单的定义

    一般查询界面是有查询条件输入表单和查询结果组成的,查询表单定义是一个数据对象,用于在SWT或Extjs中生成表单。

    查询表单转化为XML表示为:

<AbstractDataObject label="OrderQueryForm" editCols="3" storeSortDir="ASC" name="OrderQueryForm">
    <attribute label="产品" inputtype="text" name="productName"/>
    <attribute type="date" label="开始日期" inputtype="datePick" name="startOrderDate"/>
    <attribute type="date" label="截至日期" inputtype="datePick" name="endOrderDate"/>
    <attribute colspan="1" label="统计" rowspan="1" inputtype="multSelect" name="aggregateColumns">
        <value name="orderCnt" value="orderCnt" label="交易单数"/>
        <value name="totalPrice" value="totalPrice" label="总价格"/>
    </attribute>
    <attribute colspan="1" label="分组" rowspan="1" inputtype="multSelect" name="groupColumns">
        <value name="date" value="date" label="日期"/>
        <value name="productName" value="productName" label="产品"/>
    </attribute>
</AbstractDataObject>

 

4. 编辑SWT查询界面和运行效果

   SWT的查询界面事物转换为XML表示如下:

<Shell height="400" text="订单查询" width="650" name="shell" RESIZE="true">
    <FillLayout name="shellFillLayout"/>
    <DataObjectEditCompoiste queryDataObject="xworker:app:examples.useradmin.order.OrderQueryForm" deleteButton="false" editButton="false" newButton="false" queryConfig="xworker:app:examples.useradmin.order.OrderQueryCondition" name="queryComposite" dataObject="xworker:app:examples.useradmin.order.OrderQuery"/>
</Shell>

    运行结果见附图。

   

 

 

5. 编辑Extjs查询界面和运行效果

   Extjs的查询界面事物转换为XML表示如下:

<SimpleControl name="test">
    <view title="订单查询" name="view">
        <ExtJs>
            <Viewport renderTo="document.body" varname="viewPort" id="&apos;viewPord&apos;" layout="&apos;border&apos;">
                <items>
                    <DataObjectFormPanel split="true" region="&apos;north&apos;" df_dataObject="xworker:app:examples.useradmin.order.OrderQueryForm" title="&apos;查询条件&apos;" df_editorType="query" height="125" id="&apos;formPanel&apos;" df_column="3">
                        <buttons>
                            <Button text="&apos;查询&apos;">
                                <function name="handler" code="var form = Ext.getCmp(&apos;formPanel&apos;).getForm();
var store = Ext.StoreMgr.get(&apos;grid_store&apos;);
store.load({params:form.getValues()});"/>
                            </Button>
                        </buttons>
                    </DataObjectFormPanel>
                    <DataObjectGridPanel varname="grid" split="true" region="&apos;center&apos;" dobj_condition="xworker:app:examples.useradmin.order.OrderQueryCondition" height="400" dataObject="xworker:app:examples.useradmin.order.OrderQuery" id="&apos;grid&apos;"/>
                </items>
            </Viewport>
        </ExtJs>
    </view>
    <result name="success" value="xworker:app:examples.useradmin.order.OrderQueryExtjs:/@test/@view"/>
</SimpleControl>

 查询结果见附图。


 

6. 总结

    以上贴出的XML是编写SWT和Extjs查询的全部代码(包括界面本身),可以看到在XWorker中编写简单的SWT查询和Extjs的代码是非常简洁的,只需要少量的配置就可以编写出一个查询界面。

    其实在XWorker中越高阶的事物越是简洁和容易被使用,这也是将来XWorker可以让普通人使用它开发程序有了可能性。

    另外XWorker的数据对象才刚刚成型,还有许多bug和要完善的,这正是希望能够开发人员参与的原因之一。

 


 

 

 

  • 大小: 57 KB
  • 大小: 54.8 KB
0 请登录后投票
   发表时间:2012-01-29   最后修改:2012-01-29

  编码和解码的示例

 

编码和解码模块式春节里做的一个模块,这个示例的目的是想让大家看一下如何在XWorker中创建和使用框架程序。

 

编码和解码的主要用途是用于网络传输,比如网络棋牌游戏的服务器和客户端数据交互协议,使用编码和解码模块能够快速定义网络协议。

 

1. 创建编码和解码的框架。

   a. 创建主要的事物Coder(相当于Java中的基类),Coder转化为XML大概如下:

<thing name="Coder" label="Coder" descriptors="xworker:core:things.lang.MetaDescriptor3">
    <actions name="actions">
        <GroovyAction name="encode" code="..." /> <!-- 方法-编码-->
        <GroovyAction name="decode" code="..."/> <!-- 方法-解码-->
        <NOOP name="newInstance"/> <!--方法-创建实例,解码时用,NOOP是没有操作的动作,需要子事物实现-->
        <GroovyAction name="startEncode" code="..." ><!-- 方法-开始编码,调用的入口 -->
            <ins>
                <param name="data"/>
            </ins>
        </GroovyAction>
        <GroovyAction  name="startDecode" code="..."><!--方法-开始解码,调用的入口 -->
            <ins>
                <param name="buffer"/>
            </ins>
        </GroovyAction>
    </actions>
    <attribute name="name"/>
    <attribute name="label"/>
    <attribute description="&lt;p&gt;属性路径,使用Ognl从dataSource中取。&lt;/p&gt;" name="propertyPath"/>
    <attribute inputtype="html" name="description" colspan="2"/>
    <attribute description="&lt;p&gt;编码时初始化buffer的大小。&lt;/p&gt;" name="capacity" default="1024" group="encode"/>
    <attribute inputtype="truefalse" description="&lt;p&gt;&lt;font face=&quot;Courier New&quot;&gt;true&lt;/font&gt; to get a direct buffer, &lt;tt&gt;false&lt;/tt&gt; to get a heap buffer.&lt;/p&gt;" name="direct" default="false" group="encode"/>
    <attribute inputtype="truefalse" name="autoExpand" default="true" group="encode"/>
    <attribute inputtype="select" description="&lt;p&gt;编码后的输出类型。&lt;/p&gt;" name="encodeReturnType" default="IoBuffer" group="encode">
        <value name="IoBuffer" value="IoBuffer" label="IoBuffer"/>
        <value name="byte[]" value="byte[]" label="byte[]"/>
    </attribute>
</thing>
 

 

    b. 创建具体的编码类型,如:IntCoder、DoubleCoder、MapCoder等。

   MapCoder事物的转化为XML后大概如下:MapCoder集成Coder,Coders的目的是让MapCoder也有各种Coder的子列表,在编辑时可以添加各种Coder子事物。

 

<thing extends="xworker:codec:Coder,xworker:codec:Coders" description="&lt;p&gt;解码时生成一个HashMap。&lt;/p&gt;" name="MapCoder" label="MapCoder" descriptors="xworker:core:things.lang.MetaDescriptor3">
    <actions name="actions">
        <ObjectFactory name="newInstance" className="java.util.HashMap"/>
    </actions>
</thing>

 

 IntCoder事物转化为XML后大概如下:

    <thing extends="xworker:codec:Coder" name="IntCoder" label="IntCoder" descriptors="xworker:core:things.lang.MetaDescriptor3">

    <actions name="actions">
        <GroovyAction code="import org.xworker.util.UtilData;
buffer.putInt((int) (UtilData.getInt(data, 0) &amp; 0xFFFFFFFF));" name="encode"/><!-- 方法:编码-->
        <GroovyAction code="return buffer.getInt();" name="decode"/><!--方法:解码-->
    </actions>
</thing>

    c. 创建Coders事物,比如MapCoder可以有各种子Coder子节点的,其他Coder也可能有这样的子节点,如ObjectCoder,把各种Coder放到Coders的子节点下,MapCoder继承Coders就可以在编辑器里快速添加其他Coder子事物了。

    Coders转化为XML的代码大概如下:

 

<thing description="&lt;p&gt;Codec的作用是把数据编码成byte[],把byte[]解码成数据。&lt;/p&gt;
&lt;p&gt;编码和解码过程中的临时变量有,data(数据)、buffer(Mina IoBuffer)。&lt;/p&gt;" name="Datas" label="Datas" descriptors="xworker:core:things.lang.MetaDescriptor3">
    <thing extends="xworker:codec:collection.ArrayCoder" name="ArrayCoder" descriptors="xworker:core:things.lang.MetaDescriptor3:/@thing" group="collection" inheritDescription="true"/>
    <thing extends="xworker:codec:collection.ListCoder" name="ListCoder" descriptors="xworker:core:things.lang.MetaDescriptor3:/@thing" group="collection" inheritDescription="true"/>
    <thing extends="xworker:codec:collection.MapCoder" name="MapCoder" descriptors="xworker:core:things.lang.MetaDescriptor3:/@thing" group="collection" inheritDescription="true"/>
    <thing extends="xworker:codec:collection.ObjectCoder" name="ObjectCoder" descriptors="xworker:core:things.lang.MetaDescriptor3:/@thing" group="collection" inheritDescription="true"/>
    <thing extends="xworker:codec:attribute.ByteCoder" name="ByteCoder" descriptors="xworker:core:things.lang.MetaDescriptor3:/@thing" group="attribute" inheritDescription="true"/>
    <thing extends="xworker:codec:attribute.ShortCoder" name="ShortCoder" descriptors="xworker:core:things.lang.MetaDescriptor3:/@thing" group="attribute" inheritDescription="true"/>
    <thing extends="xworker:codec:attribute.IntCoder" name="IntCoder" descriptors="xworker:core:things.lang.MetaDescriptor3:/@thing" group="attribute" inheritDescription="true"/>
    <thing extends="xworker:codec:attribute.LongCoder" name="LongCoder" descriptors="xworker:core:things.lang.MetaDescriptor3:/@thing" group="attribute" inheritDescription="true"/>
    <thing extends="xworker:codec:attribute.FloatCoder" name="FloatCoder" descriptors="xworker:core:things.lang.MetaDescriptor3:/@thing" group="attribute" inheritDescription="true"/>
    <thing extends="xworker:codec:attribute.DoubleCoder" name="DoubleCoder" descriptors="xworker:core:things.lang.MetaDescriptor3:/@thing" group="attribute" inheritDescription="true"/>
    <thing extends="xworker:codec:attribute.CharCoder" name="CharCoder" descriptors="xworker:core:things.lang.MetaDescriptor3:/@thing" group="attribute" inheritDescription="true"/>
    <thing extends="xworker:codec:attribute.StringCoder" name="StringCoder" descriptors="xworker:core:things.lang.MetaDescriptor3:/@thing" group="attribute" inheritDescription="true"/>
    <thing extends="xworker:codec:control.If" name="If" descriptors="xworker:core:things.lang.MetaDescriptor3:/@thing" group="control" inheritDescription="true"/>
</thing>

 

 

2. 使用编码和解码框架

   a. 使用Coder框架定义一个编码解码协议。

    比如测试用的编码解码协议如下:

 

<MapCoder encodeReturnType="byte[]" name="TestCoder" label="TestCoder">
    <ByteCoder propertyPath="byteValue" name="byte"/>
    <CharCoder propertyPath="charValue" name="CharCoder"/>
    <DoubleCoder propertyPath="doubleValue" name="DoubleCoder"/>
    <FloatCoder propertyPath="floatValue" name="FloatCoder"/>
    <IntCoder propertyPath="intValue" name="IntCoder"/>
    <LongCoder propertyPath="longValue" name="LongCoder"/>
    <ShortCoder propertyPath="shortValue" name="ShortCoder"/>
    <StringCoder propertyPath="stringValue" name="StringCoder"/>
    <ArrayCoder propertyPath="arrayValue" name="ArrayCoder" sizeType="byte">
        <MapCoder name="MapCoder">
            <StringCoder propertyPath="stringValue" name="StringCoder"/>
        </MapCoder>
    </ArrayCoder>
    <ObjectCoder propertyPath="objectValue" name="ObjectCoder" className="org.xworker.Thing">
        <StringCoder propertyPath="name" name="name"/>
        <StringCoder propertyPath="descriptors" name="descriptors"/>
        <StringCoder propertyPath="extends" name="extends"/>
    </ObjectCoder>
    <If condition="data.byteValue &gt; 0 &amp;&amp; data.byteValue &lt; 10" name="if">
        <StringCoder propertyPath="str1" name="str1"/>
        <ELSEIF condition="data.byteValue &gt;= 10 &amp;&amp; data.byteValue &lt;20" name="elseIf">
            <StringCoder propertyPath="str2" name="str2"/>
        </ELSEIF>
        <ELSE name="else">
            <StringCoder propertyPath="str3" name="str3"/>
        </ELSE>
    </If>
</MapCoder>

 

 

    b. 编写编码和解码的测试程序。

 

<thing name="TestCoderTest" label="TestCoderTest" descriptors="xworker:core:things.lang.MetaDescriptor3">
    <actions name="actions">
        <GroovyAction code="return [&quot;byteValue&quot;:1, &quot;shortValue&quot;:2323, &quot;intValue&quot;:1223434, 
        &quot;longValue&quot;:34343333, &quot;charValue&quot;:3434, &quot;floatValue&quot;:2.34334, &quot;doubleValue&quot;:34343.544545,
        &quot;stringValue&quot;:&quot;hello world! 你好&quot;, 
        &quot;arrayValue&quot;:[
            [&quot;stringValue&quot;:&quot;hello&quot;],[&quot;stringValue&quot;:&quot;hello1&quot;]
        ],
        &quot;objectValue&quot;:world.getThing(&quot;xworker:codec:test.TestCoder&quot;),
        &quot;str1&quot;:&quot;IF条件&quot;, &quot;str2&quot;:&quot;ELSE条件&quot;, &quot;str3&quot;:&quot;ESLE条件&quot;];" name="testEncode">
            <Result condition="_return != null" name="Result">
                <Encode inputVarName="_return" varScope="xworker:codec:test.TestCoderTest:/@actions/@testEncode" outputVarName="output" name="encode" codecPath="&quot;xworker:codec:test.TestCoder&quot;"/>
                <EncodeHexString lowerCase="true" inputVarName="output" varScope="xworker:codec:test.TestCoderTest:/@actions/@testEncode" outputVarName="hexString" name="toHexString"/>
                <Log message="the output hexstring is:" varName="hexString" name="logHexString"/>
            </Result>
        </GroovyAction>
        <GroovyAction code="return &quot;010d6a40e0c4f16ce9a2c64015f9480012ab0a00000000020c09a50913001168656c6c6f20776f726c642120c4e3bac302000568656c6c6f000668656c6c6f31000954657374436f646572002178776f726b65723a636f6465633a636f6c6c656374696f6e2e4d6170436f646572000000064946ccf5bcfe&quot;;" name="testDecode">
            <Result condition="_return != null" name="Result">
                <DecodeHexString outputVarName="output" name="decodeHexString" inputVarName="_return" varScope="xworker:codec:test.TestCoderTest:/@actions/@testDecode"/>
                <Decode inputVarName="output" varScope="xworker:codec:test.TestCoderTest:/@actions/@testDecode" outputVarName="data" name="decode" codecPath="&quot;xworker:codec:test.TestCoder&quot;"/>
                <Log message="the output hexstring is:" varName="data" name="logHexString"/>
            </Result>
        </GroovyAction>
    </actions>
</thing>

    在这个测试程序里,把一个Map编码成byte[]然后转化成16进制字符串并通过日志打印出来,解码过程正好相反,把一个16进制字符串转化成byte[],然后解码后打印出来。

 

3. 总结

    无。

 

0 请登录后投票
   发表时间:2012-02-07  
楼主介绍的这个东西我实在是没看明白,不过不管东西好坏,这种坚持的精神是值得学习鼓励的。持续关注,期望能通俗易懂一些。毕竟不是每个人都有你那种哲学思维的头脑的。。。。。。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics