庄周梦蝶

生活、程序、未来
   :: 首页 ::  ::  :: 聚合  :: 管理

怎么解析一个xml字符串?我不是第一次看到有人问这个问题了..汗

1.使用StringReader

 

Document doc  =  builder.parse(  new  java.io.StringReader(str)); 

2.使用DocumentHelper.parseText()

String text  =   " <person> <name>James</name> </person> "
Document document 
=  DocumentHelper.parseText(text); 

3.最苯的方法:

 

Document doc   =   builder.parse(  new   ByteArrayInputStream(str.getBytes())); 

posted @ 2007-02-06 12:39 dennis 阅读(463) | 评论 (0)编辑 收藏

工作中还是一直使用jdk1.4.2版本,JDK5出来这么久也只是偶尔玩玩,特别是在学习EJB3时好好体验了一把Annotation的便利.

枚举类型也是JDK5引入的新的特性,看了几篇文章,还是蛮有趣的.

过去我们定义常量,都是在一个专门的类或者接口中定义一大堆静态常量类型,比如衣服的尺寸:

 

public   class  Size {

  
public   static   final  String S = " S " ;

  
public   static   final  String M = " M " ;

  
public   static   final  String L = " L " ;

  
public   static   final  String XX = " XX " ;

  

}

 

然后这样调用:Size.X,Size.M...

现在引入了枚举类型,我们可以这样定义:

 

public   enum  Size  {

  S,M,L,XX,XXX,XXXL;

}

 

调用的方式不变,如:Size.S,Size.M...如果仅仅这样的好处,好象还没什么理由让我们体验到便利的一面,OK,让我们谈谈enum的特性.

1.排序,枚举类型默认按照原始排列的各个值元素的顺序为依据,比如上面的例子:S<M<L<XX<XXX<XXL.默认提供compareTo()方法来比较:

 

Size.S.compareTo(Size.M);   // 结果为-1

 

2.通过values()来列举所有的值,比如:

 

    for (Size s:Size.values()) {

      System.out.println(s);

   }

 

此例用到了JDK5的新特性,简化的for循环

3.枚举类型的集合:J2SE5提供了EnumMap<K extends Enum<K>,V>和EnumSet<E extends Enum<E>)两个枚举类型的集合类型,以map为例子:

 

EnumMap(Size,String) map = new  EnumMap(Size,String > (Size. class );

map.put(Size.S,
" 适合身高55-160的人 " );

map.put(Size.M,
" 适合身高160-165的人 " );

map.put(Size.L,
" 适合身高165-170的人 " );

 

...

4.给枚举类型增加方法:枚举类型可以像类那样添加方法,假设大家在挑衣服的时候,常常不关心现在试的衣服的尺码多少,而是简单地获取比当前的大一个级别的尺码,我们给Size增加一个increase()方法:

 

  public  Size increase()  {
   Size sizes[] 
=   this .values();
   
int  pos  =   this .ordinal();
   
if  (pos  <  sizes.length  -   1 )
    pos
++ ;
   
return  sizes[pos];
 }

 

通过ordinal()方法找到当前的Size对象的值在整个Size值域中的位置,判断位置是否是最大值,如果不是就再增长一个级别返回.

问题来了,如果我们希望Size的每个值都有一个test方法返回消息,而且消息都不一样.那我们该如何处理.当然,我们可以像上面这样:

public String test(){ ..}

可以我们想实现更个性化的消息,比如"你好矮!...","你好胖..","你太高了吧!!!!"等等之类.首先我们给Size定义一个抽象方法:

 

abstract  String test();

 

然后就简单了,每个值都实现自己的test方法:

 

{
  String test() 
{
   
return   " 号码:S,很不厚道地说,你很矮 " ;
  }

 }
,

{
  String test() 
{
   
return   " 号码:M,如果你是MM,身高正合适 " ;
  }

 }
,

{
  String test() 
{
   
return   " 号码:L,帅哥,电话号码多少 " ;
  }

 }
,

XX 
{
  String test() 
{
   
return   " 号码:XX.MM,三围不错..别打我!!! " ;
  }

 }
,

 

 ....

漂亮吧,枚举类型实在是个有趣的东东,当俺公司全面转向J2SE5的时候可以好好玩一把

  

posted @ 2007-02-06 12:37 dennis 阅读(601) | 评论 (0)编辑 收藏

常用的几个:

^[_/.0-9a-z-]+@([0-9a-z][0-9a-z-]+/.)+[a-z]{2,3}$

^[_a-z0-9-]+(/.[_a-z0-9-]+)*@[a-z0-9-]+(/.[a-z0-9-]+)*$

^(([0-9a-zA-Z]+)|([0-9a-zA-Z]+[_.0-9a-zA-Z-]*[0-9a-zA-Z]+))@([a-zA-Z0-9-]+[.])+([a-zA-Z]{2}|net|com|gov|mil|org|edu|int)$

^([a-z0-9A-Z]+[-|//.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?//.)+[a-zA-Z]{2,}$

/w+([-+.]/w+)*@/w+([-.]/w+)*/./w+([-.]/w+)*

在JAVA中使用:

 

import java.sql.*;
import java.io.*;
import java.util.regex.*;

public class test{
 public static void main(String[] args){
  try{
   String s = "";
   while(!s.equals("q")){
    System.out.print("input:");
    DataInputStream in = new DataInputStream(new BufferedInputStream(System.in));
    s = in.readLine();
    System.out.println("your input is :"+s);
    String check = "^([a-z0-9A-Z]+[-|//.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?//.)+[a-zA-Z]{2,}$";
    Pattern regex = Pattern.compile(check);
                Matcher matcher = regex.matcher(s);
                boolean isMatched = matcher.matches();
                if(isMatched){
                 System.out.println("it's a email");
             }else{
              System.out.println("it's not a email");
             } 
    
   }
        }catch(Exception e){
         System.out.println("error"+e.getMessage());
     }
 }         

posted @ 2007-02-06 12:33 dennis 阅读(3917) | 评论 (2)编辑 收藏

花了两天时间,终于把jasperreport与项目中使用的hibernate结合使用.最新版本的ireport支持HQL查询,可以在 ireport里面写HQL语句查询并设计好报表.需要注意的是把hibernate.cfg.xml包括进classpath!!(菜单options ->classpath进行设置)给张图:

test2.jpg

设计好报表之后编译成jasper文件,在servlet中调用,我们需要实现自己的hibernate datasource:

public class HibernateQueryResultDataSource implements JRDataSource {

 private String[] fields;

 private Iterator iterator;

 private Object currentValue;

 public HibernateQueryResultDataSource(List list, String[] fields) {
  this.fields = fields;
  this.iterator = list.iterator();
 }

 public Object getFieldValue(JRField field) throws JRException {
  Object value = null;
  int index = getFieldIndex(field.getName());
  if (index > -1) {
   Object[] values = (Object[]) currentValue;
   value = values[index];
  }
  return value;
 }

 public boolean next() throws JRException {
  currentValue = iterator.hasNext() ? iterator.next() : null;
  return (currentValue != null);
 }

 private int getFieldIndex(String field) {
  int index = -1;
  for (int i = 0; i < fields.length; i++) {
   if (fields[i].equals(field)) {
    index = i;
    break;
   }
  }
  return index;
 }

}

此类构造函数需要两个参数,查询结果的list以及查询的所有属性名(这些属性名必须和报表界面的field名一致)

,使用方式如下:

1.导出pdf:

File reportFile = new File(getServletContext().getRealPath(
    "/reports/" + queryResult.getReportFileName() + ".jasper"));

  HibernateQueryResultDataSource dataSource = new HibernateQueryResultDataSource(
    queryResult.getList(parameters), queryResult.getFields());
  if (reportType.equals("pdf") || reportType.equals("")) {
   try {
    byte[] bytes = JasperRunManager.runReportToPdf(reportFile
      .getPath(), null, dataSource);
    response.setContentType("application/pdf");
    response.setContentLength(bytes.length);
    ServletOutputStream ouputStream = response.getOutputStream();
    ouputStream.write(bytes, 0, bytes.length);
    ouputStream.flush();
    ouputStream.close();

   } catch (Exception e) {
    e.printStackTrace();
   }
  }

2.导出excel,需要把poi-2.0-final-20040126.jar放进web的lib里:

try {

    JasperPrint print = JasperFillManager.fillReport(
      new FileInputStream(reportFile), null, dataSource);
    // JRXlsExporter t=null;
    JRXlsExporter jRXlsExporter = new JRXlsExporter();
    ByteArrayOutputStream xlsReport = new ByteArrayOutputStream();
    jRXlsExporter.setParameter(JRExporterParameter.JASPER_PRINT,
      print);
    jRXlsExporter.setParameter(JRExporterParameter.OUTPUT_STREAM,
      xlsReport);
    jRXlsExporter
      .setParameter(
        JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS,
        Boolean.TRUE);
    jRXlsExporter.setParameter(
      JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND,
      Boolean.TRUE);
    // jRXlsExporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME,ReportsConstants.bankDetailsHtml);

    // jRXlsExporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET,
    // Boolean.TRUE);

    jRXlsExporter.exportReport();
    byte[] bytes = xlsReport.toByteArray();

   
    response.setContentType("application/vnd.ms-excel");
    response.setContentLength(bytes.length);
    xlsReport.close();
    OutputStream ouputStream = response.getOutputStream();
    ouputStream.write(bytes, 0, bytes.length);
    ouputStream.flush();
    ouputStream.close();

   } catch (Exception e) {
    e.printStackTrace();
   }

posted @ 2007-02-06 12:31 dennis 阅读(3097) | 评论 (1)编辑 收藏

没办法直接设置可以采用变通手段来做:新建一个分组,组表达式写成new Integer($V{COLUMN_COUNT}.intValue()/?),?号用你所需要的数字来代替,代表每页记录数

posted @ 2007-02-06 12:30 dennis 阅读(649) | 评论 (0)编辑 收藏

 项目已经上线,昨天客户发现一个问题,某个操作取消不了,查看一下log,系统是websphere5.x,发现以下的异常:

E WLTC0033E: 在清除未解析 LocalTransactionContainment 时,资源 jdbc/oa回滚。
[07-1-15 17:37:09:280 CST] 57961377 LocalTranCoor E WLTC0032E: 一个或多个资源回滚。一个未解析的 LocalTransactionContainment 有一个未解析的回滚操作。
[07-1-15 17:37:09:280 CST] 57961377 WebAppTransac E WTRN0043I: 由于 setRollbackOnly,本地事务回滚。
[07-1-15 17:37:09:296 CST] 57961377 WebGroup      E SRVE0026E: [Servlet 错误]-[LocalTransaction rolled-back due to setRollbackOnly]:com.ibm.ws.LocalTransaction.RolledbackException
    at com.ibm.ws.LocalTransaction.LocalTranCoordImpl.cleanup(LocalTranCoordImpl.java(Compiled Code))
    at com.ibm.ws.webcontainer.webapp.WebAppTransactionCollaborator.postInvoke(WebAppTransactionCollaborator.java(Compiled Code))
    at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.dispatch(WebAppRequestDispatcher.java(Compiled Code))
    at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.forward(WebAppRequestDispatcher.java(Compiled Code))
    at com.ibm.ws.webcontainer.srt.WebAppInvoker.doForward(WebAppInvoker.java(Compiled Code))
    at com.ibm.ws.webcontainer.srt.WebAppInvoker.handleInvocationHook(WebAppInvoker.java(Compiled Code))
    at com.ibm.ws.webcontainer.cache.invocation.CachedInvocation.handleInvocation(CachedInvocation.java(Compiled Code))
    at com.ibm.ws.webcontainer.cache.invocation.CacheableInvocationContext.invoke(CacheableInvocationContext.java(Compiled Code))
    at com.ibm.ws.webcontainer.srp.ServletRequestProcessor.dispatchByURI(ServletRequestProcessor.java(Compiled Code))
    at com.ibm.ws.webcontainer.oselistener.OSEListenerDispatcher.service(OSEListener.java(Compiled Code))
    at com.ibm.ws.webcontainer.http.HttpConnection.handleRequest(HttpConnection.java(Compiled Code))
    at com.ibm.ws.http.HttpConnection.readAndHandleRequest(HttpConnection.java(Compiled Code))
    at com.ibm.ws.http.HttpConnection.run(HttpConnection.java(Compiled Code))
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java(Compiled Code))



查了下代码,一开始没发现有什么问题,不过是4,5个增删操作(两张表以上)。把错误信息输入google搜索,挺多人碰到这个错误,有的说是websphere的bug,有的说要把AutoCommit设置为true.
websphere的事务处理确实有bug,不过我们已经打过补丁,把AutoCommit设置为true的话,与我们所需要的效果不同,毕竟需要这些操作在同一个事务内。昨天查了一个晚上没找到原因,今天一段一段地调试代码,让我发现问题了:
conn = ConnectionManager.getConnection();
conn.setAutoCommit(false);
在conn.commit()前,我进行了一个判断:

if(....){
  return;
}
conn.commit

直接return,导致后面的conn.commit()没有执行,事务不完整。修改成:
if(....){
  ...
  conn.commit();
  return;
}

所以这个异常的出现,很有可能是你的事务处理有问题,那条教训还是很有用的:一个方法最好不要有多个return语句。

posted @ 2007-02-06 12:27 dennis 阅读(1231) | 评论 (0)编辑 收藏

 这篇文章的想法来自于过去的两篇文章:《设计自己的MVC框架》《设计模式之事务处理》
链接:
http://www.javaresearch.org/article/59935.htm
http://www.javaresearch.org/article/59043.htm


代码下载同样在www.126.com的邮箱里,用户名 sharesources 密码 javafans

    本文只是学习性质的文章,我一开始的想法就是修改《设计模式之事务处理》,提供Annotation来提供事务支持,支持到方法级别。通过引入一个 @Transaction标注,如果被此标注的方法将自动享受事务处理。目的是学习下Annotation和加深下对声明式事务处理的理解。

    Annotation是JDK5引入的新特性,现在越来越多的框架采用此特性来代替烦琐的xml配置文件,比如hibernate,ejb3, spring等。对Annotation不了解,请阅读IBM网站上的文章,还有推荐javaeye的Annotation专栏:http: //www.javaeye.com/subject/Annotation

    代码的示例是一个简单的用户管理例子。

    首先,环境是mysql+jdk5+myeclipse5+tomcat5,在mysql中建立一张表adminusers:
    create table adminusers(id int(10) auto_increment not null primary key,
     name varchar(10) not null,
     password varchar(10) not null,
     user_type varchar(10));
    然后在tomcat下建立一个数据源,把代码中的strutslet.xml拷贝到tomcat安装目录下的 /conf/Catalina/localhost目录里,请自行修改文件中的数据库用户名和密码,以及数据库名称。另外,把mysql的 jdbc驱动拷贝到tomcat安装目录下的common/lib目录。这样数据源就建好了。在web.xml中引用:

   <resource-ref>
        <description>DB Connection</description>
        <res-ref-name>jdbc/test</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>
   
    我的例子只是在《设计模式之事务处理》的基础上改造的,在那篇文章里,我讲解了自己对声明式事务处理的理解,并利用动态代理实现了一个 TransactionWrapper(事务包装器),通过业务代理工厂提供两种版本的业务对象:经过事务包装的和未经过事务包装的。我们在默认情况下包装业务对象中的所有方法,但实际情况是,业务对象中的很多方法不用跟数据库打交道,它们根本不需要包装在一个事务上下文中,这就引出了,我们为什么不提供一种方式来配置哪些方法需要事务控制而哪些并不需要?甚至提供事务隔离级别的声明?很自然的想法就是提供一个配置文件,类似spring式的事务声明。既然JDK5已经引入Annotation,相比于配置文件的烦琐和容易出错,我们定义一个@Transaction的annotation来提供此功能。

    看下Transaction.java的代码:
    package com.strutslet.db;

    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    import java.sql.Connection;

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Transaction {
       //事务隔离级别,默认为read_committed
       public int level() default Connection.TRANSACTION_READ_COMMITTED    ;
    }

@Transaction 标注只有一个属性level,level表示事务的隔离级别,默认为Read_Committed(也是一般JDBC驱动的默认级别,JDBC驱动默认级别一般于数据库的隔离级别一致)。 @Target(ElementType.METHOD)表示此标注作用于方法级别, @Retention(RetentionPolicy.RUNTIME)表示在运行时,此标注的信息将被加载进JVM并可以通过Annotation的 API读取。我们在运行时读取Annotation的信息,根据隔离级别和被标注的方法名决定是否将业务对象的方法加进事务控制。我们只要稍微修改下 TransactionWrapper:

//TransactionWrapper.java
package com.strutslet.db;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;

import com.strutslet.exception.SystemException;

public class TransactionWrapper {

   
    public static Object decorate(Object delegate) {
        return Proxy.newProxyInstance(delegate.getClass().getClassLoader(),
                delegate.getClass().getInterfaces(), new XAWrapperHandler(
                        delegate));
    }

    static final class XAWrapperHandler implements InvocationHandler {
        private final Object delegate;

        XAWrapperHandler(Object delegate) {
            // Cache the wrapped delegate, so we can pass method invocations
            // to it.
            this.delegate = delegate;
        }

        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            Object result = null;
            Connection con = ConnectionManager.getConnection();
            //得到Transaction标注
            Transaction transaction = method.getAnnotation(Transaction.class);

            //如果不为空,说明代理对象调用的方法需要事务控制。
            if (transaction != null) {
                // System.out.println("transaction.." + con.toString());
                // 得到事务隔离级别信息
                int level = transaction.level();
                try {
                    if (con.getAutoCommit())
                        con.setAutoCommit(false);
                    //设置事务隔离级别
                    con.setTransactionIsolation(level);
                    //调用原始对象的业务方法
                    result = method.invoke(delegate, args);
                    con.commit();
                    con.setAutoCommit(true);
                } catch (SQLException se) {
                    // Rollback exception will be thrown by the invoke method
                    con.rollback();
                    con.setAutoCommit(true);
                    throw new SystemException(se);
                } catch (Exception e) {
                    con.rollback();
                    con.setAutoCommit(true);
                    throw new SystemException(e);
                }
            } else {
                result = method.invoke(delegate, args);
            }

            return result;
        }
    }
}

现在,看下我们的UserManager业务接口,请注意,我们是使用动态代理,只能代理接口,所以要把@Transaction标注是接口中的业务方法(与EJB3中的Remote,Local接口类似的道理):
package com.strutslet.demo.service;

import java.sql.SQLException;

import com.strutslet.db.Transaction;
import com.strutslet.demo.domain.AdminUser;

public interface UserManager {
    //查询,不需要事务控制
    public boolean checkUser(String name, String password) throws SQLException;

    //新增一个用户,需要事务控制,默认级别
    @Transaction
    public boolean addUser(AdminUser user) throws SQLException;

}

要把addUser改成其他事务隔离级别(比如oracle的serializable级别),稍微修改下:@Transaction(level=Connection.TRANSACTION_SERIALIZABLE)
public boolean addUser(AdminUser user) throws SQLException;

不准备详细解释例子的业务流程,不过是登录和增加用户两个业务方法,看下就明白。阅读本文前最好已经读过开头提过的两篇文章。我相信代码是最好的解释:)

posted @ 2007-02-06 12:24 dennis 阅读(991) | 评论 (0)编辑 收藏

     摘要:   阅读全文

posted @ 2007-02-06 11:54 dennis 阅读(2407) | 评论 (2)编辑 收藏

     摘要:   阅读全文

posted @ 2007-02-06 11:49 dennis 阅读(3380) | 评论 (0)编辑 收藏

     摘要: 《J2EE设计模式》学习笔记  阅读全文

posted @ 2007-02-06 11:47 dennis 阅读(1368) | 评论 (0)编辑 收藏

仅列出标题
共56页: First 上一页 48 49 50 51 52 53 54 55 56 下一页