最近测试OMADM1.2的时候,039,040两个case是关于TLS SSL的,搞的很迷惑,最近看了一下原来TLS几乎就是SSL,基本上一摸一样而已。
Sun.com上面看到
SSL was developed by Netscape in 1994, and with input from the Internet community, has evolved to become a standard. It is now under the control of the international standards organization, the Internet Engineering Task Force (IETF). The IETF has renamed SSL to Transport Layer Security (TLS), and released the first specification, version 1.0, in January 1999. TLS 1.0 is a modest upgrade to the most recent version of SSL, version 3.0. The differences between SSL 3.0 and TLS 1.0 are minor.
所以这2个case基本上测试一个就足够了。
另外tls本来就是传输层上的一个协议,所以要是用HTTPS的话,如果你用应用服务器,比如TOMCAT WBLOGIC,他们都支持SSL,根本不需要程序实现任何东西,只要你会使用keytool生成证书就可以了。
这块只是牵扯到JSSE,具体可以到http://java.sun.com/j2se/1.4.2/docs/guide/security/jsse/JSSERefGuide.html#Introduction看
Keytool其实再JRE/LIB/SECUTITY下面的包里面,
C:\j2sdk1.4.2_05\jre\lib\security>keytool
keytool 用法:
-certreq [-v] [-alias <alias>] [-sigalg <sigalg>]
[-file <csr_file>] [-keypass <keypass>]
[-keystore <keystore>] [-storepass <storepass>]
[-storetype <storetype>] [-provider <provider_class_name>] ...
-delete [-v] -alias <alias>
[-keystore <keystore>] [-storepass <storepass>]
[-storetype <storetype>] [-provider <provider_class_name>] ...
-export [-v] [-rfc] [-alias <alias>] [-file <cert_file>]
[-keystore <keystore>] [-storepass <storepass>]
[-storetype <storetype>] [-provider <provider_class_name>] ...
-genkey [-v] [-alias <alias>] [-keyalg <keyalg>]
[-keysize <keysize>] [-sigalg <sigalg>]
[-dname <dname>] [-validity <valDays>]
[-keypass <keypass>] [-keystore <keystore>]
[-storepass <storepass>] [-storetype <storetype>]
[-provider <provider_class_name>] ...
-help
-identitydb [-v] [-file <idb_file>] [-keystore <keystore>]
[-storepass <storepass>] [-storetype <storetype>]
[-provider <provider_class_name>] ...
-import [-v] [-noprompt] [-trustcacerts] [-alias <alias>]
[-file <cert_file>] [-keypass <keypass>]
[-keystore <keystore>] [-storepass <storepass>]
[-storetype <storetype>] [-provider <provider_class_name>] ...
-keyclone [-v] [-alias <alias>] -dest <dest_alias>
[-keypass <keypass>] [-new <new_keypass>]
[-keystore <keystore>] [-storepass <storepass>]
[-storetype <storetype>] [-provider <provider_class_name>] ...
-keypasswd [-v] [-alias <alias>]
[-keypass <old_keypass>] [-new <new_keypass>]
[-keystore <keystore>] [-storepass <storepass>]
[-storetype <storetype>] [-provider <provider_class_name>] ...
-list [-v | -rfc] [-alias <alias>]
[-keystore <keystore>] [-storepass <storepass>]
[-storetype <storetype>] [-provider <provider_class_name>] ...
-printcert [-v] [-file <cert_file>]
-selfcert [-v] [-alias <alias>] [-sigalg <sigalg>]
[-dname <dname>] [-validity <valDays>]
[-keypass <keypass>] [-keystore <keystore>]
[-storepass <storepass>] [-storetype <storetype>]
[-provider <provider_class_name>] ...
-storepasswd [-v] [-new <new_storepass>]
[-keystore <keystore>] [-storepass <storepass>]
[-storetype <storetype>] [-provider <provider_class_name>] ...
1:生成一个
C:\j2sdk1.4.2_05\jre\lib\security>keytool -genkey -alias duke -keyalg RSA -val
idity 10 -storetype jks -keystore trust1.jks
2:查看你刚才生成的证书
C:\j2sdk1.4.2_05\jre\lib\security>keytool -list -v -keystore trust1.jks
当然要输入密码了。
但是我不太明白服务器需要2个证书1个是custom identity keystore 一个是custom trust keystore为什么2个 的输入类型不一样,一个是KeyEntry另外一个是trustedCertEntry,这个流程到底是怎样的?申请证书->导入证书 还是不明白,请指教。
posted @
2007-07-04 17:43 小小程序程序员混口饭吃 阅读(1975) |
评论 (1) |
编辑 收藏
摘要: 最近复习了一下AXIS,写了2个小例子1: bean
1package test.soap.vo; 2 3import java.io.Serializable; 4 5public class User implements Serializable {&nbs...
阅读全文
posted @
2007-06-15 15:48 小小程序程序员混口饭吃|
编辑 收藏
Java对象序列化学习笔记- -
beejoy 原创 来源:java研究组织
目前网络上关于对象序列化的文章不少,但是我发现详细叙述用法和原理的文章太少。本人
把自己经过经验总结和实际运用中的体会写成的学习笔记贡献给大家。希望能为整个java社
区的繁荣做一点事情。
序列化的过程就是对象写入字节流和从字节流中读取对象。将对象状态转换成字节流之后,
可以用java.io包中的各种字节流类将其保存到文件中,管道到另一线程中或通过网络连接
将对象数据发送到另一主机。对象序列化功能非常简单、强大,在RMI、Socket、JMS、EJB
都有应用。对象序列化问题在网络编程中并不是最激动人心的课题,但却相当重要,具有
许多实用意义。
一:对象序列化可以实现分布式对象。主要应用例如:RMI要利用对象序列化运行远程主机
上的服务,就像在本地机上运行对象时一样。
二:java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。
可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用对象序
列化可以进行对象的"深复制",即复制对象本身及引用的对象本身。序列化一个对象可能
得到整个对象序列。
从上面的叙述中,我们知道了对象序列化是java编程中的必备武器,那么让我们从基础开始
,好好学习一下它的机制和用法。
java序列化比较简单,通常不需要编写保存和恢复对象状态的定制代码。实现java.io.Seri
alizable接口的类对象可以转换成字节流或从字节流恢复,不需要在类中增加任何代码。只
有极少数情况下才需要定制代码保存或恢复对象状态。这里要注意:不是每个类都可序列化,
有些类是不能序列化的,例如涉及线程的类与特定JVM有非常复杂的关系。
序列化机制:
序列化分为两大部分:序列化和反序列化。序列化是这个过程的第一部分,将数据分解成字
节流,以便存储在文件中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列
化不仅要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的
对象实例。ObjectOutputStream中的序列化过程与字节流连接,包括对象类型和版本信息。
反序列化时,JVM用头信息生成对象实例,然后将对象字节流中的数据复制到对象数据成员中。
下面我们分两大部分来阐述:
处理对象流:
(序列化过程和反序列化过程)
java.io包有两个序列化对象的类。ObjectOutputStream负责将对象写入字节流,ObjectInp
utStream从字节流重构对象。
我们先了解ObjectOutputStream类吧。ObjectOutputStream类扩展DataOutput接口。
writeObject()方法是最重要的方法,用于对象序列化。如果对象包含其他对象的引用,则
writeObject()方法递归序列化这些对象。每个ObjectOutputStream维护序列化的对象引用表,
防止发送同一对象的多个拷贝。(这点很重要)由于writeObject()可以序列化整组交叉引用的
对象,因此同一ObjectOutputStream实例可能不小心被请求序列化同一对象。这时,进行反引用
序列化,而不是再次写入对象字节流。
下面,让我们从例子中来了解ObjectOutputStream这个类吧。
// 序列化 today's date 到一个文件中.
FileOutputStream f = new FileOutputStream("tmp");
ObjectOutputStream s = new ObjectOutputStream(f);
s.writeObject("Today");
s.writeObject(new Date());
s.flush();
现在,让我们来了解ObjectInputStream这个类。它与ObjectOutputStream相似。它扩展Dat
aInput接口。ObjectInputStream中的方法镜像DataInputStream中读取Java基本数据类型的
公开方法。readObject()方法从字节流中反序列化对象。每次调用readObject()方法都返回
流中下一个Object。对象字节流并不传输类的字节码,而是包括类名及其签名。readObject()
收到对象时,JVM装入头中指定的类。如果找不到这个类,则readObject()抛出
ClassNotFoundException,如果需要传输对象数据和字节码,则可以用RMI框架。
ObjectInputStream的其余方法用于定制反序列化过程。
例子如下:
//从文件中反序列化 string 对象和 date 对象
FileInputStream in = new FileInputStream("tmp");
ObjectInputStream s = new ObjectInputStream(in);
String today = (String)s.readObject();
Date date = (Date)s.readObject();
定制序列化过程:
序列化通常可以自动完成,但有时可能要对这个过程进行控制。java可以将类声明为serial
izable,但仍可手工控制声明为static或transient的数据成员。
例子:一个非常简单的序列化类。
public class simpleSerializableClass implements Serializable{
String sToday="Today:";
transient Date dtToday=new Date();
}
序列化时,类的所有数据成员应可序列化除了声明为transient或static的成员。将变量声
明为transient告诉JVM我们会负责将变元序列化。将数据成员声明为transient后,序列化
过程就无法将其加进对象字节流中,没有从transient数据成员发送的数据。后面数据反序
列化时,要重建数据成员(因为它是类定义的一部分),但不包含任何数据,因为这个数据
成员不向流中写入任何数据。记住,对象流不序列化static或transient。我们的类要用
writeObject()与readObject()方法以处理这些数据成员。使用writeObject()与readObject()
方法时,还要注意按写入的顺序读取这些数据成员。
关于如何使用定制序列化的部分代码如下:
//重写writeObject()方法以便处理transient的成员。
public void writeObject(ObjectOutputStream outputStream) throws IOException{
outputStream.defaultWriteObject();//使定制的writeObject()方法可以
利用自动序列化中内置的逻辑。
outputStream.writeObject(oSocket.getInetAddress());
outputStream.writeInt(oSocket.getPort());
}
//重写readObject()方法以便接收transient的成员。
private void readObject(ObjectInputStream inputStream) throws
IOException,ClassNotFoundException{
inputStream.defaultReadObject();//defaultReadObject()补充自动序列化
InetAddress oAddress=(InetAddress)inputStream.readObject();
int iPort =inputStream.readInt();
oSocket = new Socket(oAddress,iPort);
iID=getID();
dtToday =new Date();
}
完全定制序列化过程:
如果一个类要完全负责自己的序列化,则实现Externalizable接口而不是Serializable接口
。Externalizable接口定义包括两个方法writeExternal()与readExternal()。利用这些方
法可以控制对象数据成员如何写入字节流.类实现Externalizable时,头写入对象流中,
然后类完全负责序列化和恢复数据成员,除了头以外,根本没有自动序列化。这里要注意了。
声明类实现Externalizable接口会有重大的安全风险。writeExternal()与readExternal()
方法声明为public,恶意类可以用这些方法读取和写入对象数据。如果对象包含敏感信息,
则要格外小心。这包括使用安全套接或加密整个字节流。到此为至,我们学习了序列化的
基础部分知识。关于序列化的高级教程,以后再述。
posted @
2007-06-08 13:39 小小程序程序员混口饭吃 阅读(957) |
评论 (1) |
编辑 收藏
CMWAP 和 CMNET 只是中国移动人
为划分的两个GPRS接入方式。前者是为手机WAP上网而设立的,后者则主要是为PC、笔记
本电脑、PDA等利用GPRS上网服务。它们在实现方式上并没有任何差别,但因为定位不同
,所以和CMNET相比,CMWAP便有了部分限制,资费上也存在差别。
WAP只是一种GPRS应用模式,它与GRPS的接入方式是无关的。WAP应用采用的实现方
式是“终端+WAP网关+WAP服务器”的模式,不同于一般Internet的“终端+服务器”
的工作模式。主要的目的是通过WAP网关完成WAP-WEB的协议转换以达到节省网络流量和
兼容现有WEB应用的目的。WAP网关从技术的角度讲,只是一个提供代理服务的主机,它
不一定由网络运营商提供。但据我所知,中国移动GPRS网络目前只有唯一的一个WAP网关
:10.0.0.172,有中国移动提供,用于WAP浏览(HTTP)服务。有一点需要注意,WAP网
关和一般意义上的局域网网关是有差别的,标准的WAP网关仅仅实现了HTTP代理的功能,
并未完成路由、NAT等局域网网关的功能。这就决定了它在应用上所受到的限制。
为了从应用中区别两者的定位,中国移动对CMWAP作了一定的限制,主要表现在CMW
AP接入时只能访问GPRS网络内的IP(10..*),而无法通过路由访问Internet。我们
用CMWAP浏览Internet上的网页就是通过WAP网关协议或它提供的HTTP代理服务实现的。
也就是需要通过中国移动GPRS网络唯一的一个WAP网关:10.0.0.172。CMNET拥有完全的
Internet访问权,这里就不多说了,主要让我们来看看CMWAP。因为有了上面提到的限制
,CMWAP的适用范围就要看WAP网关所提供的支持了。目前,中国移动的WAP网关对外只提
供HTTP代理协议(80和8080端口)和WAP网关协议(9201端口)。
因此,只有满足以下两个条件的应用才能在中国移动的CMWAP接入方式下正常工作:
1. 应用程序的网络请求基于HTTP协议。2. 应用程序支持HTTP代理协议或WAP网关协议。
而cmnet则不受任何的限制。
说白了就是说通过cmwap的方式访问,需要走中国移动的网关通过http协议去连接,
这样的后果就是速度会变慢,相信很多朋友都用过代理服
务器吧,对,就是那个感觉,而通过cmnet来连接的,就是直接连接到无限乾坤在inter
net上的服务器,速度会比cmwap的快一些。说完了速度,就该说价格了,如果玩家没有
采用套餐的话,那cmwap和cmnet都是一样的,1kb三分钱,或者订了一个xx元包xM的套餐
,超出部分1k一分钱,这种时候,同等价格都一样,据我了解,cmwap版本流量会大一些
,所以还是用cmnet比较好,又快又省钱。但是对于很多地方的动感地带用户而言,情况
可能有些不同,相当一些地方的动感地带只能访问cmwap,不能访问cmnet,所以没地选
择了,还有一些地方有动感地带的包月上网卡,有10元、20元、50元的等等,具体的要
看当地的资费政策了,而这些包月卡通常只包cmwap的流量,这个时候如果用cmnet还要
另外付费,所以建议这些用户还是使用cmwap吧。最后总结一下,如果玩家的手机卡只能
访问cmwap或者有cmwap包月的套餐,那么您就使用cmwap连接来游戏,否则使用cmnet连
接是更好的选择
所以,一句话,有wap包月的地区就使用wap包月上网,没有包月业务的就用cmnet,反正都是按流量算钱,为什么不选择快一点的呢(但还是要提醒大家,按流量计费产生的费用是巨大的,要
多多注意)
posted @
2007-05-17 10:50 小小程序程序员混口饭吃 阅读(1970) |
评论 (0) |
编辑 收藏
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class TestConn {
public TestConn() {
super();
}
public static void main(String[] args) throws Exception {
String url = null;
getHttpText(url);
System.out.println("abc");
}
public static String getHttpText(String str) {
URL url = null;
try {
url = new URL(str);
} catch (MalformedURLException e) {
e.printStackTrace();
}
HttpURLConnection huc = null;
try {
huc = (HttpURLConnection) url.openConnection();
huc.setRequestMethod("GET");
huc.setRequestProperty("Content-Type",
"application/vnd.syncml.dm+xml");
// application/x-www-form-urlencoded
// application/vnd.syncml.dm+xml
huc.setDoOutput(true);
huc.setRequestProperty("Cache-Control", "private");
huc.setRequestProperty("Accept-Charset", "utf-8");
huc.setRequestProperty("Accept", "application/vnd.syncml.dm+xml");
huc.setRequestProperty("Content-Length", "3");
DataOutputStream printout;
printout = new DataOutputStream(huc.getOutputStream());
printout.writeBytes("abc");
} catch (IOException e) {
e.printStackTrace();
}
InputStream is = null;
try {
is = huc.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader br = new BufferedReader(new InputStreamReader(is));
StringBuffer sb = new StringBuffer();
String line = "";
try {
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
}
posted @
2007-05-14 09:16 小小程序程序员混口饭吃 阅读(4062) |
评论 (0) |
编辑 收藏
记事本=notepad
计算器=calc
注册表=regedit
系统检测=dxdiag
画图=mspaint
远程桌面=mstsc
posted @
2007-04-29 17:27 小小程序程序员混口饭吃 阅读(485) |
评论 (1) |
编辑 收藏
其实这个问题不是程序的问题,主要是property中文问题,这个问题可以通过build解决掉
<native2ascii src="." dest="build" includes="*Props.txt" />
把配置文件编码 windows下默认GBK编码,linux 要加encoding
代码一行不用改,放心汉化吧~~
posted @
2007-04-24 15:21 小小程序程序员混口饭吃 阅读(1904) |
评论 (3) |
编辑 收藏
如题,有没有朋友知道开源的在线图片处理的程序,在页面上直接处理图片,有点象iephotoshop,功能即使不如
imageJ,也要有一些基本的功能.
posted @
2007-04-19 09:20 小小程序程序员混口饭吃 阅读(2082) |
评论 (2) |
编辑 收藏
话说“你不理财,财不理你”
那么什么是理财呢???
很多人都很知道“理财”,也都无时无刻不在理财,但把理财说清楚的人却不多...
很多人说到理财想到的就是投资,就是开源节流,就是合理分配财产,等等… …
其实,
---------------------------------------------------------
理财就是对财富的有效管理。
理财的内涵很广,包括开源节流,包括合理分配财产,包括投资增值等,但又不止于这些。从理财的基础理论来讲,主要包括:现金管理、资产管理、债务管理、风险管理、投资管理等等。
---------------------------------------------------------
现金管理是理财的基础。包括各项收入的筹划和管理,包括各项税费的管理,包括各项日常支出的管理,包括现金的积累和短期储蓄等等。具体的管理工具和形式有各式各样的银行卡片,各式各样的储蓄方式,各种各样的支出方式,包括各种各样的节俭手段等等。
资产管理是理财的重心。资产具体包括固定资产、流动资产等。固定资产比如房产、铺面等等,流动资产包括储蓄资产、投资资产、保险资产等。资产管理是家庭理财的重点,合理有效的管理需要。
债务管理是理财的关键。债务并非完全的坏事,合理的管理债务是迅速达到理财目标的捷径,只要把债务控制在一定的合理的范围之内,对优化财务结构有很好的作用。比如在财力许可的情况下可以通过按揭提前实现高品质的家庭生活,通过金融信用延迟支付货款往来等,从而更快实现财务目标。
风险管理是理财的关键。有效的风险管理是现代社会先进的标志,没有对风险的管理交通工具不能上路运营,贸易货运不能出门出海流通,商场大厦无法入住营业,流动性和小家化也决定个人进行风险管理是大势所趋。
投资管理是理财的要点。现在很多对投资理财非常渴望,一提到投资赚钱眼睛就发亮,主要是因为目前我国金融环境不够完善,安全稳健的大众投资品种非常匮乏,很多人的收益局限于2个点以内,相较于去年初高达5个点的通货膨胀显然是一个很大的威胁。而国内居民的投资信息和能力先天不足,稍有异动即可能遭遇陷阱的现状导致国民储蓄逐年逼高。在理财范畴内投资增值是最需要专业知识的,也是实现家庭理财目标最关键的步骤。所以如何实现投资的有效管理就很重要。
总之,理财就是所有与财富有关的活动的总称,是现代社会重要的组成要素,是现代人过上幸福快乐生活必备的基本素质。
而且,五个理财的基本方面也是互相关联,互为制约,相互促进的。
posted @
2007-02-13 11:07 小小程序程序员混口饭吃 阅读(350) |
评论 (0) |
编辑 收藏
做为新一代
3G
及移动终端浪潮的设备管理平台,
OMA DM
技术获得了众多设备厂商和运营商的追捧,也为软件开发商提供新的崛起机会。业内目前也有不少工作在做这方面的软件。好多公司这方面的产品都是基于Sync4J开发的。
Sync4J
开源项目为我们提供了完整的
OMA DM 1.1.2
规范的
Java
实现。本文记录了
Sync4J
DM Server
安装以及使用SCTS模拟器来模拟手机做一个DM业务,本文没有用PPG来通过短信方式来用真手机来做,只是用模拟器来做的。SCTS是OMA官方提供的一个测试工具,主要用来测试DMserver的,这里我们用来测试Sync4J。Sync4J和SCTS的集合是我们学习OMA的一个很好的方式。
1
:用到以下工具。
Oracle9i
jboss-3.2.3
sync4j-server-dm-1.4.9 sync4j
官方有下载
SCTS_DeviceManagement_v1.12.zip OMA
官方网站有下载。
2
:安装调试
2.1
解压文件:
jboss-3.2.3
解压到
C:\jboss-3.2.3
把
sync4j-server-dm-1.4.9
解压到
D:\sync4j\all\server-dm
.
直接安装
SCTS.
2.2
配置环境变量
JAVA_HOME=
J2EE_HOME=
C:\jboss-3.2.3
SYNCSERVER_HOME=
D:\sync4j\all\server-dm
2.3
修改SYNCSERVER_HOME下的几个配置文件
SYNCSERVER_HOME\
default\config\common\properties\
Sync4j.properties
把第一行改为
server.uri=http://your
IP:8080/sync4j-dm/dm
SYNCSERVER_HOME\
install.properties
改为
(1)server-name=http://10.150.4.7:8080/sync4j-dm/dm
(2)
用
oracle
的数据库,以下是用来连接数据库的,所以一定要配置正确。
jdbc.classpath=C:\\jboss-3.2.3\\server\\all\\lib\\ojdbc14.jar
jdbc.driver=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@11.11.11.11:1521:abc
jdbc.user=sync4j
jdbc.password=sync4j
2
.4以上都做完后用Sync4j自己带的安装脚本安装sync4j dm server
在
SYNCSERVER_HOME
下运行
bin\install.cmd jboss32
2
.5由于这个版本存在了一个bug,所以在2.4做完后要修改
SYNCSERVER_HOME\bin\start.cmd
把倒数第三行
call\run.bat -c
sync4j
改为
call %J2EE_HOME%\bin\run.bat -c sync4j
2
.6 在SYNCSERVER_HOME 运行 bin\start.cmd安装
所有程序到安装到了
jboss_home
下了,可以到
JBOSS_HOME\
server\sync4j
就可以看到了,看一下你的
oralce
库里面也初始化了数据,表也建好了。
2
.7 添加一个手机(我们其实是个模拟器)上来
http://your
ip:8080/dmdemo/jsp/addDevice.jsp
填写一个
IMEI:111111111111111,
2
.8 配置scts
Add
device : IMEI:111111111111111
然后点
apply
点击
DM
Account
Name
:
sync4j
Server:sync4j
Con :
不用填写
Address
:
http://your
ip /sync4j-dm/dm
Port
:8080
Server
authentication:
Digest :
找数据库用
sync4j
的数据库中,
sycn4j_device
表中
:IMEI:111111111111111
,
server
的
password
为:
srvpwd,
把这个
password
填写到
password
中。
Client authentication
DIGEST: USER NAME:
sync4j PASSWORD:
sync4j
Add
就可以了
然后点
connect
连一下
DM SERVER
看看能否连上。
第一次一般会出现认证错我,接着再联一次就可以了,
SCTS
有日志可以查看。
如果连通了那下面就来做一个采集模拟器上的一个节点吧。
http://your ip:8080/dmdemo/index.html
用
device id
:
IMEI:111111111111111 login
然后点击
add to operation list
然后用
SCTS
主动回联一下,看看
server
能够拿到这个节点的值
你会看到
6
个
message
!!!
详细看一下这
6
个
message
你会发现,这个节点的采集已经成功了!
posted @
2007-02-05 10:02 小小程序程序员混口饭吃 阅读(9268) |
评论 (11) |
编辑 收藏