颠覆软件

关注 : 架构与设计,敏捷,快速开发,项目管理,执行力,SSH,RoR

这里的xml为什么这样红?

Filed under: java开发技术 — Alex at 2:55 pm on Monday, August 4, 2008

1.从svn版本上checkout出来的新的版本,dwr部分的xml配置文件是红色提示错误,一开始以为是jsp的普通验证错误,后发现不是那么回事。

2.跟踪xsi文件,结果发现有一些远端的schema打不开,立刻明白是怎么回事,可能和用户现场的局域网的网络限制有关,于是立即用cdma连上去,clean,rebuild ==>OK。

3.ps:很多的运行环境可能不能连上公网,可以考虑将sxi的location设置为运行服务器的url

框架库:选一款适合你的武器行走江湖

Filed under: java开发技术 — Alex at 12:34 pm on Saturday, September 1, 2007

key words:web快速开发框架

做java项目的开发,可选用的框架很多,这是一件幸福的事情,同时也是一件痛苦的事情。

可选用的框架目前大致如下:

  • Grails
  • Ruby on Rails
  • JBoss Seam
  • RIFE
  • Trails

我个人看好两个,一个是Ruby on Rails,另一个是Jboss Seam,原因很简单,好用。

鄙人认为,做开发的人都比较自傲,以征服所谓高科技含量的技术为荣,但是往往不回头想想效率,这有点类似于麦当劳与中国的大厨 ,我们要的是效率,不是要的是崇拜和门槛。换句话说,我们要工业化,不要手工作坊。我们要人人都能快速进行开发,而不仅仅是某几个人的专利! 换句话,我们要真正的自由! 我们要解放! 我们要革他妈的命!!!我们需要的是关注业务,关注团队,技术,应该跟自来水一样,要就打开用,而不要再自己去造一个管道取水。

我欣赏那些为了提高软件开发效率而作研究的公司,比如ESB算一个,虽然他现在的情况不是很明确,但是至少有这种组件重用的思想。扪心自问,你的项目中有几个是能重用的,不用问,80%蛋都扯不上。

RoR算一个,一个突破性的 开发平台,算是一次革命。

Spring算不算? 有人认为当然算,我个人认为不算,非要说好,我只能说仅仅使事情方便一点而已,无他也!

Jboss Seam算不算? 我认为算一个,很多人现在不怎么看好,但是我可以预测,不久的将来一定会成为主流,不用怀疑.

很多东西是拿来被利用的,被 Fuck的,不是让你消磨时间的.

未来团队组建的方式我的原则是这样的:

一个技术负责人带一帮刚毕业的大学生,经过一到两周的培训,就可以 进行正常开发,所有的技术学习曲线很低,每个人可能不太明白具体细节或者原理怎么回事,但是首先能用起来,而不是发愣.

不要指望你的公司全是牛人,也不要指望一个牛人能把所有的细节技术都传授给下面的人,我们要的是可以传递可以复制的东西.

谈谈方法中的返回值类型和参数类型

Filed under: java开发技术 — Alex at 9:47 pm on Sunday, May 13, 2007

和大家谈谈方法中的返回值类型和参数类型。

大多数时候我们用具体的返回类型,比如要么是一个具体的对象,要么是一个Collection作为返回类型,对于参数同样如此,
现在我看到另一种做法,即参数和返回类型都是HashMap,大家以为此种做法是否可取?

代码如下:

public BeanValue saveMyPo(RequestMap rMap) {

        BeanValue value 
= new BeanValue();

        
try {

            MyPo mypo
= (MyPo) BeanUtil.convertObject(MyPo.class,
                    rMap.getMap());

            mypo.setTtime(
new Date());




            dao.saveObject(mypo);

            value.addRequestMap(
hi, mypo);

        }
 catch (Exception e) {
            value.addErrorMap(Constants.MyException, e);
            value.setForword(
fail);
        }


        
return value;

    }

目前这个做法看得到的好处有几点:
1。返回的类型可以存放更多的内容,包括错误信息以及更多的其他内容
2。参数传递的内容更丰富,可以减少不必要的重载,减少代码量。

不过,如果说有什么缺点的话可能就是语义不够明确,那么除了这一点还有什么别的问题么? 请大家拍砖。

[zt]插入图片到数据库(BLOB大字段保存对象)

Filed under: java开发技术, 数据库 — Alex at 10:02 pm on Wednesday, March 28, 2007

[zt]用JSP实现上传文件的两种方法

Filed under: java开发技术 — Alex at 10:03 pm on Monday, March 26, 2007

key words: 文件上传,upload, cos.jar + uploadbean.jar + filemover.jar

以前用cos作文件上传,但是对于文件上传后的改名还需要借助其他的工具。

摘录如下:

在用Java开发企业器系统的使用,特别是涉及到与办公相关的软件开发的时候,文件的上传是客户经常要提到的要求.因此有 一套很好文件上传的解决办法也能方便大家在这一块的开发.

首先申明,该文章是为了自己记录一备以后开发需要的时候,不用手忙脚乱哈哈……..

现在在国内用的非常多的一般是两种方法解决来解决文件上传.

cos.jar + uploadbean.jar + filemover.jar
这个是用的非常普遍的,原因是因为他操作方便,是我们不必再去关注,那些文件的输入和输出流,使我们从底层的流中解脱出来.
UploadFile,UploadBean,MultipartFormDataRequest

<%@ page contentType=”text/html;charset=gb2312″ %>
<head>
<title>fbysss UploadBean 示例</title>
<!–meta http-equiv=”Content-Type” content=”text/html; charset=iso-8859-1″–>
<!–meta http-equiv=”Content-Type” content=”text/html; charset=gb2312″–>
</head>
<FORM name=”form1″ METHOD=”POST” ACTION=”sssupload.jsp” ENCTYPE=”multipart/form-data”>
<input name=”title” type= ”text” value=”中文字”>
<td class=”bodystyle”>附件</td>
<td class=”bodystyle”> <input name=”attach” type=”FILE” id=”attach” size=”50″ > </td>
<input name=”ok” type= ”submit” value=”提交”>
</form>

2.读取表单页面sssgetdata.jsp

<!–
//==========================================================================
//文件:UploadBean上传实例
//功能:解决中文乱码,完成文件上传,并提供上传改名解决方案
//作者:fbysss
//msn:jameslastchina@hotmail.com
//==========================================================================
–>
<%@ page contentType=”text/html;charset=GBK” %>
<%@ page language=”java” import=”com.jspsmart.upload.*”>
<%@ page import=”java.text.SimpleDateFormat”>
<%@ page import=”java.io.File”>
<%@ page import=”java.util.*”>
<%@ page import=”javazoom.upload.*”>
<%@ page import=”uploadutilities.FileMover”>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=gb2312″>
</head>
<
request
.setCharacterEncoding(”GBK”);//设置编码格式,就不用一个个转码了。
FileMover fileMover 
= new FileMover();//你也可以使用自带的实例中jsp:useBean的形式。
UploadBean upBean 
= new UploadBean();
MultipartFormDataRequest mrequest 
= null;
Hashtable files = null;

if (MultipartFormDataRequest.isMultipartFormData(request))
{
mrequest 
= new MultipartFormDataRequest(request,null,100*1024*1024,MultipartFormDataRequest.COSPARSER,”GBK”);//注意这里也要设置编码参数
String sTt0 
= mrequest.getParameter(”title”);
out.println(”<br>Title0是:”+sTt0+”<br>“);
String sTt1 = new String(sTt0.getBytes(”ISO-8859-1″),”GBK”);
out.println(”
<br>Title1是:”+sTt1+”<br>“);
//这里用来测试title参数是否正确。调试的时候,加一句if (true)return;即可。
files = mrequest.getFiles();
}


//获取修改前的文件名
String sOldFileName =mrequest.getParameter(”oldfilename”);
out.println(”sOldFileName:”+sOldFileName);
String sWebRootPath = request.getRealPath(”/”);//得到你的web应用的根。
String sPath=sWebRootPath+”attach”;
int iFileCount = 0;
String sServerFileName=”";
String sLocalFileName = ”";
//文件获取
if ( (files != null) || (!files.isEmpty()) ) {

iFileCount = files.size();
UploadFile file = (UploadFile) files.get(”attach”);
sLocalFileName=file.getFileName();
out.println(”sLocalFileName:”+sLocalFileName);
int ii= sLocalFileName.indexOf(”.”); //取文件名的后缀
String sExt = sLocalFileName.substring(ii,sLocalFileName.length());
//得到不重复的文件名
java.util.Date dt = new java.util.Date(System.currentTimeMillis());
SimpleDateFormat fmt = new SimpleDateFormat(”yyyyMMddHHmmssSSS”);
sServerFileName= fmt.format(dt);
sServerFileName =sServerFileName + sExt;
//如果不存在该目录,则新建一个
File dir =new File(sPath);
if (!dir.exists()){
dir.mkdirs();
}
upBean.setFolderstore(sPath);//设置要上传的目录
upBean.addUploadListener(fileMover);//增加filMover监听
fileMover.setNewfilename(sServerFileName);//设置服务器上的文件名
upBean.store(mrequest, ”attach”);//上传
out.println(”file path is ”+sPath+”/”+sServerFileName);
}

%>

Demo注意事项:cos.jar,uploadbean.jar,filemover.jar这几个包必须有。
必备下载地址:
UploadBean1.5:http://wcarchive.cdrom.com/pub/simtelnet/winnt/java/uploadbean1_5.zip
FileMover1.3:http://www.javazoom.net/jzservlets/uploadbean/addons/filemover1.3.zip
参考下载地址:
ChinesUpload例子:http://www.javazoom.net/jzservlets/uploadbean/addons/ChineseUpload.zip
参考了fbysss的一篇文章
2. org.apache.struts.upload.FormFile
Struts1.1的org.apache.struts.upload.FormFile类。很方便,不用自己写。也不用写一个jsp调用jspsmartupload就可以搞定。

选择上传文件页面:selfile.jsp

——————————————————————————–
<%@ taglib uri=”/WEB-INF/struts-html.tld” prefix=”html”%>
<html:html>
<html:form action=”/uploadsAction.do” enctype=”multipart/form-data”>
<html:file property=”theFile”/>
<html:submit/>
</html:form>
</html:html>

——————————————————————————–
UpLoadAction.java
——————————————————————————–

import java.io.*;
import javax.servlet.http.*;
import org.apache.struts.action.*;
import org.apache.struts.upload.FormFile;

/**
* <p>Title:UpLoadAction</p>
* <p>Description: QRRSMMS </p>
* <p>Copyright: Copyright (c) 2004 jiahansoft</p>
* <p>Company: jiahansoft</p>
@author wanghw
@version 1.0
*/


public class UpLoadAction extends Action {
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
if (form instanceof uploadsForm) {//如果form是uploadsForm
String encoding = request.getCharacterEncoding();
if ((encoding != null&& (encoding.equalsIgnoreCase(utf-8)))
{
response.setContentType(
text/html; charset=gb2312);//如果没有指定编码,编码格式为gb2312
}

UpLoadForm theForm 
= (UpLoadForm ) form;
FormFile file 
= theForm.getTheFile();//取得上传的文件
try {
InputStream stream 
= file.getInputStream();//把文件读入
String filePath = request.getRealPath(/);//取当前系统路径
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream bos 
= new FileOutputStream(filePath + / +
file.getFileName());
//建立一个上传文件的输出流
//System.out.println(filePath+”/”+file.getFileName());
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ( (bytesRead = stream.read(buffer, 08192)) != -1{
bos.write(buffer, 
0, bytesRead);//将文件写入服务器
}

bos.close();
stream.close();
}
catch(Exception e){
System.err.print(e);
}

//request.setAttribute(”dat”,file.getFileName());
return mapping.findForward(display);
}

return null;
}

}



——————————————————————————–

UpLoadForm.java

——————————————————————————–

import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.*;
import org.apache.struts.upload.*;

/**
* <p>Title:UpLoadForm</p>
* <p>Description: QRRSMMS </p>
* <p>Copyright: Copyright (c) 2004 jiahansoft</p>
* <p>Company: jiahansoft</p>
@author wanghw
@version 1.0
*/


public class UpLoadForm extends ActionForm {
public static final String ERROR_PROPERTY_MAX_LENGTH_EXCEEDED = org.apache.struts.webapp.upload.MaxLengthExceeded;
protected FormFile theFile;
public FormFile getTheFile() {
return theFile;
}

public void setTheFile(FormFile theFile) {
this.theFile = theFile;
}

public ActionErrors validate(ActionMapping mapping, HttpServletRequest request)
{
ActionErrors errors 
= null;
//has the maximum length been exceeded?
Boolean maxLengthExceeded = (Boolean)
request.getAttribute(MultipartRequestHandler.ATTRIBUTE_MAX_LENGTH_EXCEEDED);
if ((maxLengthExceeded != null&& (maxLengthExceeded.booleanValue()))
{
errors 
= new ActionErrors();
errors.add(ERROR_PROPERTY_MAX_LENGTH_EXCEEDED, 
new ActionError(maxLengthExceeded));
}

return errors;

}

}

//这是相对应的form,还有其他属性可以设置,具体可以参考struts的上传例子。

——————————————————————————–

struts-config.xml

——————————————————————————–

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE struts-config PUBLIC “-//Apache Software Foundation//DTD Struts Configuration 1.1//EN” “http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd”;>
<struts-config>
<form-beans>
<form-bean name=”uploadsForm” type=”UpLoadForm” />
</form-beans>
<action-mappings>
<action name=”uploadsForm” type=”UpLoadAction” path=”/uploadsAction”>
<forward name=”display” path=”/display.jsp” />
</action>
</action-mappings>
</struts-config>
<!–display.jsp就是随便写一个成功页–>

jsp防盗链

Filed under: java开发技术 — Alex at 10:05 pm on Tuesday, March 13, 2007

key words : jsp防盗链 header

最近碰到盗链的问题,即复制一个url地址,在另一个地方也能访问。

index.jsp页面

<html>
  
<head><title>Simple jsp page</title></head>
  
<body>Place your content here

  here is index jsp
    get header info
  
<href=”a.jsp”>a.jsp</a>
  
</body>
</html>
a.jsp页面

<html>
  
<head><title>Simple jsp page</title></head>
  
<body>Place your content here

  here is a. jsp
    get header info
  
<%=request.getHeader(Referer)%>
  
<%if(null == request.getHeader(Referer) || request.getHeader(Referer).indexOf(yourdomain.com< 0){%>
     做人要厚道
  
<%}else{%>
  合法访问
  
<%}%>
  
</body>
</html>

即从内部访问可以,直接粘贴地址在另一个浏览器里访问禁止

真正理解面向接口编程

Filed under: java开发技术 — Alex at 10:06 pm on Monday, March 12, 2007

key words :面向接口编程

面向对象设计里有一点大家已基本形成共识,就是面向接口编程,我想大多数人对这个是没有什么觉得需要怀疑的。

问题是在实际的项目开发中我们是怎么体现的呢? 难道就是每一个实现都提供一个接口就了事了?反过来说,你有时候有没有觉得接口是多余的事? 又或者,你仅仅是觉得现在类似spring这样的框架已习惯用接口这种方式而心存当然。

设计模式解析里提到了面向对象设计考虑的几个视角,一个是概念层,一个是规约层,一个是实现层。我如果没有猜错的话,实际上我们大多数人的眼睛一直是盯着实现层的,而这正是面向对象设计所极力避免的,即你不要在一开始就关注这些细节,你要关注的是规约(接口).

对于实际项目开发来说,如果我们把实现的过程分为多个阶段的话我们不妨这么划分,第一阶段,根据client端的需要去设计我们的规约(interface),在这个阶段任何实现都没有,所有的任务就是定义接口所需要的职责,以及所需要的一些po,vo;第二阶段,实现前面定义的规约。而以前我是怎么做的呢? 我是交叉作的,即假模假样的定义一个接口(其实我心里在想这个东西有屁用),然后定义了一个方法,然后就立即去实现这个方法,再然后我又定义一个方法,继续去实现,我现在终于想通了,这样好累,效率很低,最重要的是,这不属于真正的设计。
现在我是怎么做的呢?比如一个list.jsp里需要查询,列表,然后看明细信息,然后增加信息,我会第一步在接口里定义完(这个过程会有整体设计的意识),毫不关心底层实现(数据库、事务),我的目标就是”我想要这个功能,我想要那个功能”,至于那个功能怎么实现在第一阶段我认为那不是我的事情(尽管这个事情最终还是由我来做) .大家看这个过程和前面的过程有什么本质的不同呢? 就是分层的概念更加明显,你的工作更有层次,每次都有先设计再实现的步骤,而前面那个过程很容易就让你不知不觉地陷入纯实现的陷阱中。

一点感想,欢迎大家拍砖。

上传文件放在哪里比较合适?

Filed under: java开发技术 — Alex at 10:10 pm on Wednesday, January 31, 2007

目里面有上传文件的需求,我想了一下不外乎下面两种处理方法: 1. 在数据库表中建立一个blob字段存放用户上传文件. 2. 在服务器上建立一个文件夹保存用户上传文件,数据库表中只存放该文件的url地址. 我本人现在比较倾向于第2种方案, 主要原因是担心方案1的效率(我用的是mysql数据库)。 但是处理过程中除了维护数据库中表的字段还要维护上传的文件,稍微麻烦一点。 大家在项目里面又是怎么做呢? 给我点建议!谢谢 讨论内容见: javaeye robin更建议第二种方案,放在数据库中主要的问题是 AppServer吃不消,开销比较大. 上面是摘录,不过我们这里用的是Oracle9i AS,在Oracle的协作套间里一般文档或者上传的文件都是保存在数据库里,还把这个特性作为Oracle 与别的协作套件之间不同的卖点。 大家以为如何? 我直觉是Oracle的DB和oc4j的AppServer对付这个似乎没有开销上的担心,但是没有实际检测过。 换句话说,文件的管理是放在文件夹里方便还是数据库里方便? 有点为难 update (2007-5-13): 还有一种方案结合了数据库和IO,我认为比较可行,就是文件存在数据库,但是下载的时候第一次从数据库下载,然后第一次这个文件保存在一个临时文件夹下面,以后每次下载的时候总是先检查此临时文件夹,如果已经存在则直接下载,如果没有则从数据库重复这个动作。当然,保存在临时文件夹下的文件的命名需要唯一,这个应该没有问题。

web快速开发相关技术和产品

Filed under: RoR, java开发技术 — Alex at 10:14 pm on Saturday, January 20, 2007

key words : web快速开发

web快速开发是一个值得期待的东西,最早我接触过codecharge,是一个商业软件,功能据说很强大,我试用过,支持php,asp,jsp等多语言,但是感觉对java的支持不是很顺手,接着就是asp,这个好也不好,原因就不说了,因为我对java关注。

2. 接着就是dorado ,刚看到的,感觉也不错,有asp的风格,不过更适合j2ee的环境 ,这里是他们的在线演示demo,有兴趣的可以看一下

3. 最后,刚google了一下,Oracle也有一个基于Oracle数据库的快速开发产品  : APEX,基于浏览器做DB 开发,原来的名字叫做HTML DB,名字很直观,据说Oracle的metalink就是用这个实现的,应该功能不赖。

4.对了,再补充一个现在很热的,Ror,听说javaeye的网站要重新用ruby1.2开发,试用过一点,感觉确实令人震惊,值得关注。

java的技术其实是看着很热闹,比较大的东西也不少,但是真正关注web这一块的其实不多,无论是struts还是webwork,离我们所说的真正的“快速开发”的距离很远,而以上一些工具的出现也许会逐步改善j2ee在这一领域的现状。

我之所以对这个目前有点兴趣,确实有一种强烈的反差在折磨着我,因为我相信在j2ee的web开发里确实存在本来要开发1周多的工作量很可能用一个好的工具几个小时就搞定了,这是一件多么荒唐搞笑的事情?如果dorado在它的产品中真的能做到这样那我们的java开发那么坑吃坑吃的折腾个什么劲啊? 也许真的有奇迹,我宁愿相信有这样的奇迹。

大家有什么好的想法可以讨论一下。

[zt]关于commons logging

Filed under: java开发技术 — Alex at 10:27 pm on Monday, December 18, 2006

key words: commons log,log4j,apache log

前言: 对于log4j虽然在用,但是也存在一个疑问,怎么有的用apache的commons logging有的直接用log4j,下面的这篇文章解释了我的疑问.

转自 here

Apache组织开发了一套用于支持Logging的Log4J,Java 1.4版本也引入了一套内置的 Logging框架,如果开发者想在这两套Logging系统之间自由的切换,该怎么办呢?答案就是,使用Commons Logging。 Commons Logging定义了一套抽象的Logging接口,用户可以通过配置,使这些接口指向任何一个已存在的Logging系统。

•使用抽象Logging接口
问题:
你在编写一个可以重复使用的库,需要写入Log信息,但你不想使你的Logging功能绑定在Apache Log4J或者JDK 1.4 Logging框架上。
解决方案:

public static void main(String[] args) {//自己替换[]

System.setProperty(”org.apache.commons.logging.Log”,
“org.apache.commons.logging.impl.Jdk14Logger”);
Log log = LogFactory.getLog(”com.discursive.jccook.SomeApp”);

if (log.isTraceEnabled()) {
log.trace(”This is a trace message”);
}

if (log.isDebugEnabled()) {
log.debug(”This is a debug message”);
}

log.info(”This is an informational message”);
  log.warn(”This is a warning”);
log.error(”This is an error”);
log.fatal(”This is fatal”);

}

LogFactory.getLog方法会根据底层环境返回一个适当的Log实现。如果用户想指定一个具体的Logging系统实现,可以设置org.apache.commons.logging.Log系统属性。例如:
System.setProperty(”org.apache.commons.logging.Log”,
“org.apache.commons.logging.impl.Log4JLogger”);
这样就会使用Log4J作为Logging系统。
org.apache.commons.logging.Log可以设定为:
•org.apache.commons.logging.impl.Log4JLogger  使用Log4J
•org.apache.commons.logging.impl.Jdk14Logger  使用JDK 1.4 Logging框架
•org.apache.commons.logging.impl.SimpleLog  使用Commons Logging内置的简单Log实现
其他:
总结一下,Commons Logging会按照下列顺序来指定具体的Log实现。
•如果定义了org.apache.commons.logging.Log系统参数,实用指定的Logging实现。
•如果在CLASSPATH里发现了Log4J,使用Log4J。
•如果使用的是JDK1.4,使用JDK1.4内置的Logging框架。
•如果都没有找到,则使用Commons Logging内置的简单Log实现。

Next Page »