??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲精品色午夜无码专区日韩,日批日出水久久亚洲精品tv,久久久青草青青亚洲国产免观 http://m.tkk7.com/WshmAndLily/category/10974.htmlzh-cnSun, 30 Dec 2007 01:47:59 GMTSun, 30 Dec 2007 01:47:59 GMT60用组件beanutils,dbutils化JDBC操作 http://m.tkk7.com/WshmAndLily/articles/171183.htmlsemovysemovyFri, 28 Dec 2007 06:33:00 GMThttp://m.tkk7.com/WshmAndLily/articles/171183.htmlhttp://m.tkk7.com/WshmAndLily/comments/171183.htmlhttp://m.tkk7.com/WshmAndLily/articles/171183.html#Feedback0http://m.tkk7.com/WshmAndLily/comments/commentRss/171183.htmlhttp://m.tkk7.com/WshmAndLily/services/trackbacks/171183.html    虽然现在出现了很多ORM框架Q可是还是有很多朋友也许q在使用JDBCQ就像我现在一P除了学习的时候在使用Hibernate、SpringcMq些优秀的框Ӟ工作时一直都在用JDBC。本文就单介l一下利用Jakarta Commons旗下beanutils、dbutils化JDBC数据库操作,以抛砖引玉,希望对像我一样在使用JDBC的朋友有所帮助?/p>

    下面分两部分简单介lbeanutils、dbutils在基于JDBC API数据库存取操作中的运用。第一部分显介lbeanutils在JDBC数据库存取操作中的运用,W二部分介绍dbutils在JDBC数据库存取操作中的运用,最后看看他们的优缺点,谈谈本h在项目运用过E中对他们的一点心得体会,仅供参考,其中有错误的地方希望大虾不吝赐教Q大家多多交共同进步?/p>

    一、Jakarta Commons beanutils

    Beanutils是操作Bean的锐利武器,其提q的BeanUtils工具cd以简单方便的d或设|Bean的属性,利用DynapdQ还可以在运行期创徏BeanQ符合懒人的习惯Q正如LazyDynaBeanQLazyDynaClass一P呵呵。这些用法已l有很多文章提及Q也可以参考apache的官Ҏ档?/p>

    对于直接利用JDBC API讉K数据库时Q这里针对的是返回结果集ResultSet的查询selectQ,大多数都是采用两U方式,一U是取出q回的结果集的数据存于Map中,另一U方式是Bean里。针对第二种方式QBeanutils里提供了ResultSetDynaClassl合DynaBean以及RowSetDynaClassl合DynaBean来简化操作。下面用以个单的例子展示一下beanutils的这两个cdJDBC数据库操作中的运用?/p>

    请在本机建立数据库publishQ我用的是MySQLQ在publish数据库中建立表book,脚本如下Q?/p>

CREATE TABLE book(

  id int(11) NOT NULL auto_increment,

  title varchar(50) character set latin1 NOT NULL,

  authors varchar(50) character set latin1 default NULL,

  PRIMARY KEY  (id)


)

    然后用你喜欢的编辑器建立一个类BeanutilsJDBCTestQ我们先用ResultSetDynaClass来处理,然后再用RowSetDynaClass来实现同Lc,之后看看他们之间有什么不同,用ResultSetDynaClass处理的源代码如下所C?

    然后用你喜欢的编辑器建立一个类BeanutilsJDBCTestQ我们先用ResultSetDynaClass来处理,然后再用RowSetDynaClass来实现同Lc,之后看看他们之间有什么不同,用ResultSetDynaClass处理的源代码如下所C?

package cn.qtone.test;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.Statement;

import java.util.Iterator;

import org.apache.commons.beanutils.DynaBean;

import org.apache.commons.beanutils.PropertyUtils;

import org.apache.commons.beanutils.ResultSetDynaClass;

public class BeanutilsJDBCTest{

       public static void main(String[] args) {

              Connection con = null;

              Statement st = null;

              ResultSet rs = null;

              try {

                     Class.forName("com.mysql.jdbc.Driver");

                     String url = "jdbc:mysql://127.0.0.1:3306/publish?useUnicode=true&characterEncoding=GBK";

                     con = DriverManager.getConnection(url, "root", "hyys");

                     st = con.createStatement();

                     rs = st.executeQuery("select * from book");

                     ResultSetDynaClass rsDynaClass = new ResultSetDynaClass(rs);

                     Iterator itr = rsDynaClass.iterator();

                     System.out.println("title-------------authors");

                     while (itr.hasNext()) {

                            DynaBean dBean = (DynaBean) itr.next();

                            System.out.println(PropertyUtils.getSimpleProperty(dBean,"title")

                                          + "-------------"+ PropertyUtils.getSimpleProperty(dBean, "authors"));

                     }


              } catch (Exception e) {

                     e.printStackTrace();


              } finally {

                     try {

                            if (rs != null) {

                                   rs.close();

                            }

                            if (st != null) {

                                   st.close();

                            }

                            if (con != null) {

                                   con.close();

                            }


                     } catch (Exception e) {

                            e.printStackTrace();

                     }

              }

       }

}

    用RowSetDynaClass处理的源代码如下所C?

package cn.qtone.test;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.Statement;

import java.util.Iterator;

import java.util.List;

import org.apache.commons.beanutils.DynaBean;

import org.apache.commons.beanutils.PropertyUtils;

import org.apache.commons.beanutils.RowSetDynaClass;

public class BeanutilsJDBCTest{

       public static void main(String[] args) {

              List rsDynaClass = rsTest();

              System.out.println("title ------------- authors ");

              Iterator itr = rsDynaClass.iterator();

              while (itr.hasNext()) {

                     DynaBean dBean = (DynaBean) itr.next();

                     try {

                            System.out.println(PropertyUtils.getSimpleProperty(dBean,"name")

                                          + "-------------"+ PropertyUtils.getSimpleProperty(dBean, "mobile"));

                     } catch (Exception e) {

                            // TODO 自动生成 catch ?/p>

                            e.printStackTrace();

                    }


              }


       }


       private static List rsTest() {

              Connection con = null;

              Statement st = null;

              ResultSet rs = null;

              try {

                     Class.forName("com.mysql.jdbc.Driver");

                     String url = "jdbc:mysql://127.0.0.1:3306/publish?useUnicode=true&characterEncoding=GBK";

                     con = DriverManager.getConnection(url, "root", "hyys");

                     st = con.createStatement();

                     rs = st.executeQuery("select * from book");

                     RowSetDynaClass rsdc = new RowSetDynaClass(rs);

                     return rsdc.getRows();

              } catch (Exception e) {

                     e.printStackTrace();

              } finally {

                     try {

                            if (rs != null) {

                                   rs.close();

                            }

                            if (st != null) {

                                   st.close();

                            }

                            if (con != null) {

                                   con.close();

                            }

                     } catch (Exception e) {

                            e.printStackTrace();

                     }

              }


              return null;

       }

}

    q两个方法输出的l果应该是一L。但是很昄W二U方式比W一U方式要好,它把数据讉K部分抽取出来攑ֈ一个方法中Q显得简单清晰?/p>

    其实在利用ResultSetDynaClassӞ必须在ResultSet{数据库资源关闭之前Q处理好那些数据Q你不能在资源关闭之后用DynaBeanQ否则就会抛出异常,异常是说不能在ResultSet之后存取数据Q具体的异常名我也忘了)Q当然你也可以采用以前的方式一个一个的把数据放到Map里,如果你一定要那样做,q是别用BeanutilsQ因没带l你什么好处。M利用ResultSetDynaClass你的E序的扩展性非帔R好?/p>

    从第二中方式可以看出Q利用RowSetDynaClass可以很好的解决上qResultSetDynaClass遇到的问题,RowSetDynaClass的getRows()ҎQ把每一行封装在一个DynaBean对象里,然后Q把说有的行攑ֈ一个List里,之后你就可以对返回的List里的每一个DynaBeanq行处理Q此外对于DynaBean你还可以采用标准的get/set方式处理Q当然你也可以用PropertyUtils. getSimpleProperty(Object bean, String name)q行处理?/p>

    从上面的分析中,你应该可以决定你应该使用ResultSetDynaClassq是RowSetDynaClass了?/p>

    虽然现在出现了很多ORM框架Q可是还是有很多朋友也许q在使用JDBCQ就像我现在一P除了学习的时候在使用Hibernate、SpringcMq些优秀的框Ӟ工作时一直都在用JDBC。本文就单介l一下利用Jakarta Commons旗下beanutils、dbutils化JDBC数据库操作,以抛砖引玉,希望对像我一样在使用JDBC的朋友有所帮助?/p>

    下面分两部分简单介lbeanutils、dbutils在基于JDBC API数据库存取操作中的运用。第一部分显介lbeanutils在JDBC数据库存取操作中的运用,W二部分介绍dbutils在JDBC数据库存取操作中的运用,最后看看他们的优缺点,谈谈本h在项目运用过E中对他们的一点心得体会,仅供参考,其中有错误的地方希望大虾不吝赐教Q大家多多交共同进步?/p>

    一、Jakarta Commons beanutils

    Beanutils是操作Bean的锐利武器,其提q的BeanUtils工具cd以简单方便的d或设|Bean的属性,利用DynapdQ还可以在运行期创徏BeanQ符合懒人的习惯Q正如LazyDynaBeanQLazyDynaClass一P呵呵。这些用法已l有很多文章提及Q也可以参考apache的官Ҏ档?/p>

    对于直接利用JDBC API讉K数据库时Q这里针对的是返回结果集ResultSet的查询selectQ,大多数都是采用两U方式,一U是取出q回的结果集的数据存于Map中,另一U方式是Bean里。针对第二种方式QBeanutils里提供了ResultSetDynaClassl合DynaBean以及RowSetDynaClassl合DynaBean来简化操作。下面用以个单的例子展示一下beanutils的这两个cdJDBC数据库操作中的运用?/p>

    请在本机建立数据库publishQ我用的是MySQLQ在publish数据库中建立表book,脚本如下Q?/p>

CREATE TABLE book(
  id int(11) NOT NULL auto_increment,
  title varchar(50) character set latin1 NOT NULL,
  authors varchar(50) character set latin1 default NULL,
  PRIMARY KEY  (id)
)

    然后用你喜欢的编辑器建立一个类BeanutilsJDBCTestQ我们先用ResultSetDynaClass来处理,然后再用RowSetDynaClass来实现同Lc,之后看看他们之间有什么不同,用ResultSetDynaClass处理的源代码如下所C?

    然后用你喜欢的编辑器建立一个类BeanutilsJDBCTestQ我们先用ResultSetDynaClass来处理,然后再用RowSetDynaClass来实现同Lc,之后看看他们之间有什么不同,用ResultSetDynaClass处理的源代码如下所C?

package cn.qtone.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Iterator;
import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.ResultSetDynaClass;
public class BeanutilsJDBCTest{
       public static void main(String[] args) {
              Connection con = null;
              Statement st = null;
              ResultSet rs = null;
              try {
                     Class.forName("com.mysql.jdbc.Driver");
                     String url = "jdbc:mysql://127.0.0.1:3306/publish?useUnicode=true&characterEncoding=GBK";
                     con = DriverManager.getConnection(url, "root", "hyys");
                     st = con.createStatement();
                     rs = st.executeQuery("select * from book");
                     ResultSetDynaClass rsDynaClass = new ResultSetDynaClass(rs);
                     Iterator itr = rsDynaClass.iterator();
                     System.out.println("title-------------authors");
                     while (itr.hasNext()) {
                            DynaBean dBean = (DynaBean) itr.next();
                            System.out.println(PropertyUtils.getSimpleProperty(dBean,"title")
                                          + "-------------"+ PropertyUtils.getSimpleProperty(dBean, "authors"));
                     }
              } catch (Exception e) {
                     e.printStackTrace();
              } finally {
                     try {
                            if (rs != null) {
                                   rs.close();
                            }
                            if (st != null) {
                                   st.close();
                            }
                            if (con != null) {
                                   con.close();
                            }
                     } catch (Exception e) {
                            e.printStackTrace();
                     }
              }
       }
}

    用RowSetDynaClass处理的源代码如下所C?

package cn.qtone.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.beanutils.RowSetDynaClass;
public class BeanutilsJDBCTest{
       public static void main(String[] args) {
              List rsDynaClass = rsTest();
              System.out.println("title ------------- authors ");
              Iterator itr = rsDynaClass.iterator();
              while (itr.hasNext()) {
                     DynaBean dBean = (DynaBean) itr.next();
                     try {
                            System.out.println(PropertyUtils.getSimpleProperty(dBean,"name")
                                          + "-------------"+ PropertyUtils.getSimpleProperty(dBean, "mobile"));
                     } catch (Exception e) {
                            // TODO 自动生成 catch ?br />                             e.printStackTrace();
                     }
              }
       }
       private static List rsTest() {
              Connection con = null;
              Statement st = null;
              ResultSet rs = null;
              try {
                     Class.forName("com.mysql.jdbc.Driver");
                     String url = "jdbc:mysql://127.0.0.1:3306/publish?useUnicode=true&characterEncoding=GBK";
                     con = DriverManager.getConnection(url, "root", "hyys");
                     st = con.createStatement();
                     rs = st.executeQuery("select * from book");
                     RowSetDynaClass rsdc = new RowSetDynaClass(rs);
                     return rsdc.getRows();
              } catch (Exception e) {
                     e.printStackTrace();
              } finally {
                     try {
                            if (rs != null) {
                                   rs.close();
                            }
                            if (st != null) {
                                   st.close();
                            }
                            if (con != null) {
                                   con.close();
                            }
                     } catch (Exception e) {
                            e.printStackTrace();
                     }
              }
              return null;
       }
}

    q两个方法输出的l果应该是一L。但是很昄W二U方式比W一U方式要好,它把数据讉K部分抽取出来攑ֈ一个方法中Q显得简单清晰?/p>

    其实在利用ResultSetDynaClassӞ必须在ResultSet{数据库资源关闭之前Q处理好那些数据Q你不能在资源关闭之后用DynaBeanQ否则就会抛出异常,异常是说不能在ResultSet之后存取数据Q具体的异常名我也忘了)Q当然你也可以采用以前的方式一个一个的把数据放到Map里,如果你一定要那样做,q是别用BeanutilsQ因没带l你什么好处。M利用ResultSetDynaClass你的E序的扩展性非帔R好?/p>

    从第二中方式可以看出Q利用RowSetDynaClass可以很好的解决上qResultSetDynaClass遇到的问题,RowSetDynaClass的getRows()ҎQ把每一行封装在一个DynaBean对象里,然后Q把说有的行攑ֈ一个List里,之后你就可以对返回的List里的每一个DynaBeanq行处理Q此外对于DynaBean你还可以采用标准的get/set方式处理Q当然你也可以用PropertyUtils. getSimpleProperty(Object bean, String name)q行处理?/p>

    从上面的分析中,你应该可以决定你应该使用ResultSetDynaClassq是RowSetDynaClass了?/p>

    未完待箋……



semovy 2007-12-28 14:33 发表评论
]]>
struts中实现文件下?/title><link>http://m.tkk7.com/WshmAndLily/articles/134531.html</link><dc:creator>semovy</dc:creator><author>semovy</author><pubDate>Sun, 05 Aug 2007 10:06:00 GMT</pubDate><guid>http://m.tkk7.com/WshmAndLily/articles/134531.html</guid><wfw:comment>http://m.tkk7.com/WshmAndLily/comments/134531.html</wfw:comment><comments>http://m.tkk7.com/WshmAndLily/articles/134531.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/WshmAndLily/comments/commentRss/134531.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/WshmAndLily/services/trackbacks/134531.html</trackback:ping><description><![CDATA[<font size=2>struts中实现文件下载的主要代码Q?/font> <p><font size=2>public ActionForward execute(ActionMapping mapping, ActionForm form,<br>   HttpServletRequest request, HttpServletResponse response) {<br>  String strFileName = "试文g.rar";<br>  File file = new File("具体路径" + strFileName);//<br>  if(file.exists()){<br>   try{<br>    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));<br>    byte[] buffer = new byte[1024];<br>    strFileName = java.net.URLEncoder.encode(strFileName, "UTF-8");//处理中文文g名的问题<br>    strFileName = new String(strFileName.getBytes("UTF-8"),"GBK");//处理中文文g名的问题<br>    response.reset();<br>    response.setCharacterEncoding("UTF-8");<br>    response.setContentType("application/x-rar-compressed");//不同cd的文件对应不同的MIMEcd<br>    response.setHeader("Content-Disposition","attachment; filename=" + strFileName);<br>    OutputStream os = response.getOutputStream();<br>    while(bis.read(buffer) > 0){<br>     os.write(buffer);<br>    }<br>    bis.close();<br>    os.close();<br>   }<br>   catch(Exception e){<br>    ......<br>   }<br>  }<br>  return mapping.getInputForward();<br> }</font></p> <p><font size=2>在Struts中的实现和在ASP.NET的实现类|q段代码是服务器上的文g以流的方式发送到客户端浏览器Q如果要是在U打开的方式的话还应将response.setHeader("Content-Disposition","attachment; filename=" + strFileName);改写为response.setHeader("Content-Disposition","inline; filename=" + strFileName);</font></p> <img src ="http://m.tkk7.com/WshmAndLily/aggbug/134531.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/WshmAndLily/" target="_blank">semovy</a> 2007-08-05 18:06 <a href="http://m.tkk7.com/WshmAndLily/articles/134531.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>commons fileuploadhttp://m.tkk7.com/WshmAndLily/articles/133866.htmlsemovysemovyWed, 01 Aug 2007 13:08:00 GMThttp://m.tkk7.com/WshmAndLily/articles/133866.htmlhttp://m.tkk7.com/WshmAndLily/comments/133866.htmlhttp://m.tkk7.com/WshmAndLily/articles/133866.html#Feedback0http://m.tkk7.com/WshmAndLily/comments/commentRss/133866.htmlhttp://m.tkk7.com/WshmAndLily/services/trackbacks/133866.html 

jsp文g上传大多采用采用开源项目来化处理,q里列出常用的两个jar包的实现Qƈq行比较Q说明他们的优缺点和应该注意的问题?/p>

Commons FileUploadQ可以在http://jakarta.apache.org/commons/fileupload/下蝲Q这个包需要Commons IO的支持,可以?a >http://jakarta.apache.org/commons/io/下蝲

com.oreilly.servletQ可以在http://www.servlets.com/cos/下蝲
Commons FileUpload提供三种文g上传处理方式QDiskFileUpload、ServletFileUpload和PortletFileUpload三种方式Q其中DiskFileUpload已经在javadoc下已l被标记期的ҎQ徏议用ServletFileUpload代替Q而PortletFileUpload需要配合portlet-api来用,所以这里我们只介绍ServletFileUploadQƈ且这个也是最常用的?/p>

com.oreilly.servlet也提供了三种文g上传的处理方式,MultipartWrapper、MultipartRequest和MultipartParser三种方式Q其中MultipartWrapper和MultipartRequest的用法基本相同,q且没有MultipartRequest提供的操作多Q所以这里介lMultipartRequestQMultipartParser和前两者有些不同,可以用来处理某些Ҏ情况Q例如表单中有两个同名的文g上传选择框?/p>

我们暂时UC面三U文件上传方式分别ؓQServletFileUpload方式QMultipartTestServletQ、MultipartRequest方式QMultipartTestServlet2Q、MultipartParser方式QMultipartTestServlet3Q?/p>

代码如下Q?br /> test.html

<%@ page language="java" import="java.util.*" contentType="text/html;charset=gbk" pageEncoding="gbk"%>
<html>
   <body>
     <form action="MultipartTestServlet" enctype="multipart/form-data" method="post">
      <input type="text" name="username" /><br />
      <input type="file" name="myfile" /><br/>
      <input type="file" name="myfile" /><br/>
      <input type="submit" />
     </form>
     <br/><br/><br/><br/>
     <form action="MultipartTestServlet2" enctype="multipart/form-data" method="post">
      <input type="text" name="username" /><br />
      <input type="file" name="myfile" /><br/>
      <input type="file" name="myfile" /><br/>
      <input type="submit" />
     </form>
     <br/><br/><br/><br/>
     <form action="MultipartTestServlet3" enctype="multipart/form-data" method="post">
      <input type="text" name="username" /><br />
      <input type="file" name="myfile" /><br/>
      <input type="file" name="myfile" /><br/>
      <input type="submit" />
     </form>
   </body>
</html>
MultipartTestServlet.java

package com.bug.servlet;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUpload;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.RequestContext;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.servlet.ServletRequestContext;

public class MultipartTestServlet extends HttpServlet {

public MultipartTestServlet() {
   super();
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

   request.setCharacterEncoding("gbk");
   RequestContext requestContext = new ServletRequestContext(request);
  
   if(FileUpload.isMultipartContent(requestContext)){
   
    DiskFileItemFactory factory = new DiskFileItemFactory();
    factory.setRepository(new File("c:/tmp/"));
    ServletFileUpload upload = new ServletFileUpload(factory);
    //upload.setHeaderEncoding("gbk");
    upload.setSizeMax(2000000);
    List items = new ArrayList();
     try {
      items = upload.parseRequest(request);
     } catch (FileUploadException e1) {
      System.out.println("文g上传发生错误" + e1.getMessage());
     }

    Iterator it = items.iterator();
    while(it.hasNext()){
     FileItem fileItem = (FileItem) it.next();
     if(fileItem.isFormField()){      
      System.out.println(fileItem.getFieldName() + "    " + fileItem.getName() + "    " + new String(fileItem.getString().getBytes("iso8859-1"), "gbk"));
     }else{
      System.out.println(fileItem.getFieldName() + "    " +
         fileItem.getName() + "    " +
         fileItem.isInMemory() + "     " +
         fileItem.getContentType() + "    " +
         fileItem.getSize());
     
      if(fileItem.getName()!=null && fileItem.getSize()!=0){
       File fullFile = new File(fileItem.getName());
       File newFile = new File("c:/temp/" + fullFile.getName());
       try {
        fileItem.write(newFile);
       } catch (Exception e) {
        e.printStackTrace();
       }
      }else{
       System.out.println("文g没有选择 ?文g内容为空");
      }
     }
     
    }
   }
}

}

MultipartTestServlet2.java

package com.bug.servlet;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;

public class MultipartTestServlet2 extends HttpServlet {

public MultipartTestServlet2() {
   super();
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

   //request.setCharacterEncoding("gbk");   不v作用
   System.out.println("start ");
   MultipartRequest multi = new MultipartRequest(request, "c:/tmp/", 2*1024*1024, "gbk", new DefaultFileRenamePolicy());
   System.out.println("start ");
   Enumeration filesName = multi.getFileNames();
   Enumeration paramsName = multi.getParameterNames();
   while(paramsName.hasMoreElements()){
    String paramName = (String) paramsName.nextElement();
    System.out.println(multi.getParameter(paramName));
   }
   while(filesName.hasMoreElements()){
    String fileName = (String) filesName.nextElement();
    System.out.println(multi.getFilesystemName(fileName) + "   " +
           multi.getOriginalFileName(fileName) + "   " +
           multi.getContentType(fileName) + "   ");
    if(multi.getFilesystemName(fileName)!=null && !multi.getFilesystemName(fileName).equals(""))
     System.out.println(multi.getFile(fileName).toURI());
   }
}

}

MultipartTestServlet3.java

package com.bug.servlet;

import java.io.File;
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.oreilly.servlet.multipart.FilePart;
import com.oreilly.servlet.multipart.MultipartParser;
import com.oreilly.servlet.multipart.ParamPart;
import com.oreilly.servlet.multipart.Part;

public class MultipartTestServlet3 extends HttpServlet {

public MultipartTestServlet3() {
   super();
}

public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

       MultipartParser mp = new MultipartParser(request, 2*1024*1024, false, false, "gbk");
       Part part;
       while ((part = mp.readNextPart()) != null) {
         String name = part.getName();
         if (part.isParam()) {
           ParamPart paramPart = (ParamPart) part;
           String value = paramPart.getStringValue();
           System.out.println("param: name=" + name + "; value=" + value);
         }
         else if (part.isFile()) {
           // it's a file part
           FilePart filePart = (FilePart) part;
           String fileName = filePart.getFileName();
           if (fileName != null) {
             long size = filePart.writeTo(new File("c:/tmp/"));
             System.out.println("file: name=" + name + "; fileName=" + fileName +
               ", filePath=" + filePart.getFilePath() +
               ", contentType=" + filePart.getContentType() +
               ", size=" + size);
           }
           else {
            System.out.println("file: name=" + name + "; EMPTY");
           }
           System.out.flush();
         }
       }
     }

}

web.xml中加?/p>

<servlet>
     <servlet-name>MultipartTestServlet</servlet-name>
     <servlet-class>com.bug.servlet.MultipartTestServlet</servlet-class>
   </servlet>
   <servlet>
     <servlet-name>MultipartTestServlet2</servlet-name>
     <servlet-class>com.bug.servlet.MultipartTestServlet2</servlet-class>
   </servlet>
   <servlet>
     <servlet-name>MultipartTestServlet3</servlet-name>
     <servlet-class>com.bug.servlet.MultipartTestServlet3</servlet-class>
   </servlet>
   <servlet-mapping>
     <servlet-name>MultipartTestServlet</servlet-name>
     <url-pattern>/MultipartTestServlet</url-pattern>
   </servlet-mapping>
   <servlet-mapping>
     <servlet-name>MultipartTestServlet2</servlet-name>
     <url-pattern>/MultipartTestServlet2</url-pattern>
   </servlet-mapping>
   <servlet-mapping>
     <servlet-name>MultipartTestServlet3</servlet-name>
     <url-pattern>/MultipartTestServlet3</url-pattern>
   </servlet-mapping>

我用q第一个例子的:

<!--注意:

1.当利用ServletUpload?lt;input type="radio" checked="checked">的元素会被认为是文g元素<input type="file"> 
从而会被解析出几个IFile出来

2.当用在struts的action?action的name不要讄,否则解析不出文g控g存在.因ؓactionform之前被解析掉?
-->

问题1、中文问题:
三种凡是都可以通过自己的方法来讄encoding为gbk开处理和解决中文问题,包括初始化的时候传入gbk作ؓ参数Q或是是初始化后通过setEncoding的方式来实现?br /> 另外ServletFileUpload方式也可以通过request.setCharacterEncoding("gbk");的方式来实现Q而其它两U方式不支持q种方式?/p>


问题2、文件大限?br /> ServletFileUpload方式可以讄文g大小限制Q也可以不用讄Q例子中的upload.setSizeMax(2000000)可以注释掉。如果设|upload.setSizeMax(-1)Q表明不限制上传的大。文档中没有指明默认的限制的多少Q我在不讄的情况下上传了一?M的东西,可以上传Q估计默认是不限制大的?br /> 而MultipartRequest方式和MultipartParser方式是必设|文件的上传文g的大限制的Q如果不讄Q默认是1M的大限制?/p>


问题3、文件上传发生错?br /> 如果文g上传q程中发生Q何错误,或者是文g的大超Z范围Q系l都抛出错误?br /> ServletFileUpload方式在upload.parseRequest(request)时抛出错?br /> MultipartRequest方式在new MultipartRequest(。。?时抛出错?br /> MultipartParser方式在new MultipartParser(。。?时抛出错?/p>


问题4、上传同名文件时Q他们保存到临时目录是的冲突问题
ServletFileUpload方式Q不会有冲突Q系l会把上传得文g按照一定的规则重新命名Q保证不会冲H?br /> MultipartParser方式Q会产生冲突Q系l会把文件按照上传时的文件名Q保存到临时目录下,如果两个用会同时上传文g名相同的文gQ那么就可能会生冲H,一Ҏ另一方的临时文gl替换了?br /> MultipartRequest方式Q在初始化时如果提供了一个名U{换策略,׃会有冲突Q如果不提桶Q就会有冲突。在上面的例子中我们提供了一个new DefaultFileRenamePolicy()保证了文件名不会有冲H发生?/p>


问题5Q表单中有两个同名的文g上传选择框,像我们例子中的myfile一P每个表单中有两个name=“myfile”的上传框
ServletFileUpload方式Q可以处理,可以分别得到他们各自的文Ӟ
MultipartRequest方式Q不可以处理Q会发生冲突Q会有一个上传框的文件覆盖了另外一个?br /> MultipartParser方式Q可以处理,可以分别得到他们各自的文Ӟ


备注Q?br /> 代码比较乱,主要是ؓ了说明他们间的区别。他们的详细C用说明还是要参考他的javadoc和domo?/p>

参考:
1?a >http://www.servlets.com/cos/#classes
2?a >http://jakarta.apache.org/commons/fileupload/apidocs/index.html
3?a >http://jakarta.apache.org/commons/fileupload/using.html
4?a >http://www.onjava.com/pub/a/onjava/2003/06/25/commons.html?page=3



semovy 2007-08-01 21:08 发表评论
]]>
ajax struts 动态多文g上传http://m.tkk7.com/WshmAndLily/articles/133251.htmlsemovysemovyMon, 30 Jul 2007 02:01:00 GMThttp://m.tkk7.com/WshmAndLily/articles/133251.htmlhttp://m.tkk7.com/WshmAndLily/comments/133251.htmlhttp://m.tkk7.com/WshmAndLily/articles/133251.html#Feedback1http://m.tkk7.com/WshmAndLily/comments/commentRss/133251.htmlhttp://m.tkk7.com/WshmAndLily/services/trackbacks/133251.htmlindex.jsp:

<%@ page language="java" pageEncoding="gbk"%>

<%@ taglib uri="<%@ taglib uri="<%@ taglib uri="<%@ taglib uri="

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html:html>
<head>
<title>
multiUploadDemo
</title>
</head>
<script language="javascript">
   var num = 0;
 
 function upload(){
  document.getElementById("status").innerHTML = "文g上传?..";
     multiUploadForm.submit();
   }

function additem(id)
{
 var row,cell,str;
 row = eval("document.all["+'"'+id+'"'+"]").insertRow();
 if(row != null )
    {
       cell = row.insertCell();
       str="<input type="+'"'+"file"+'"'+" name=uploadFile["+ num +"].file><input type="+'"'+"button"+'"'+" value="+'"'+"删除"+'"'+" onclick='deleteitem(this,"+'"'+"tb"+'"'+");'>"
      cell.innerHTML=str;
    }
 num++;
}
function deleteitem(obj,id)
{
 var rowNum,curRow;
 curRow = obj.parentNode.parentNode;
 rowNum = eval("document.all."+id).rows.length - 1;
 eval("document.all["+'"'+id+'"'+"]").deleteRow(curRow.rowIndex);
}
function callback(msg)
{
 document.getElementById("status").innerHTML = "文g上传完成...<br>" + msg;
}
</script>
<body bgcolor="#ffffff">
<div id="status"></div>
<html:form method="post" action="/multiUpload.do" enctype="multipart/form-data" target="hidden_frame">

<table id="tb">
</table>

</html:form>
<iframe name='hidden_frame' id="hidden_frame" style="display:none"></iframe>
<input type="button" name="btnAddFile" value="Add File" onclick="additem('tb')"/>
<input type="button" name="btnUpload" value="upload" onclick="upload()"/>
</body>
</html:html>

Struts config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "

<struts-config>
  <data-sources />
  <form-beans >
    <form-bean name="multiUploadForm" type="com.yourcompany.struts.MultiUploadForm" />

  </form-beans>

  <global-exceptions />
  <global-forwards />
  <action-mappings >
    <action
      attribute="multiUploadForm"
      name="multiUploadForm"
      path="/multiUpload"
      scope="request"
      type="com.yourcompany.struts.MultiUploadAction"
      validate="false" />

  </action-mappings>

  <message-resources parameter="com.yourcompany.struts.ApplicationResources" />
</struts-config>

Form bean:  MultiUploadForm.java


package com.yourcompany.struts;

import java.util.ArrayList;
import java.util.List;

import org.apache.struts.action.ActionForm;

public class MultiUploadForm extends ActionForm {
 private  List  myFiles; 
    public  MultiUploadForm(){ 
            myFiles  =  new  ArrayList(); 
            //Z能够在页面初始显CZ个file 
            myFiles.add(new  UploadFile()); 
    } 
    public  List  getMyFiles()  { 
            return  myFiles; 
    }         

//注意q个Ҏ的定?nbsp;

  public  UploadFile  getUploadFile(int  index){ 
            int  size  =  myFiles.size(); 
            if(index>size-1){ 
                    myFiles.add(new  UploadFile()); 
            } 
            return  (UploadFile)myFiles.get(index); 
    } 
    public  void  setMyFiles(List  myFiles)  { 
            this.myFiles  =  myFiles; 
    } 

}


ActionBean :MultiUploadAction.java

package com.yourcompany.struts;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;

public class MultiUploadAction extends Action {
 public ActionForward execute(ActionMapping mapping, ActionForm form,
   HttpServletRequest request, HttpServletResponse response) {
  MultiUploadForm multiUploadForm = (MultiUploadForm) form;
  List myFiles = multiUploadForm.getMyFiles();
  String fileStr = "";
  for (int i = 0; i < myFiles.size(); i++) {
   UploadFile uploadFile = (UploadFile) myFiles.get(i);
   FormFile file = uploadFile.getFile();

   if (file == null) {
    System.out.println("file  is  null");
   } else {

    // 能运行到q里Q就可以使用单个文g上传的方法进行上传了。@环而已
    System.out.println("filename:::" + file.getFileName());
    System.out.println("file  size:::" + file.getFileSize());
    fileStr += "filename:::" + file.getFileName() + "file  size:::" + file.getFileSize() ;
     
   }
  }
  //q回文本
  try
  {
   response.setHeader("ContentType", "text/html;charset=gbk");
   PrintWriter out = response.getWriter();
   out.write("<script>parent.callback('upload file success" + fileStr + "')</script>");
  }catch(IOException e)
  {
   e.printStackTrace();
  }

  return null;
 }

}


Bean: UploadFile.java

package com.yourcompany.struts;

import java.io.Serializable;

import org.apache.struts.upload.FormFile;

public class UploadFile implements Serializable {
  private  FormFile  file; 
     public  FormFile  getFile()  { 
             System.out.println("run  in  uploadFile.getFile()"); 
             return  file; 
     } 
     public  void  setFile(FormFile  file)  { 
             this.file  =  file; 
     } 
}



semovy 2007-07-30 10:01 发表评论
]]>
ajax struts url streamhttp://m.tkk7.com/WshmAndLily/articles/128059.htmlsemovysemovyWed, 04 Jul 2007 03:54:00 GMThttp://m.tkk7.com/WshmAndLily/articles/128059.htmlhttp://m.tkk7.com/WshmAndLily/comments/128059.htmlhttp://m.tkk7.com/WshmAndLily/articles/128059.html#Feedback0http://m.tkk7.com/WshmAndLily/comments/commentRss/128059.htmlhttp://m.tkk7.com/WshmAndLily/services/trackbacks/128059.htmlpublic class Example7Action extends Action {


  public ActionForward execute(ActionMapping mapping, ActionForm inForm, HttpServletRequest request, HttpServletResponse response) throws Exception {

    String feedURL = (String)request.getParameter("feedURL");

    if (feedURL == null || feedURL.equalsIgnoreCase("")) {
      return null; // Trivial error handling... if no URL sent in, essentially do nothing
    }
    feedURL = new URLCodec().decode(feedURL);

    // Go get the feed
    StringBuffer xml = new StringBuffer(4096);
    try {
      URL               u   = new URL(feedURL);
      InputStream       in  = u.openStream();
      InputStreamReader isr = new InputStreamReader(in);
      BufferedReader    br  = new BufferedReader(isr);
      String theLine;
      while ((theLine = br.readLine()) != null) {
        xml.append(theLine);
      }
    } catch (Exception e) {
      System.err.println("Example7Action Exception: " + e);
    }

    // Write the XML to response
    response.setContentType("text/xml");
    PrintWriter out = response.getWriter();
    out.println(xml);
    out.flush();

    return null;

  } // End execute()


}



semovy 2007-07-04 11:54 发表评论
]]>
Struts实现动态(不定数量Q多个文件上传[转蝲]http://m.tkk7.com/WshmAndLily/articles/114083.htmlsemovysemovyFri, 27 Apr 2007 06:52:00 GMThttp://m.tkk7.com/WshmAndLily/articles/114083.htmlhttp://m.tkk7.com/WshmAndLily/comments/114083.htmlhttp://m.tkk7.com/WshmAndLily/articles/114083.html#Feedback0http://m.tkk7.com/WshmAndLily/comments/commentRss/114083.htmlhttp://m.tkk7.com/WshmAndLily/services/trackbacks/114083.html主要代码如下  
 
Form部分Q? 
 
public  class  MultiUploadForm  extends  ActionForm  {  
       private  List  myFiles;  
       public  MultiUploadForm(){  
               myFiles  =  new  ArrayList();  
               //Z能够在页面初始显CZ个file  
               myFiles.add(new  UploadFile());  
       }  
       public  List  getMyFiles()  {  
               return  myFiles;  
       }          
 
   //注意q个Ҏ的定? 
 
     public  UploadFile  getUploadFile(int  index){  
               int  size  =  myFiles.size();  
               if(index>size-1){  
                       myFiles.add(new  UploadFile());  
               }  
               return  (UploadFile)myFiles.get(index);  
       }  
       public  void  setMyFiles(List  myFiles)  {  
               this.myFiles  =  myFiles;  
       }  
}  
 
Dataset部分Q? 
public  class  UploadFile  implements  Serializable  {  
       private  FormFile  file;  
       public  FormFile  getFile()  {  
               System.out.println("run  in  uploadFile.getFile()");  
               return  file;  
       }  
       public  void  setFile(FormFile  file)  {  
               this.file  =  file;  
       }  
}  
Action部分Q? 
public  class  MultiUploadAction  extends  Action  {  
       public  ActionForward  execute(ActionMapping  mapping,  ActionForm  form,  
                                                                 HttpServletRequest  request,  
                                                                 HttpServletResponse  response)  {  
               MultiUploadForm  multiUploadForm  =  (MultiUploadForm)  form;  
               List  myFiles  =  multiUploadForm.getMyFiles();  
               for(int  i  =0;i<myFiles.size();i++){  
                       UploadFile  uploadFile  =  (UploadFile)myFiles.get(i);  
                       FormFile  file  =  uploadFile.getFile();  
 
                       if(file==null){  
                               System.out.println("file  is  null");  
                       }  
                       else{  
 
                               //能运行到q里Q就可以使用单个文g上传的方法进行上传了。@环而已  
                               System.out.println("filename:::"  +  file.getFileName());  
                               System.out.println("file  size:::"  +  file.getFileSize());  
                       }  
               }  
 
               return  null;  
       }  
}  
 
JSP部分Q? 
 
<%@ page contentType="text/html; charset=GBK" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-nested.tld" prefix="nested" %>

<html:html>
<head>
<title>
multiUploadDemo
</title>
</head>
<script language="javascript" type="">
   var num = 0;
 
 function upload(){
     multiUploadForm.submit();
   }

function additem(id)
{
 var row,cell,str;
 row = eval("document.all["+'"'+id+'"'+"]").insertRow();
 if(row != null )
    {
       cell = row.insertCell();
       str="<input type="+'"'+"file"+'"'+" name=uploadFile["+ num +"].file><input type="+'"'+"button"+'"'+" value="+'"'+"删除"+'"'+" onclick='deleteitem(this,"+'"'+"tb"+'"'+");'>"
      cell.innerHTML=str;
    }
 num++;
}
function deleteitem(obj,id)
{
 var rowNum,curRow;
 curRow = obj.parentNode.parentNode;
 rowNum = eval("document.all."+id).rows.length - 1;
 eval("document.all["+'"'+id+'"'+"]").deleteRow(curRow.rowIndex);
}

</script>
<body bgcolor="#ffffff">
<html:form method="post" action="/multiUploadAction.do" enctype="multipart/form-data">

<table id="tb">
</table>

</html:form>
<input type="button" name="btnAddFile" value="Add File" onclick="additem('tb')"/>
<input type="button" name="btnUpload" value="upload" onclick="upload()"/>
</body>
</html:html> 
 struts-config.xml部分Q? 
 
   <form-beans>  
       <form-bean  name="multiUploadForm"  type="MultiUploadForm"  />  
   </form-beans>  
 
<action  name="multiUploadForm"  path="/multiUploadAction"  type="MultiUploadAction"  />  
 
以上只是对动态多文g上传部分q行了描qͼ只是一个Demo。大家可以根据自q需求变通的调整一下?nbsp; 



semovy 2007-04-27 14:52 发表评论
]]>
logic:equal,logic:present用法http://m.tkk7.com/WshmAndLily/articles/96727.htmlsemovysemovyTue, 30 Jan 2007 06:23:00 GMThttp://m.tkk7.com/WshmAndLily/articles/96727.htmlhttp://m.tkk7.com/WshmAndLily/comments/96727.htmlhttp://m.tkk7.com/WshmAndLily/articles/96727.html#Feedback0http://m.tkk7.com/WshmAndLily/comments/commentRss/96727.htmlhttp://m.tkk7.com/WshmAndLily/services/trackbacks/96727.html<logic:equal name="DeliverProveForm" property="userAction" value="create">
如果DeliverProveForm里的属性userAction的值等于create执行这ѝ?br /></logic:equal>

2.
<logic:present name="tipmsg">
如果在你的action中设|了tipmsg执行到q儿。如Qrequest.setAttribute("tipmsg","提示信息")或session.setAttribute("tipmsg","提示信息")
<bean:write name="tipmsg"/>
</logic:present> 

semovy 2007-01-30 14:23 发表评论
]]>
StrutsFileDownload-----DownloadActionhttp://m.tkk7.com/WshmAndLily/articles/91528.htmlsemovysemovyWed, 03 Jan 2007 06:05:00 GMThttp://m.tkk7.com/WshmAndLily/articles/91528.htmlhttp://m.tkk7.com/WshmAndLily/comments/91528.htmlhttp://m.tkk7.com/WshmAndLily/articles/91528.html#Feedback0http://m.tkk7.com/WshmAndLily/comments/commentRss/91528.htmlhttp://m.tkk7.com/WshmAndLily/services/trackbacks/91528.html StrutsFileDownload

A new DownloadAction was added in Struts 1.2.6 (see the [WWW] JavaDoc). This page is to show how to use it and has the following structure:

  1. Implementing a DownloadAction
    1. Implement the getStreamInfo() Method
    2. Implement the getBufferSize() Method
  2. Examples
    1. FileStreamInfo Example
    2. ResourceStreamInfo Example
    3. Byte Array Example
  3. Using the DownloadAction in your Web Pages
  4. Content Disposition
    1. Setting the Content Disposition
    2. Content Disposition Values

(!) FrankZ: Here is the sample webapp... downloadapp.zip Please note that this is my first ever attempt at editing a Wiki entry, so if I screwed anything up, I apologize in advance! Lastly, I skimmed through the content of this entry and didn't see anything blatantly wrong. I will try and proof it more thoroughly as time allows, but for now, in addition to the sample app, it should get anyone going in the right direction.

<!> niallp: Since I haven't actually used this class myself, I'm hoping that Martin, Frank or anyone else involved in the discussion/creation of this would take a look here to see if its OK.

(!) Details from this thread: [WWW] Mail Archive - Note that the link to the sample app at omnytex.com referenced in this thread is no longer valid. The sample app is attached to this Wiki page only, so download it from here downloadapp.zip

Implementing a DownloadAction

You need to extend org.apache.struts.actions.DownloadAction and implement the getStreamInfo() method. Optionally you can also override the getBufferSize() method if you require a different buffer size from the default.

Implement the getStreamInfo() Method

The getStreamInfo() method returns a StreamInfo object - which is an inner interface of the DownloadAction. The DownloadAction provides two concrete implementations (static inner classes) of the StreamInfo interface:

  • FileStreamInfo - Simplifies downloading of a file from disk - need to pass a java.io.File object to the constructor along with the content type.

  • ResourceStreamInfo - simplifies downloading of a web application resource - need to pass the ServletContext, path and content type to its constructor.

In the examples below, I have also provided a Byte array implementation of the StreamInfo interface.

Implement the getBufferSize() Method

The DownloadAction, by default, returns a buffer size of 4096. Optionally, this may be overriden to customize the size of the buffer used to transfer the file.

Examples

Below are three examples:

  • using a File

  • using a web application resource

  • using a byte array.

FileStreamInfo Example

Example of using the DownloadAction with a file. This example picks up the file name from the parameter attribute in the strust-config.xml action mapping.

import java.io.File;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DownloadAction;

public class ExampleFileDownload extends DownloadAction{

    protected StreamInfo getStreamInfo(ActionMapping mapping, 
                                       ActionForm form,
                                       HttpServletRequest request, 
                                       HttpServletResponse response)
            throws Exception {
        
        // Download a "pdf" file - gets the file name from the
        // Action Mapping's parameter
        String contentType = "application/pdf";
        File file          = new File(mapping.getParameter());

        return new FileStreamInfo(contentType, file);
        
    }

}

ResourceStreamInfo Example

Example of using the DownloadAction with a web application resource. This example picks up the web application resource path from the parameter attribute in the strust-config.xml action mapping.

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DownloadAction;

public class ExampleResourceDownload extends DownloadAction {

    protected StreamInfo getStreamInfo(ActionMapping mapping, 
                                       ActionForm form,
                                       HttpServletRequest request, 
                                       HttpServletResponse response)
            throws Exception {
        
        // Download a "jpeg" file - gets the file name from the
        // Action Mapping's parameter
        String contentType         = "image/jpeg";
        String path                = mapping.getParameter();
        ServletContext application = servlet.getServletContext();
        
        
        return new ResourceStreamInfo(contentType, application, path);
        
    }

}


Byte Array Example

Example of using the DownloadAction with a Byte Array.

This example creates a ByteArrayStreamInfo inner class which implements the StreamInfo interface.

(niallp: IMO we should include this ByteArrayStreamInfo in the implementation)

import java.io.IOException;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DownloadAction;

public class ExampleByteArrayDownload extends DownloadAction {

    protected StreamInfo getStreamInfo(ActionMapping mapping, 
                                       ActionForm form,
                                       HttpServletRequest request, 
                                       HttpServletResponse response)
            throws Exception {
        
        // Download a "pdf" file
        String contentType = "application/pdf";
        byte[] myPdfBytes  = null;              // Get the bytes from somewhere

        return new ByteArrayStreamInfo(contentType, myPdfBytes);
        
    }

    protected class ByteArrayStreamInfo implements StreamInfo {
        
        protected String contentType;
        protected byte[] bytes;
        
        public ByteArrayStreamInfo(String contentType, byte[] bytes) {
            this.contentType = contentType;
            this.bytes = bytes;
        }
        
        public String getContentType() {
            return contentType;
        }

        public InputStream getInputStream() throws IOException {
            return new ByteArrayInputStream(bytes);
        }
    }
}

Using the DownloadAction in your Web Pages

The last bit of the puzzle is how do I use this action?

You need to do two things:

  • As with any Struts action, you need to configure it in the struts-config.xml

  • Use it on your web page like any other link to a file

So for example you might have something like the following in your struts-config.xml:

    <action path="/downloadMyPdfFile" type="myPackage.ExampleFileDownload" parameter="/foo/bar.pdf">
    <action path="/downloadMyImage"   type="myPackage.ExampleResourceDownload" parameter="/images/myImage.jpeg">

The on your jsp page, you might use these in the following way:

    <html:img action="downloadMyImage" alt="My Image" height="400" width="400"/>

    <html:link action="downloadMyPdfFile">Click Here to See the PDF</html:link>

Note you may need to set the nocache value to false in the controller section of your struts config file. Nocache set to true prevented me from being able to use Internet Explorer to download the file succesfully; Firefox and Safari worked fine.

    <controller contentType="text/html;charset=UTF-8" locale="true" nocache="false" />

Content Disposition

Setting the Content Disposition

DownloadAction doesn't cater for setting the content dispositon header. The easiest way is set it in the getStreamInfo() method, for example...

public class ExampleFileDownload extends DownloadAction{


    protected StreamInfo getStreamInfo(ActionMapping mapping, 
                                       ActionForm form,
                                       HttpServletRequest request, 
                                       HttpServletResponse response)
            throws Exception {

        // File Name
        String fileName = mapping.getParameter();

        // Set the content disposition
        response.setHeader("Content-disposition", 
                           "attachment; filename=" + fileName);
        
        // Download a "pdf" file - gets the file name from the
        // Action Mapping's parameter
        String contentType = "application/pdf";
        File file          = new File(fileName);

        return new FileStreamInfo(contentType, file);
        
    }
}

Probably would want to play with the file name, to remove any path info first.

Content Disposition Values

You can set the content disposition to either download the file or open up in the browser:

  • To open up in the browser: "inline; filename=myFile.pdf"

  • To download: "attachment; filename=myFile.pdf"

Displaying images I always set the content disposition to the "inline" option.

NOTE: I'm not expert at this, just got it working by trial and error. I had problems and I'm seem to remember I had to play with setting the response headers to get it to work properly. There may also be browser issues - my app only has to work with IE. Anyone who knows more about this, feel free to amend this page.

FIX for IE: Content-Disposition Attachment Header Does Not Save File [WWW] link

last edited 2006-01-25 18:40:18 by WendySmoak



semovy 2007-01-03 14:05 发表评论
]]>
struts+MySQL实现囄的存储与昄http://m.tkk7.com/WshmAndLily/articles/88347.htmlsemovysemovySun, 17 Dec 2006 08:30:00 GMThttp://m.tkk7.com/WshmAndLily/articles/88347.htmlhttp://m.tkk7.com/WshmAndLily/comments/88347.htmlhttp://m.tkk7.com/WshmAndLily/articles/88347.html#Feedback0http://m.tkk7.com/WshmAndLily/comments/commentRss/88347.htmlhttp://m.tkk7.com/WshmAndLily/services/trackbacks/88347.html Z信息理pȝ中,需要管理用L个hw䆾照片。通常q种格式的照片只有几 K 到几?/span> K 大小Q保存在数据库中易于q行理和维护(如果攑֜文g夹下Ҏ发生误操作而引h据被修改或丢失)?/span>

功能设计Q?/span> l用h供一个上传的界面Qƈ讑֮上传文g的尺怸限。用户上传的照片先统一保存在一个时文件夹中,之后可以?/span> <img> 指向临时文g夹中的这个图片,让用户可以预览自׃传的照片。当所有的用户信息都收集完成后Q将囄和其他信息一q提交,保存到数据库中。保存成功以后,删除临时文g夹中的图片?/span>

实现步骤Q?/span>

我用的是从 struts 主页上下载的 struts-1.2.8-src Q其?/span> web/examples/ 目录下有一?/span> upload 的例子,E微修改了一下就直接拿过来用了。这是一?/span> JSP 面?/span> ActionForm ?/span> Action 的组合。下面分别列出各自的代码?/span>

upload.jsp 的部分源代码Q?/span>

<html:form action="/UploadSubmit" enctype="multipart/form-data">     

      请选择需要上传的照片 :

     <html:file property="theFile"/>

     <html:submit value=" 上传 "/>     

</html:form>

接下来需要在 ActionForm 中声明这个属性,q设|?/span> getter ?/span> setter ҎQ这部分源代码如下:

public class UploadForm extends ActionForm {

    protected FormFile theFile;

    public FormFile getTheFile() {

        return theFile;

    }

    public void setTheFile(FormFile theFile) {

        this.theFile = theFile;

    }

}

q个表单?/span> theFile 属性不?/span> String ?/span> boolean Q而是 org.apache.struts.upload.FormFile 。因为用户上传的是一个二q制文gQ?/span> HTTP 协议是以文本形式传输数据的,q就需要进行{换。打个比方,一辆汽车需要从甲地送到乙地Q但是两C间只有一条烦道,汽R没法开Q所以就想个办法在甲地把汽R先拆了,把零仉到乙地再重新组装成一辆汽车?/span> FormFile L是拆卸和组装的作用Q只不过它把拆卸、传输和l装的过E都装h了,我们看到的是一辆汽车从甲地开q?/span> FormFile Q过一会它׃乙地开出来?/span> J 我们要决定的只是把它停到什么地方,q就?/span> Action 的活了?/span>

按照功能设计Q?/span> Action 要把q部车停C个时文件夹下面Q这部分源代码如下:

public ActionForward execute(ActionMapping mapping,

                                 ActionForm form,

                                 HttpServletRequest request,

                                 HttpServletResponse response)

        throws Exception {

        if (form instanceof UploadForm) {

            UploadForm theForm = (UploadForm) form;

             // 获取上传的数据文?/span>

            FormFile file = theForm.getTheFile();

            // 获取文g?/span>

            String filename= file.getFileName();

            // 讄囄文g临时存放的\?/span>

            HttpSession session = request.getSession();

            String path = session.getServletContext().getRealPath("/") + "temp\\" + filename;

            try {

                // d文g中的数据Q获取二q制的数据流

             InputStream stream = file.getInputStream();

             // 把数据写到指定\?/span>

             OutputStream bos = new FileOutputStream(path);

             int bytesRead = 0;

             byte[] buffer = new byte[8192];

             while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {

                 bos.write(buffer, 0, bytesRead);

             }

             bos.close();

             logger.info("The file has been written to \""

                       + path + "\"");

                // 设计一个标讎ͼ说明用户已经上传q照片了?/span>               

             session.setAttribute("imageuploaded","true");

             session.setAttribute("filename",filename);

             // close the stream

             stream.close();

             bos.flush();

             bos.close();

            }catch (FileNotFoundException fnfe) {

                return null;

            }catch (IOException ioe) {

                return null;

            }

            //destroy the temporary file created

            file.destroy();

            // 转向下一个页?/span>

            return mapping.findForward("next");

        }

        //this shouldn't happen in this example

        return null;

    }

q样囄p攑֜ temp 的时文件夹下,昄的时候,只需要先查一下标讎ͼ看看用户是否上传了照片,如果已经上传Q就用一?/span> <img src=”?gt; 引用q个囄。还有一个小地方需要修改,因ؓ限定上传的是w䆾照片Q需要限定一个尺怸限,q个?/span> struts ?/span> upload 里面有现成的例子。先?/span> struts-config.xml 中配|这?/span> ActionForm ?/span> Action Q?/span>

<form-bean name="uploadForm"

 type="org.apache.struts.webapp.upload.UploadForm"/>

…?/span>

<action input="/pages/hr/error.jsp" name="uploadForm"

          path="/UploadSubmit" scope="request"

type="org.apache.struts.webapp.upload.UploadAction" validate="true">

   <forward name="next" path="/pages/hr/input.jsp"/>

</action>

…?/span>

<controller maxFileSize="2M" inputForward="true" />

在配|文件中已经看到 <action> ?/span> validate 属性被讄成?/span> true ”,q就是说表单提交之前先要对其内容q行验证Q这里我们要验证的就?/span> theFile 是否出?/span> controller 中设定的最大尺?/span> ?st1:chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="2" unitname="m">2M?/span> 。这个验证是通过 ActionForm ?/span> validate Ҏ来实现的Q?/span>

/**

     * Check to make sure the client hasn't exceeded the maximum allowed upload size inside of this validate method.

**/

    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(

                ActionMessages.GLOBAL_MESSAGE ,

                new ActionMessage("maxLengthExceeded"));

            errors.add(

                ActionMessages.GLOBAL_MESSAGE ,

                new ActionMessage("maxLengthExplanation"));

        }

        return errors;

    }

q里我估计有?/span> hook 之类的东西先截获了表单(应该?/span> controller 有关Q,?/span> theFile 的尺寸进行校验,然后把结果保存在 request scope 中?/span> Validate Ҏ只要查一下这个结果就可以了,如果寸标Q表单就不会被提交给 Action ?/span>

以上是完成了第一步,从用户那里拿到照片,q保存在临时文g夹当中。接下来要做的就是把照片保存?/span> MySQL 数据库中Q这个字D|用的?/span> MEDIUMBLOB Q因?/span> BLOB 最大长度是 216-1 字节Q大U?/span> 64K Q?/span> MEDIUMBLOB ?/span> 224-1 字节Q约 16M Q够用了。保存图片的主要代码如下Q?/span>

/**

 * 用L照片保存在数据表中,d成功后,删除临时文g夹中的图片?/span>

 * @param id 用户的n份号Q作为图片的标识?/span>

 * @param path 囄存放的\径。一般存攑֜一个时文件夹中?/span>

 * @return

 */

public static void saveImage(int id, String path) throws SQLException{

     String time = new java.util.Date().toString();

     Connection conn = null;

     PreparedStatement pstmt = null;

     boolean flag = false;

     // 获取q接

     try {

         conn = DbManager.getConnection();

         logger.info(time + ":saveImage() ?/span> DbManager 数据库连接池获取一个连接?/span> ");

     } catch (SQLException e) {

         // 如果没有能够?/span> DbManager 获取q接Q此ơ查询操作失?/span>

         logger.error(time + ": saveImage() 不能获取数据库连接,无法保存囄Q?/span> ");

         throw new SQLException(":saveImage() 不能获取数据库连接,无法保存囄Q?/span> ");

     }

    

         // 执行查询

     try {

         pstmt = conn.prepareStatement("UPDATE hr01 SET hr01_photo=? where hr01_id=?");

         FileInputStream in = new FileInputStream(path);

         pstmt.setBinaryStream(1,in,in.available());

         pstmt.setInt(2,id);        

         pstmt.executeUpdate();

         pstmt.executeUpdate("COMMIT");

         logger.info(" " + path + " 被添加到数据库中Q?/span> ");

         flag = true;           

     }catch(IOException e){

         logger.error(" " + path + " 文gd错误Q请查文件\径是否正?/span> ");

         throw new SQLException(" 无法保存囄Q?/span> ");

     }catch (SQLException ex) {

         logger.error(new java.util.Date() + "Error:Insert into table."

                 + ex.getMessage());        

         logger.error(" " + path +" 没有被保存到数据?/span> .");

         throw new SQLException(" " + path +" 没有被保存到数据?/span> .");

        

     } finally {

         try {

             pstmt.close();

             conn.close();

             logger.info("DbHrinfo saveImage() closed the connection created at " + time);

         } catch (SQLException e) {

         }

     }
>    

     // 囄d成功以后删除时文件夹中的囄数据

     if(flag == true){

         File file = new File(path);

         if(file.exists()){

             file.delete();

         }

     }

}

需要注意的?/span> pstmt.executeUpdate("COMMIT"); q行代码Q最初我q没有写q行Q程序能利执行Q日志中也显C“图片××被d到数据库中”,但是到库里一查询Q什么都没有?/span> SQL 语句被提交,但是数据库里面没有即时的昄Q估计是~冲区的作用Q它把我?/span> SQL 语句~存h而不是立x交给数据库。后来我?/span> textpad 里面单独执行q段代码Q发C用?/span> COMMIT ?/span> SQL 语句q卌提交了。这个地方还没有弄清楚,以后需要l研I?/span>

功能上做一点小改进Q用h交了照片以后Q浏览了一下觉得不满意Q只要还没有最l提交数据,当然允许他重C传一个照片。我们只需要在 <img src=”?gt; 下面提供一个“重新提交”的链接可以了。这个链接指向一?/span> AlterImageAction Q它的功能就是清?/span> session 中用户已l上传照片的标记Qƈ把刚才保存到临时文g夹中的照片删掉,{待用户重新上传。这部分代码如下Q?/span>

public ActionForward execute(ActionMapping mapping,

         ActionForm form,HttpServletRequest request,

         HttpServletResponse response)

throws IOException,ServletException{

        

     HttpSession session = request.getSession();

        //1. 从时文件夹中删除图?/span>

     String filename = (String)session.getAttribute("filename");

     String path = session.getServletContext().getRealPath("/")

+ "temp\\" + filename;

     File file = new File(path);

     if(file.exists()){

         file.delete();

         logger.info(" 文g " + path + " 已经被删?/span> ");

     }

    

     //2. ?/span> session 中清除上传图片的标记

    

     session.removeAttribute("imageuploaded");

     session.removeAttribute("filename");       

     return mapping.findForward("next");    

}

提交和保存到此功德圆满。下ơ用h要查询自q信息的时候,因ؓ临时文g夹中已经没有用户照片Q需要从数据库中d。用一?/span> ShowImageAction 来实现这个功能:

public ActionForward execute(ActionMapping mapping,

         ActionForm form, HttpServletRequest request,

         HttpServletResponse response)

throws IOException,ServletException{

     // 需要的情况下设|数据源

     if (!DbManager.hasSetDataSource()) {

         javax.sql.DataSource dataSource;

         try {

             dataSource = getDataSource(request);

             DbManager.setDataSource(dataSource);

         } catch (Exception e) {

             logger.error(e.getMessage());

             mapping.findForward("error");

         }

     }

    

     String photo_no = request.getParameter("photo_no");

     Connection conn = null;

     Statement stmt = null;

     // 获取q接

     try {

         conn = DbManager.getConnection();

         logger.info("showimage.jsp ?/span> DbManager 数据库连接池获取一个连接?/span> ");

     } catch (SQLException e) {

         // 如果没有能够?/span> DbManager 获取q接Q此ơ查询操作失?/span>

        logger.error(" showimage.jsp 不能获取数据库连接,无法d囄Q?/span> ");

     }

     try {

         // 准备语句执行对象

         stmt = conn.createStatement();

         String sql = " SELECT hr01_photo FROM hr01 WHERE hr01_id='" + photo_no + "'";

         ResultSet rs = stmt.executeQuery(sql);

         if (rs.next()) {

             InputStream in = rs.getBinaryStream("hr01_photo");

             int bytesRead = 0;

byte[] buffer = new byte[8192];

             response.setContentType("image/jpeg");

             response.setContentLength(in.available());

             OutputStream outs = response.getOutputStream();

                            

             while ((bytesRead = in.read(buffer, 0, 8192)) != -1) {

                 outs.write(buffer, 0, bytesRead);

             }

             outs.flush();

             in.close();

             rs.close();

         } else {

             rs.close();

             response.sendRedirect("error.jsp");

         }

     }catch(SQLException e){

        

     }finally {

         try{

         stmt.close();

         conn.close();

         }catch(SQLException ex){

            

         }

     }

     return null;

}

以前一直不清楚 execute Ҏ中的 response 参数的用法,因ؓ处理完以后总要 redirect 到另外一个页面,所以用的最多的是把数据保存在 session 中,在另一个页面里再取出来用。这ơ纯_Ҏ试验性地?/span> response 中写?/span> image/jpeg 内容Q然后返回一?/span> null 倹{最后的执行l果跟我预期的一P在浏览器中直接显CZ数据库中d的图片。那么接下来很好做了,只需要在 JSP 面中设|一?/span> <image> 标签Q指向这?/span> Action 可以,当然Q在q之前需要在 struts-config.xml 中先部vq个 Action Q?/span>

<action path="/ShowImage"

 type="software.action.ShowImageAction"></action>

然后?/span> JSP 面中引用这?/span> Action 来显C图?/span> :

<img src="/tibet/ShowImage.do?photo_no=666542">


< p>

semovy 2006-12-17 16:30 发表评论
]]>
html:messages与html:errorshttp://m.tkk7.com/WshmAndLily/articles/82531.htmlsemovysemovyTue, 21 Nov 2006 06:33:00 GMThttp://m.tkk7.com/WshmAndLily/articles/82531.htmlhttp://m.tkk7.com/WshmAndLily/comments/82531.htmlhttp://m.tkk7.com/WshmAndLily/articles/82531.html#Feedback0http://m.tkk7.com/WshmAndLily/comments/commentRss/82531.htmlhttp://m.tkk7.com/WshmAndLily/services/trackbacks/82531.html 1. ?/strong>     
    <html:messages> 标签?<html:errors> 标签有些怼之处, 也能够在|页上输出消? 不过两者的使用Ҏ有些差别.
2. 实例
    <html:messages id="message" message="true">
        <bean:write name="message"/>
    </html:messages>

3. 属?/font>
(1) name: 指定ActionMessages 对象存放?request ?session 范围内的属?key(即上面实例中的message). 标签处理cdҎq一属性key 来检索request ?session 范围?ActionMessages 对象.

(2) message: 指定消息的来? 如果为true , 则从request ?session 范围内检索出属?key?Globals.MESSAGE_KEY ?ActionMessages 对象, 此时 name 属性无? 如果为false ,则根据name 属性来索ActionMessages 对象, 如果此时没有讄name 属? 采用默认值Globals.ERROR_KEY. message 属性的默认gؓfalse.
(3) id: 用来命名从消息集合中索出的每?ActionMessage 对象, 它和<bean:write>标签的name 属性匹? 在上例中, <html:messages> 标签的处理类每次从消息集合中取出一?ActionMessages 对象, 把它命名ؓ "message", <bean:write> 标签接着把这个名?message" 的ActionMessage 对象的消息输出到|页?
4. 创徏ActionMessages 集合, 存入request ?/strong>
    ActionMessages actionMessages = new ActionMessages();
    actionMessages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("record.inserted"));
    saveMessages(request, actionMessages);



semovy 2006-11-21 14:33 发表评论
]]>
վ֩ģ壺 ҹ޸˾| պƵƵ| ޹Ʒ˾þ| ѹۿƵ| ձWWWѰ | ȫƵ߹ۿ| Av뾫Ʒ| ҹӰ߹ۿ| ޾Ʒ| һ| ŮڵƵվ| **aaaaaëƬ| AAAձ߲ѹۿ| ĻƷƵ| Av뾫Ʒ| ߹ۿAVÿո| ޵һҳĻ| ޹һҳwww| ޹һ| һĻ| ҹ侫Ʒպ| ֳִִӲƵ | һëƬȫѲ| Ʒ鶹˳վ| һɫëƬ| ɫaѿ| ޾ƷӰ| ޾ƷGVͬ| ŷݵһղsuv| avԴվavַ| Թ| ޾Ʒ456˳| һAVٸӰ| ۺavһ| ɫ18վWWW߲| vavaó| ŷ͵| avһվ²| ֳִִӲ3pƵ | þþ뾫Ʒպ| պ޵һҳ|