Java

通过Runtime.getRuntime().exec() 调用系统应用时,应该异步打印verbose信息

如果你这样打, 可能会导致执行阻塞 private static void printInput(Process p) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream())); String line; while ((line = in.readLine()) != null) { System.out.println(line); } in.close(); } 所以,你要用非阻塞的方式来打。CXF源代码里有个不错的例子: if (p.getErrorStream() != null) { StreamPrinter errorStreamPrinter = new StreamPrinter(p.getErrorStream(), "", System.out); errorStreamPrinter.start(); //StreamPrinter是一个线程 } if (p.getInputStream() != null) { StreamPrinter infoStreamPrinter = new StreamPrinter(p.getInputStream(), …

通过Runtime.getRuntime().exec() 调用系统应用时,应该异步打印verbose信息 Read More »

讨论:如果一个布尔值可能为空,则不要用布尔来定义它的类型

“肚子里的孩子是不是男的?”? 除了回答“是”或“否”,还可以回答“不知道/未定” 原始的boolean类型不能赋值为“未定”,不能用; java.lang.Boolean类型的对象可以赋值为“null”,似乎可以解决这个问题。 但这种做法仍有隐患:   1. 有的人对“Boolean值可能为空”缺乏意识。 比如你的同事再调用你的 isBoy()时可能并不会先判断它是否为null.   2. 有些框架对封装类型如Boolean, Integer会使用默认值机制。比如有些Web Service框架就会把客户端传来的Boolean值强行设置成Boolean.FALSE 为了解决这个问题,最好弃用布尔类型,改用enum,或者字符串。人们在潜意识里都知道enum和字符串可能为空,因此不会贸然犯错。 enum Gender{ MALE, FEMALE }

jax-ws中映射多态

public interface AnimalService { @WebMethod void add(Animal animal); } 这里Animal是抽象类,它有两个子类Cat和Dog; 有没有办法在WSDL里实现这种多态? 答案是可以,使用@XmlSeeAlso注解即可 @XmlSeeAlso({Cat.class, Dog.class}) public abstract class Animal{ } 这样产生的WSDL里会有这样的东西: <xs:complexType name="cat"> <xs:complexContent> <xs:extension base="tns:animal"> <xs:sequence> … </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType>

不推荐的作法:数据库里把ID设为Number类型,Java里设为字符串类型

ID一般是自增的,所以数据库里应设为Number类型 Java里可以把它置为String类型,因为ID纯粹是一个标识,并没有数字意义(不参与加减乘除) 然而这里有个小陷阱:类型转换时会出问题。 数字格式化为String时可能会产生逗号,带逗号的String未必能舒服地转回成数字。 当你的系统与另外一个系统交互,且另外一个系统要求ID为数字类型时,这种问题就可能成为灾难。

松散的系统交互方式: One-way Messaging, Compensation 和 Idempotency

为了让两个交互的系统能够减少耦合,它们之间的消息交换方式应该尽量松散。 为了使交互变得松散,可以采用以下手段或者遵循以下准则:   1. One-Way Messaging. 即异步调用。一个典型的例子就是request/callback:  给对方系统发一个Notification,让对方在它方便地时候回调我们,拿它想要的东西   2. Compensation. 为了保证事务的原子性,一般可以采取“两阶段提交”手段; 但这种手段要求两个系统都要使用相应的基础设施,比较麻烦; 替代方案是在发生单边数据时采用Compensation操作: 要么系统自动把本方已生成的数据取消,要么发一封邮件通知某人在对方系统里手动补上相应数据。   3. Idempotency. 发出请求后却没能收到对方的反馈,那对方倒底是处理请求失败,还是处理请求成功但发送反馈超时? 本方系统不知道,因此不知道能否重发请求。为了解决这个问题,对方系统应该保证重复请求不会产生错误的结果,这样就不怕重复。

如何实现Web Service的Idempotency

摘自《SOA In Practice》 一个Service执行一次请求产生的结果,如果跟执行多次同样的请求产生的结果相同,则可以说这个Service满足了Idempotency 1. Reading Service都是Idempotent 2. "update bonus = 100 where id = 3" 是Idempotent 3. "update bonus += 100 where id =3 " 不是Idempotent — 操作结果依赖数据原先状态的Service都不是Idempotent     为了把这种Service变成 Idempotent,应该遵守这样一种契约:Consumer的请求里应该有一个RequestId, 重发时仍然使用同样的RequestId; Provider收到请求后要将RequestId存起来,如果新请求的RequestId已经存在了,就不要再执行相应的操作。   

研究了一下OAuth

假设你的网站有这样一种功能:如果用户同意,你的网站可以代表他去拿他在Facebook上的非公开照片; 然后在线下打印,把照片寄给你。 简单的解决办法是用户把他的facebook用户名/密码提交给你的网站,然后你的网站再用这个用户名/密码去调Facebook的web service. 问题是:    1. 用户不愿意把他在Facebook的用户名和密码给你的网站    2. 即使他愿意给你,他也会担心你的网站在拿到照片之后,又去进行“获取聊天记录”之类的未授权操作    3. 用户现在允许你现在去拿照片,但不代表允许你明天也可以拿 OAuth就是用来解决这种典型问题 :“Allowing one party(你的网站) to access someone else’s resources(用户在Facebook的照片) on their behalf(代表用户)”      1. 用户不用提供用户名/密码给你的网站,相反他的浏览器会跳转到facebook,他在facebook端输入用户名/密码,然后再跳转回来。回来时会在URL里加上一个token    2. 你的网站可以根据这个token去facebook拿照片。这个token将专用于“拿照片”。如果你想趁机窃取更多的个人资料,facebook会拒绝    3. 这个token也有时限,超过一段时间即失效。差不多你只能拿一次照片。