??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲欧美国产国产综合一区,亚洲欧洲日本在线,亚洲情侣偷拍精品http://www.tkk7.com/lmsun/category/2850.htmlzh-cnWed, 28 Feb 2007 20:35:47 GMTWed, 28 Feb 2007 20:35:47 GMT60JSP面查询昄常用模式http://www.tkk7.com/lmsun/articles/14127.htmlmy javamy javaMon, 26 Sep 2005 09:24:00 GMThttp://www.tkk7.com/lmsun/articles/14127.htmlhttp://www.tkk7.com/lmsun/comments/14127.htmlhttp://www.tkk7.com/lmsun/articles/14127.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/14127.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/14127.htmlhttp://www.javaresearch.org/article/showarticle.jsp?column=106&thread=8512

author: evan

email: evan_zhao@hotmail.com
    
背景Q?BR>1Q?nbsp;   需要将数据库查询结果在JSP中以列表方式昄
2Q?nbsp;   在一个良好的J2EE模式中数据库查询一般用DAO实现QData Access ObjectQ, JSP仅用于显C数?BR>
问题Q?BR>    通过JDBC ResultSet可获取查询结果(存在于数据库~冲区内Q,但在Statement、Connection关闭后ResultSet即不可用。因此需要一U方式取出所有查询结果ƈ传递至JSP面?BR>
解决Ҏ一Q?BR>    使用Value Object。将每条记录均封装成JavaBean对象Q把q些对象装入Collection传送给JSP昄。这U方法的~点是每一U查询都需要定义一个java classQƈ且将记录数据装成java对象时也需要很多额外的代码?BR>CZ代码Q?BR>
  1. //查询数据代码
  2.   Connection conn = DBUtil.getConnection();
  3.   PreparedStatement pst = null;
  4.   ResultSet rs = null;
  5.   try{
  6.     String sql=“select emp_code, real_name from t_employee where organ_id=??
  7.     pst = conn.preparedStatement(sql);
  8.     pst.setString(1, ?01?;
  9.     ResultSet rs = pst.executeQuery();
  10.     List list = new ArrayList();
  11.     Employee emp;
  12.     while (rs.next()){
  13.       emp = new Employee();
  14.       emp.setReakName(rs.getString(“real_name?);
  15.       emp.setEmpCode(rs.getString(“emp_code?);
  16.       ?
  17.       list.add(emp);
  18.     }
  19.     return list;
  20.   }finally{
  21.     DBUtil.close(rs, pst ,conn);
  22.   }
  23. //jsp昄部分代码
  24. <%
  25.   List empList = (List)request.getAttribute(“empList?;
  26.   if (empList == null) empList = Collections.EMPTY_LIST;
  27. %>
  28. ?
  29. <table  cellspacing="0" width=?0%?gt;
  30.     <tr>  <td>代码</td> <td>姓名</td>  </tr>
  31. <%
  32.   Employee emp;
  33.   for (int i=0; i< empList.size(); i++){
  34.     emp = (Employee) empList.get(i);
  35. %>
  36.     <tr>  
  37.       <td><%= emp.getEmpCode()%></td> 
  38.       <td><%= emp.getRealName()%></td>  
  39.     </tr>
  40. <%
  41.   }// end for
  42. %>
  43. </table>


解决Ҏ?/B>Q?BR>    遍历ResultSet取出所有数据封装进Collection?BR>具体做法Q?BR>1Q?nbsp;   生成一个List对象(List list = new ArrayList() )?BR>2Q?nbsp;   生成一个Map对象(Map map = new HashMap() )。用Map装一行数据,key为各字段名,value为对应的倹{?map.put(“USER_NAME?, rs.getString(“USER_NAME?)
3Q?nbsp;   第2 步生成的Map对象装入W?步的list对象?list.add(map) )?BR>4Q?nbsp;   重复2?步直到ResultSet遍历完毕
在DBUtil. resultSetToList(ResultSet rs)Ҏ中实C上述q程Q所有列名均使用大写Q,可参考用?BR>
CZ代码Q?BR>
  1. //查询数据部分代码Q?/FONT>
  2.   ?
  3.   Connection conn = DBUtil.getConnection();
  4.   PreparedStatement pst = null;
  5.   ResultSet rs = null;
  6.   try{
  7.     String sql=“select emp_code, real_name from t_employee where organ_id=??
  8.     pst = conn.preparedStatement(sql);
  9.     pst.setString(1, ?01?;
  10.     rs = pst.executeQuery();
  11.     List list = DBUtil. resultSetToList(ResultSet rs);
  12.     return list;
  13.   }finally{
  14.     DBUtil.close(rs, pst ,conn);
  15.   }
  16. //JSP昄部分代码
  17. <%
  18.   List empList = (List)request.getAttribute(“empList?;
  19.   if (empList == null) empList = Collections.EMPTY_LIST;
  20. %>
  21. ?
  22. <table  cellspacing="0" width=?0%?gt;
  23.     <tr>  <td>代码</td> <td>姓名</td>  </tr>
  24. <%
  25.   Map colMap;
  26.   for (int i=0; i< empList.size(); i++){
  27.     colMap = (Map) empList.get(i);
  28. %>
  29.   <tr>  
  30.     <td><%=colMap.get(“EMP_CODE?%></td> 
  31.     <td><%=colMap.get(“REAL_NAME?%></td>  
  32.   </tr>
  33. <%
  34.   }// end for
  35. %>
  36. </table>


解决Ҏ?/B>Q?BR>    使用RowSet?BR>RowSet是JDBC2.0中提供的接口,Oracle对该接口有相应实玎ͼ其中很有用的是oracle.jdbc.rowset.OracleCachedRowSet?nbsp;OracleCachedRowSet实现了ResultSet中的所有方法,但与ResultSet不同的是QOracleCachedRowSet中的数据在Connection关闭后仍然有效?BR>
oracle的rowset实现?A >http://otn.oracle.com/software/content.html的jdbc下蝲里有Q名U是ocrs12.zip

CZ代码Q?BR>
  1. //查询数据部分代码Q?/FONT>
  2.   import javax.sql.RowSet;
  3.   import oracle.jdbc.rowset.OracleCachedRowSet;
  4.   ?
  5.   Connection conn = DBUtil.getConnection();
  6.   PreparedStatement pst = null;
  7.   ResultSet rs = null;
  8.   try{…?
  9.     String sql=“select emp_code, real_name from t_employee where organ_id=??
  10.     pst = conn.preparedStatement(sql);
  11.     pst.setString(1, ?01?;
  12.     rs = pst.executeQuery();
  13.     OracleCachedRowSet ors = newOracleCachedRowSet();
  14.     //ResultSet中的数据装到RowSet?/FONT>
  15.     ors.populate(rs);
  16.     return ors;
  17.   }finally{
  18.     DBUtil.close(rs, pst, conn);
  19.   }
  20. //JSP昄部分代码
  21. <%
  22.   javax.sql.RowSet empRS = (javax.sql.RowSet) request.getAttribute(“empRS?;
  23. %>
  24. ?
  25. <table  cellspacing="0" width=?0%?gt;
  26.     <tr>  <td>代码</td> <td>姓名</td>  </tr>
  27. <%
  28.   if (empRS != nullwhile (empRS.next() ) {
  29. %>
  30.   <tr>  
  31.     <td><%= empRS.get(“EMP_CODE?%></td> 
  32.     <td><%= empRS.get(“REAL_NAME?%></td>  
  33.   </tr>
  34. <%
  35.   }// end while
  36. %>
  37. </table>


适用场合Q?BR>  Ҏ一使用于定制的查询操作
  Ҏ二适用于多条查询语句或需要对查询l果q行处理的情c?BR>  Ҏ三适合于单条查询语句,适用于快速开发?BR>

相关链接Q?BR>    如果需要分|C参考:JSP分页技术实?/A>
    如果查询l果需要生成WORD或者EXCELQ请参考:
使用jsp实现word、excel格式报表打印

附:DBUtil代码Q?BR>
  1. import java.util.List;
  2. import java.util.ArrayList;
  3. import java.util.Map;
  4. import java.util.HashMap;
  5. import java.util.Properties;
  6. import java.util.Collections;
  7. import java.sql.Connection;
  8. import java.sql.SQLException;
  9. import java.sql.ResultSet;
  10. import java.sql.ResultSetMetaData;
  11. import java.sql.Statement;
  12. import java.sql.PreparedStatement;
  13. import javax.naming.Context;
  14. import javax.naming.InitialContext;
  15. import javax.naming.NamingException;
  16. import javax.sql.DataSource;
  17. public class DBUtil{
  18.     private static final String JDBC_DATA_SOURCE = "java:comp/env/jdbc/DataSource";
  19.     /**
  20.      enableLocalDebug: 是否在本地调试?lt;br>
  21.      gؓtrue时如果查找数据源p|则用DriverManager与数据库建立q接Q?/FONT>
  22.      如果为false则只查找数据源徏立数据库q接?/FONT>
  23.      默认为false?lt;br>
  24.      可通过pȝ属性jdbc.enable_local_debug=true讄enableLocalDebug为trueQ启用本地调试:<br>
  25.      增加JVM parameterQ?nbsp;-Djdbc.enable_local_debug=true
  26.      */
  27.     private static boolean enableLocalDebug = false;
  28.     static{
  29.         enableLocalDebug = Boolean.getBoolean ("jdbc.enable_local_debug");
  30.     }
  31.     private static Context ctx = null;
  32.     private static javax.sql.DataSource ds = null;
  33.     private static void initDataSource() throws Exception{
  34.         // Put connection properties in to a hashtable.
  35.         if (ctx == null) {
  36.             ctx = new InitialContext();
  37.         }
  38.         if (ds == null) {
  39.             ds = (javax.sql.DataSource) ctx.lookup(JDBC_DATA_SOURCE);
  40.         }
  41.     }        
  42.     /**
  43.      * 查找应用服务器数据源Q从数据源中获得数据库连接?lt;br><br>
  44.      * 在本地调试时如果查找数据源失败ƈ且enableLocalDebug==true
  45.      * 则根据系l属性用java.sql.DriverManager建立q接?lt;br>
  46.      * 本地调试时可配置的系l属性如下:<br>
  47.      * <p>
  48.      *     #jdbc驱动E序?nbsp;<br>
  49.      *     jdbc.driver=<i>oracle.jdbc.driver.OracleDriver</i> <br> <br>
  50.      *     #数据库连接串<br>
  51.      *     jdbc.url=<i>jdbc:oracle:thin:@10.1.1.1:1521:ocrl</i> <br> <br>
  52.      *     #数据库用户名<br>
  53.      *     jdbc.username=<i>scott</i> <br> <br>
  54.      *     #数据库用户密?lt;br>
  55.      *     jdbc.password=<i>tiger</i> <br>
  56.      * </p>
  57.      * 可通过JVM参数讄上述pȝ属性:<br>
  58.      * -Djdbc.driver=oracle.jdbc.driver.OracleDriver 
  59.      *  -Djdbc.url=jdbc:oracle:thin:@10.1.1.1:1521:ocrl
  60.      *  -Djdbc.username=scott -Djdbc.password=tiger
  61.      * @return Connection
  62.      * @throws NamingException 如果数据源查扑֤?/FONT>
  63.      * @throws SQLException 如果建立数据库连接失?/FONT>
  64.      */
  65.     public static Connection getConnection() throws  SQLException{
  66.         try{
  67.             initDataSource();
  68.             return ds.getConnection();
  69.         }catch(SQLException sqle){
  70.             throw sqle;
  71.         }catch(Exception ne){
  72.             if (enableLocalDebug){
  73.                 return getTestConn();
  74.             }else{
  75.                 throw new RuntimeException(ne.toString());
  76.             }
  77.         }
  78.     }
  79.     //通过DriverManager建立本地试q接
  80.     private static Connection getTestConn(){
  81.       try {
  82.           String driver = System.getProperty("jdbc.driver");
  83.           System.out.println("jdbc.driver="+driver);
  84.           String url = System.getProperty("jdbc.url");
  85.           System.out.println("jdbc.url="+url);
  86.           String userName = System.getProperty("jdbc.username");
  87.           System.out.println("jdbc.username="+userName);
  88.           String password = System.getProperty("jdbc.password");
  89.           System.out.println("jdbc.password="+password);
  90.           Class.forName(driver).newInstance();
  91.           return java.sql.DriverManager.getConnection(url, userName, password);
  92.       }
  93.       catch (Exception ex) {
  94.         ex.printStackTrace();
  95.         throw new RuntimeException(ex.getMessage());
  96.       }
  97.     }
  98.     /**
  99.      * 查询结果封装成List?lt;br>
  100.      * List中元素类型ؓ装一行数据的MapQMap key为字D名Q大写)Qvalue为相应字D?/FONT>
  101.      * @param rs ResultSet
  102.      * @return List
  103.      * @throws java.sql.SQLException
  104.      */
  105.     public static List resultSetToList(ResultSet rs) throws java.sql.SQLException{
  106.         if (rs==nullreturn Collections.EMPTY_LIST;
  107.         ResultSetMetaData md = rs.getMetaData();
  108.         int columnCount = md.getColumnCount();
  109.         List list = new ArrayList();
  110.         Map rowData;
  111.         while (rs.next()){
  112.             rowData = new HashMap(columnCount);
  113.             for (int i=1; i<=columnCount; i++){
  114.                 rowData.put(md.getColumnName(i),rs.getObject(i));
  115.             }
  116.             list.add(rowData);
  117.         }
  118.         return list;
  119.     }
  120.     /**
  121.      * 关闭ResultSet、Statement和Connection
  122.      * @param rs ResultSet to be closed
  123.      * @param stmt Statement or PreparedStatement  to be closed
  124.      * @param conn Connection  to be closed
  125.      */
  126.     public static void close(ResultSet rs, Statement stmt, Connection conn){
  127.             if (rs != nulltry{
  128.                 rs.close();
  129.             }catch(java.sql.SQLException ex){
  130.                 ex.printStackTrace();
  131.             }
  132.             if (stmt != nulltry{
  133.                  stmt.close();
  134.             }catch(java.sql.SQLException ex){
  135.                 ex.printStackTrace();
  136.             }
  137.             if (conn != nulltry{
  138.                 conn.close();
  139.             }catch(java.sql.SQLException ex){
  140.                 ex.printStackTrace();
  141.             }
  142.     }
  143. }// end of DBUtil


my java 2005-09-26 17:24 发表评论
]]>
用JAVA实现一个分늱http://www.tkk7.com/lmsun/articles/14123.htmlmy javamy javaMon, 26 Sep 2005 08:59:00 GMThttp://www.tkk7.com/lmsun/articles/14123.htmlhttp://www.tkk7.com/lmsun/comments/14123.htmlhttp://www.tkk7.com/lmsun/articles/14123.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/14123.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/14123.htmlq里我以从一个用戯中查询用户信息ؓ例演C其用法Q?/P>

1.PageResultSet.java文g~译成class文gQƈ攑օ你的Web
应用E序的WEB-INF/classes/com/youngor/util目录下,可以对包名做相应修改?/P>

2.在你的ActioncM:
先从业务处理逻辑cM取出数据(ArrayList或Vector格式)
UserBO userBO=new UserBO();
Collection data=userBO.findUsers();//CZҎ
再得到当前页curPage和每记录数pageSize
int curPage = Integer.parseInt(request.getParameter(“cur_page?);
int pageSize=15;
然后生成PageResultSet对象
PageResultSet dataList = new PageResultSet(data, curPage, pageSize);
request.setAttribute("usersList", usersList);

3.在你的JSP面?
   <%
          PageResultSet pageResultSet=(PageResultSet)request.getAttribute("usersList");
   ArrayList usersList=(ArrayList)pageResultSet.getData();
   for(int i=0;i<usersList.size();i++)
   {
            UserEO userEO=(UserEO)usersList.get(i);%>
      <tr>
        <td><a href="view_user.do?id=<%=userEO.getId()%>"><%=userEO.getUsername()%></a></td>
        <td><%=userEO.getName()%></td>
        <td><%=userEO.getPhoneNumber()%></td>
        <td><%=userEO.getEmailBox()%></td>
        <td><%=userEO.getAddress()%></td>
        <td><%=userEO.getPostcode()%></td>
        </tr>
    <%}%>
    </table></td>
  </tr>
</table>

<!-- 昄分页工具?-->

<%=pageResultSet.getToolBar("list_users.do")%>


注意Q?BR>1、如果你觉得分页工具栏不能满你的要求,可以用PageResultSetcM的公共方?BR>first()、previous()、next()、last()定制自己的工hQƈ且,你还可以在PageResultSet中定义多个样式的工具栏;
2、getToolBar(String url)Ҏ接受带查询字W串的参敎ͼ比如“list_users.do?class_id=1“?/P>

 

//PageResultSet.java
package com.youngor.util;

import java.util.*;

/**
 * <p>Title: PageResultSet</p>
 *
 * <p>Description:分页c?</p>
 *
 * <p>Copyright: Copyright (c) 2004</p>
 *
 * <p>Company:youngor-studio(http://www.54youngor.com) </p>
 * @author:伍维?BR> * @version 1.0
 */
public class PageResultSet {
    /**
     * 分页数据
     */
    private Collection data = null;
    /**
     * 当前?BR>     */
    private int curPage;
    /**
     * 每页昄的记录数
     */
    private int pageSize;
    /**
     * 记录行数
     */
    private int rowsCount;
    /**
     * |
     */
    private int pageCount;

    public PageResultSet(Collection data) {
        this.data = data;
        this.curPage = 1;
        this.pageSize = 10;
        this.rowsCount = data.size();
        this.pageCount = (int) Math.ceil((double) rowsCount / pageSize);
    }

    public PageResultSet(Collection data, int curPage) {
        this.data = data;
        this.curPage = curPage;
        this.pageSize = 10;
        this.rowsCount = data.size();
        this.pageCount = (int) Math.ceil((double) rowsCount / pageSize);
    }

    public PageResultSet(Collection data, int curPage, int pageSize) {
        this.data = data;
        this.curPage = curPage;
        this.pageSize = pageSize;
        this.rowsCount = data.size();
        this.pageCount = (int) Math.ceil((double) rowsCount / pageSize);
    }

    /**
     * getCurPage:q回当前的页?BR>     *
     * @return int
     */
    public int getCurPage() {
        return curPage;
    }

    /**
     * getPageSizeQ返回分大?BR>     *
     * @return int
     */
    public int getPageSize() {
        return pageSize;
    }

    /**
     * getRowsCountQ返回总记录行?BR>     *
     * @return int
     */
    public int getRowsCount() {
        return rowsCount;
    }

    /**
     * getPageCountQ返回总页?BR>     *
     * @return int
     */
    public int getPageCount() {
        return pageCount;
    }
    /**
     * W一?BR>     * @return int
     */
    public int first() {
        return 1;
    }
    /**
     * 最后一?BR>     * @return int
     */
    public int last() {
        return pageCount;
    }
    /**
     * 上一?BR>     * @return int
     */
    public int previous() {
        return (curPage - 1 < 1) ? 1 : curPage - 1;
    }
    /**
     * 下一?BR>     * @return int
     */
    public int next() {
        return (curPage + 1 > pageCount) ? pageCount : curPage + 1;
    }

    /**
     * W一?BR>     * @return boolean
     */
    public boolean isFirst() {
        return (curPage==1)?true:false;
    }

    /**
     * W一?BR>     * @return boolean
     */
    public boolean isLast() {
        return (curPage==pageCount)?true:false;
    }
    /**
     * 获取当前|?BR>     * @return Collection
     */
    public Collection getData() {
        Collection curData = null;
        if (data != null) {
            int start = (curPage - 1) * pageSize;
            int end = 0;
            if (start + pageSize > rowsCount)
                end = rowsCount;
            else
                end = start + pageSize;
            ArrayList arrayCurData = new ArrayList();
            ArrayList arrayData = null;
            Vector vectorCurData = new Vector();
            Vector vectorData = null;
            boolean isArray = true;
            if (data instanceof ArrayList) {
                arrayData = (ArrayList) data;
                isArray = true;
            } else if (data instanceof Vector) {
                vectorData = (Vector) data;
                isArray = false;
            }
            for (int i = start; i < end; i++) {
                if (isArray) {
                    arrayCurData.add(arrayData.get(i));
                } else {
                    vectorData.add(vectorData.elementAt(i));
                }
            }
            if (isArray) {
                curData = (Collection) arrayCurData;
            } else {
                curData = (Collection) vectorCurData;
            }
        }
        return curData;
    }
    /**
     * 获取工具?BR>     * @return String
     */
    public String getToolBar(String fileName){
        String temp="";
        if(fileName.indexOf("?")==-1)
        {
            temp="?";
        }
        else
        {
            temp="&";
        }
        String str="<form method='post' name='frmPage' action='"+fileName+"'>";
        str+="<p align='center'>";
        if(isFirst())
            str+="首页 上一?amp;nbsp;";
        else
        {
            str+="<a href='"+fileName+temp+"cur_page=1'>首页</a>&nbsp;";
            str+="<a href='"+fileName+temp+"cur_page="+(curPage-1)+"'>上一?lt;/a>&nbsp;";
        }
        if(isLast())
            str+="下一?N&nbsp;";
        else
        {
            str+="<a href='"+fileName+temp+"cur_page="+(curPage+1)+"'>下一?lt;/a>&nbsp;";
            str+="<a href='"+fileName+temp+"cur_page="+pageCount+"'>N</a>&nbsp;";
        }
        str+="&nbsp;?lt;b>"+rowsCount+"</b>条记?amp;nbsp;";
        str+="&nbsp;转到<select name='page' onChange=\"location='"+fileName+temp+"cur_page='+this.options[this.selectedIndex].value\">";
        for(int i=1;i<=pageCount;i++)
        {
            if(i==curPage)
                str+="<option value='"+i+"' selected>W?+i+"?lt;/option>";
            else
                str+="<option value='"+i+"'>W?+i+"?lt;/option>";
        }
        str+="</select></p></form>";
        return str;
    }
}



my java 2005-09-26 16:59 发表评论
]]>
Security for J2EE Applicationshttp://www.tkk7.com/lmsun/articles/13618.htmlmy javamy javaWed, 21 Sep 2005 03:14:00 GMThttp://www.tkk7.com/lmsun/articles/13618.htmlhttp://www.tkk7.com/lmsun/comments/13618.htmlhttp://www.tkk7.com/lmsun/articles/13618.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/13618.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/13618.htmlListing 1

   <html>
   <head>
   </head>
   <body onLoad="document.myForm.submit()">
   <form action="https://loginserver.yourcorp.com/webapp/login
   servlet" name="myForm" method="POST">
   <input type="hidden" name="key" value="!@#$EncryptedString!@#$">
   </form>
   </body>
   </html>


Listing 2

<html>
<head>
<title>Hello World
<SCRIPT language="JavaScript" SRC="https://partner1/servlet/LCMMSServlet/login?data=ALKSDFJQWER...JLQKWE">
</SCRIPT>
<SCRIPT language="JavaScript"
SRC="https://partner2/servlet/LCMMSServlet/login?data=ALKSDFJQWER...JLQKWE">
</SCRIPT>
<SCRIPT language="JavaScript">
function postForm() {
   document.myForm.submit( );
}
</SCRIPT>
</head>

<body bgcolor=#FFFFFF onLoad="postForm()">
<form action="https://myserver/servlet/LCMMSServlet/authenticated"
method="POST" name="myForm">
<input type="hidden" name="data" value="ALKSDFJQWER...JLQKWE">
<input type="hidden" name="url" value="/requested/url?param1=val1¶m2=val2">
</form>
</body>
</html> 



Listing 3

<FRAMESET ROWS="100%,0%,0%" onLoad="submitViewableFrameForm()">
    <FRAME NAME="viewable" SRC="TempFrame.jsp">
    <!--The frame below logs in the browser to partner1 -->
    <FRAME NAME="setPartner1cookie"

SRC="https://partner1:7002/servlet/LCMMSServlet/login?data=ALKSDFJQWER...JLQKWE">


    <!--The frame below logs in the browser to partner2 -->
    <FRAME NAME="setPartner2cookie"

SRC="https://partner2:7002/servlet/LCMMSServlet/login?data=ALKSDFJQWER...JLQKWE">
</FRAMESET>



Listing 4

<html>
<head>
</head>
<body bgcolor=#FFFFFF>
Put some text here like "Logging in...Please wait."
<form action="https://myserver/servlet/LCMMSServlet/authenticated"
                method="POST" name="myForm" target="_top">
<input type="hidden" name="data" value="ALKSDFJQWER...JLQKWE">
<input type="hidden" name="url" value="/requested/url?param1=val1¶m2=val2">
</form>
</body>
</html>



Listing 5

CryptTool ct = CryptToolFactory.getCryptTool( ... );
Properties p = new Properties ( );
... //Get user Id
String userId = ...;
p.setProperty ("uid",userId);
p.setProperty("anotherProp", someValue);


//The String returned is a hex encoded ciphertext
String encryptedInfo = ct.encrypt(p);
Cookie c = new Cookie ("SSO",encryptedInfo);
c.setMaxAge(-1);
c.setDomain(".yourDomain.com");
c.setPath("/");


//If this is a login server cookie and cookie has to be sent over SSL
c.setSecure(true);


//Send cookie to client
response.addCookie (c );



Listing 6

package jdj.sso.test;


import java.net.*;
import java.io.*;


public class HttPSocketClient {


   public static void main(String[] args) throws Exception {
        String host = null;
        int port = -1;
        String path = null;
        for (int i = 0; i < args.length; i++)
            System.out.println(args[i]);


        if (args.length < 3) {
            System.out.println(
                "USAGE: java HttPSocketClient " +
                "host port requestedfilepath");
            System.exit(-1);
        }
        try {
            host = args[0];
            port = Integer.parseInt(args[1]);
            path = args[2];
        } catch (IllegalArgumentException e) {
             System.out.println("USAGE: java HttPSocketClient " +
                 "host port requestedfilepath");
             System.exit(-1);
        }


        try {



            Socket socket = new Socket(host,port);


            PrintWriter out = new PrintWriter(
                                  new BufferedWriter(
                                  new OutputStreamWriter(
                                  socket.getOutputStream())));


            out.println("GET " + path + " HTTP/1.1");
            out.println();
            out.flush();


            BufferedReader in = new BufferedReader(
                                    new InputStreamReader(
                                    socket.getInputStream()));


            String inputLine;


            while ((inputLine = in.readLine()) != null)
                System.out.println(inputLine);


            in.close();
            out.close();
            socket.close();


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



Listing 7

grant CodeBase "file:./Login.jar" {
         permission java.security.AllPermission;
};


grant CodeBase "file:./HttpSocketClient.jar",
        Principal javax.security.auth.kerberos.KerberosPrincipal
                "your_kerb_username@your_realm" {


        permission java.net.SocketPermission "*", "connect";


        permission javax.security.auth.kerberos.ServicePermission
                "krbtgt/your_realm@your_realm",
                "initiate";


        permission javax.security.auth.kerberos.ServicePermission


"server_service_principal@your_realm",
                "initiate";
};

 



my java 2005-09-21 11:14 发表评论
]]>
利用 Jsp+Taglib+JavaBean 快速构?动态数据库查询模板http://www.tkk7.com/lmsun/articles/11744.htmlmy javamy javaThu, 01 Sep 2005 05:39:00 GMThttp://www.tkk7.com/lmsun/articles/11744.htmlhttp://www.tkk7.com/lmsun/comments/11744.htmlhttp://www.tkk7.com/lmsun/articles/11744.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/11744.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/11744.html阅读全文

my java 2005-09-01 13:39 发表评论
]]>
安装配置Jbosshttp://www.tkk7.com/lmsun/articles/11609.htmlmy javamy javaWed, 31 Aug 2005 02:51:00 GMThttp://www.tkk7.com/lmsun/articles/11609.htmlhttp://www.tkk7.com/lmsun/comments/11609.htmlhttp://www.tkk7.com/lmsun/articles/11609.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/11609.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/11609.html1?Jboss的配|安?BR>1.1、Jboss的下?/STRONG>
Jboss的下载地址为:http://www.jboss.org/。目前的最新版本是QJboss2.2.1。徏议你下蝲Jboss2.2.1和tomcat3.2.1集成的下载包Q这样避免了单个下蝲后两者之间配|的问题。下载地址是:http://prdownloads.sourceforge.net/jboss/JBoss-2.2.1_Tomcat-3.2.1.zip

下蝲完成后,解压C个目录,q个目录名ؓE:\program files\jb_tomQ这个目录名是笔者自定的Q。下面有如下子目?

E:\program files\jb_tom\jboss和E:\jb_tom\tomcat

注意Q这里的目录E微做了改动Q徏议你TOMCAT_HOME加到CLASSPATH中,否则E:\program files\jb_tom\jboss里的run_with_tomcat.batq个文g要做相应改动才能正常q行?BR>
1.2、配|运?/B>
在启动Jboss前应该先安装好JDKQ徏议安装JDK1.3以上的版本(目前最新的正式版本是JDK1.3.1Q,然后系l的Classpath讄好。Jboss不要M配置和修改,当然Q最好将TOMCAT_HOME加到Classpath中,q样QE:\program files\jb_tom\jboss里的run_with_tomcat.batq个文g前的TOMCAT_HOME可以去掉了?BR>
q行E:\program files\jb_tom\jboss里的run_with_tomcat.batq个文gQ这PTomcat端口?080QJboss?083Q运行http://localhost:8080/出现tomcat首页Q运行http://localhost:8083/出现无错误的空白页?BR>
2?试EJB
2.1、启动JBOSSQ?/B>
Ҏ么,q里׃多作描述了,因ؓ前面已经写过了^&^?BR>
2.2、下载ƈ配置EJB例程
到http://www.wodejia.net/softdownload/java/interestejb.zip下蝲interestejb.zipQ这是我们用于试的EJB例程。将压羃包解开Q出现如下目录:

interest/com

interest/docs

…?BR>
该目录下所有文件全部copy到jboss安装目录下的examples目录下,如果没有examples目录Q就自己建立一个,l构如下Q?BR>
E:\ program files\jb_tom \jboss\examples\interest...

文件E:\program files\jb_tom\jboss\examples\interest\interest.jar复制刎ͼE:\program files\jb_tom\jboss\deploy下?BR>
在Classpath中加入如下文Ӟe:\program files\jb_tom\tomcat\lib\servlet.jar;e:\program files\jb_tom\jboss\client\jboss-client.jar;e:\program files\jb_tom\jboss\client\jnp-client.jar;e:\program files\jb_tom\jboss\lib\ext\ejb.jar;e:\program files\jb_tom\jboss\examples\interest\interest-client.jar

Z试Client通过servlet调用EJBQ必dQ?E:\program files\jb_tom\jboss\examples\interest下EJB.class和EJB.java复制刎ͼ

E:\program files\jb_tom\tomcat\webapps\ROOT\WEB-INF\classes目录?BR>
目录E:\jb_tom\jboss\examples\interest\com以及此下的所有文仉复制到E:\program files\jb_tom\tomcat\webapps\ROOT\WEB-INF\classes下?BR>
重新启动JBOSS_TOMCAT?BR>
2.3、command下client试q行Q?/B>
command下,q入目录E:\ program files\jb_tom\jboss\examples\interest

java InterestClient

出玎ͼ

Got context

Got reference

Interest on 1000 units, at 10% per period, compounded over 2 periods is: 210.00000000000023

JbossH口出玎ͼ

[Interest] Someone called `calculateCompoundInterest!`

2.4、web下client通过Servlet试q行Q?/B>
http://localhost:8080/servlet/EJB

出玎ͼ

Interest on 1000 units, at 10% per period, compounded over 2 periods is: 210.00000000000023

JbossH口出玎ͼ

[Interest] Someone called `calculateCompoundInterest!`

到此已经成功了?

注意Q这里将JBoss-2.2.1_Tomcat-3.2.1.zip解压后复制到E:\program files\jb_tom目录?BR>

my java 2005-08-31 10:51 发表评论
]]>
关于打印http://www.tkk7.com/lmsun/articles/11407.htmlmy javamy javaMon, 29 Aug 2005 01:51:00 GMThttp://www.tkk7.com/lmsun/articles/11407.htmlhttp://www.tkk7.com/lmsun/comments/11407.htmlhttp://www.tkk7.com/lmsun/articles/11407.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/11407.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/11407.html1
方式Q采用css来控制打华ͼ提供一个专门的控制打印的css文gQ然后在需要打印的面的代码中该css文g引入
下面通过例子来讲解如何实现页面的打印Q?BR>1Q写控制打印的样式表文gprint.cssQ文件内容如下:
@media print {
header{display:none}
button{display:none}
textarea{display:none}
select{display:none}
.noprint{display:none;
 position: relative;
 right:0px}
input{position: relative;left:0px;
  right:19px;
  BORDER-TOP: 0px;
  BORDER-LEFT: 0px;
  BORDER-RIGHT: 0px;
  BORDER-BOTTOM: 0px;
  COLOR : #FFFFFF;
  display:""}
select{position: relative;left:-50px;
   border:0pt;
   vertical-align:justify;
   display:""}
  table{
    position: relative;left:-40px;
   MARGIN-TOP: 1px;
   MARGIN-BOTTOM: 1px;
   PADDING-BOTTOM: 1px;
   BORDER-TOP: 1px;
   BORDER-LEFT: 1px;
   BORDER-RIGHT: 1px;
   BORDER-BOTTOM: 1px;
   COLOR : #FFFFFF;  
   display:""
   }  
.print{position: relative;left:-50px;
   right:10px;
   display:""
   }
}
其中Q@media print中的print指定了需要用的讑֤Q就是—打印机Q网l打印机Q?BR>.noprint{display:none; position: relative; right:0px}
说明其上面的所有元素都不打华ͼ所以display属性设|ؓnone.
位置position属性设|ؓrelativeQ表C相对位|。如果不讄为relativeQ则打印出来的效果会和页面上的位|一模一P如果实需要和面一致的话,当然可以不设|成relative。Right属性以及它的DC打印出来的位置相对于页面原始位|的偏移方向以及偏移量,当然q可以是left.
Ҏ上面的定义,header,button,textarea和select是不打印的,当然q些都是Ҏ需要可以添加和修改的?BR>接下来就是需要打印的元素的定义了Q其各个属性的含义都是֐思义的,很容易理解,在此不做赘述Q只需要记住将display属性的D是ؓIZ””就可以了?BR>2Q在需要打印的面的代码中Q将该样式表文g引入Q?BR><head>
<link rel=stylesheet href="print.css">
……………………………?BR></head>
其中Qhref属性指定的是样式表文g的位|?BR>3Q在面代码中加入用打印API的代码,一般来说加?lt;body>…?.</body>之间卛_Q?BR><OBJECT ID="WebBrowser" WIDTH=0 HEIGHT=0 CLASSID="CLSID:8856F961-340A-11D0-A96B-00C04FD705A2"></OBJECT>
q段代码是必不可的Q不必了解其切含义?BR>4Q用js写执行打印动作的函数Q一个简单的例子如下Q?BR>function doPrint()
{
WebBrowser.ExecWB(6,6);
}
其中的WebBrowser.ExecWB(6,6);语句表示执行打印。还有其他的一些功能,如下Q?BR>WebBrowser.ExecWB(1,1) 打开
WebBrowser.ExecWB(2,1) 关闭现在所有的IEH口Qƈ打开一个新H口
WebBrowser.ExecWB(4,1) 保存|页
WebBrowser.ExecWB(6,6) 打印
WebBrowser.ExecWB(7,1) 打印预览
WebBrowser.ExecWB(8,1) 打印面讄
WebBrowser.ExecWB(10,1) 查看面属?
WebBrowser.ExecWB(15,1) 好像是撤销Q有待确?
WebBrowser.ExecWB(17,1) 全?
WebBrowser.ExecWB(22,1) h
WebBrowser.ExecWB(45,1) 关闭H体无提C?BR>5Q在面代码中添加打印按钮:
<input type=button value="toPrinter" onclick="doPrint()">
6Q调整页面元素,控制打印l节。具体做法是Q如果想打印某个面元素Q只需要将该元素放?lt;div class=print>?lt;/div>中;如果不想打印Q则该元素攑֜<div class=noprint>?lt;/div>中?/P>

做到以上几点Q一个简单的打印功能实CQ?BR>


2

<%@ page contentType="application/msword;charset=GBK" %>



my java 2005-08-29 09:51 发表评论
]]>
快速配|weblogic8.X的应用目?/title><link>http://www.tkk7.com/lmsun/articles/11069.html</link><dc:creator>my java</dc:creator><author>my java</author><pubDate>Thu, 25 Aug 2005 07:45:00 GMT</pubDate><guid>http://www.tkk7.com/lmsun/articles/11069.html</guid><wfw:comment>http://www.tkk7.com/lmsun/comments/11069.html</wfw:comment><comments>http://www.tkk7.com/lmsun/articles/11069.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/lmsun/comments/commentRss/11069.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/lmsun/services/trackbacks/11069.html</trackback:ping><description><![CDATA[我们知道在weblogic7.x之前Q安装完后weblogic会自动创建默认的应用目录DefaultWebApp。如果没有特别的需要,可以利用这个默认的应用目录布vWeb应用E序或者J2EEpȝ了。而在weblogic8.x之后版本中,它不会自动创建默认的应用目录。所以我们需要用Configuration Wizard来创q应用目录Q发布应用目录有两种ҎQ现分别介绍? <P>1.weblogic8.x安装 weblogic8.x有几个版本提供用,q且从这个版本出C中文版。例子中使用了英文版。weglogic安装很简单,只需要按默认g路下一步就OK了?</P> <P>2.创徏weblogic服务 安装成功后,依次点击”开始?>”BEA WebLogic Platform 8.1?>”Configuration Wizard”,启动”BEA WebLogic Configuration Wizard?选择”create a new weblogic configuration”,然后”next?在”template”选择”base weblogic server domain?然后”next?没有特别的需要就不修攚w认选择Q然后”next”,在这个界面上输入用户名、密码和创徏q个服务的描qͼ误住这个用户密码它是启动这个服务和q入服务控制台的帐号Q?然后”next”,选择jdk的版?然后”next”,在这个界面你可以修改创徏服务的目录和名称Q然后按”create”开始创建?</P> <P>3.创徏应用目录 创徏应用目录有两U方式分别介l如下: </P> <P>3.1 最单的应用目录创徏 当weblogic服务创徏成功后,再次打开“Configuration Wizard”,q次选择”extend and existing weblogic configuration(扩展weblogic配置)?然后”next?选择weblogic服务目录Q然后”next?在”Configuration Extensions”中N”DefaultWebApp”,然后以下取默认g路”next”直到”import”就OK了。默认应用目录一般在D:\bea\user_projects\applications\mydomain\DefaultWebApp(注:d:为我PCZ安装weblogic的盘W,读者根据安装目录进行查??</P> <P>试Q启动weblogic服务,然后输入<A href="http://localhost:7001/">http://localhost:7001</A>可以看Cl性页面了?</P> <P>3.2使用控制台创建应用目?当weblogic服务创徏成功?启动weblogic服务,然后在浏览器中输?A href="http://localhost:7001/console">http://localhost:7001/console</A> 在登录界面输入你创徏weblogic服务时的用户密码?</P> <P>a.创徏一个新目录做ؓ卛_发布的应用目录,我用d:\appweb做ؓ例了目录,在该目录下再创徏WEB-INF,在WEB-INF下面创徏web.xml文gQ目录结构ؓ </P> <P>appweb </P> <P>|__WEB-INF/web.xml </P> <P>web.xml内容一般是: </P> <P><?xml version="1.0" ?> <BR><!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "<A > <BR><web-app> <BR><welcome-file-list> <BR><welcome-file>index.html</welcome-file> <BR></web-app> </P> <P><BR>b.目录创徏完成后,在控制台的首,选择“Web Application Modules?>”Deploy a new Web Application Module... ?在”Location”下选择你刚才创建的appweb(注意q个目录一定要有WEB-INF目录Qƈ且在WEB-INF目录下一定要有web.xml文gQ否则不能够创徏应用目录)。选择后,点击”target module”,q回Q可以看到当前weblogic服务中依成功创徏的应用目录了。然后再创徏一个index.html文档攑֜appweb目录下,完成了应用目录的创建?</P> <P>试Q启动weblogic服务,然后输入<A href="http://localhost:7001/appweb/index.html">http://localhost:7001/appweb/index.html</A>可以看到自p|的面了?</P> <P><BR><BR>2<BR><BR>二、开始部|J2EE web目</P> <P>     Web目的部|采用Configuration Wizard工具。依ơ点几Z开始?>“BEA WebLogic Platform<BR>8.1?>“Configuration Wizard”,启动”BEA WebLogic Configuration Wizard”?/P> <P>     2.1 新徏weblogic domain<BR>         选择”新建weblogic配置”,</P> <P>         然后”下一步?在”模李쀝选择”base weblogic server domain?</P> <P>         然后”下一步?没有特别的需要就不修攚w认选择Q然后”下一步”,在这个界面上输入用户名、密码(如填写用户wangnewtonQ密码wangnewtonQ和创徏q个服务的描qͼ误住这个用户密码它是启动这个服务和q入服务控制台的帐号Q?/P> <P>         然后”下一步”,选择jdk的版?然后”下一步”,在这个界面你可以修改创徏服务的目录和配置名称Q然后按”创建”开始创建?/P> <P>         点击完成l束?/P> <P>     2.2 创徏应用目录Q创建应用目录有两种方式分别介绍如下</P> <P>         2.2.1Ҏ一Ql采用Configuration Wizard 创徏<BR>              q次选择”extend and existing weblogic configuration(扩展weblogic配置)?</P> <P>              然后“下一步?选择前面配置的weblogic配置目录mydomainQ然后“下一步?</P> <P>              在”Configuration Extensions”中N”DefaultWebApp”,</P> <P>              然后以下取默认g路”下一步”直到”导入”就OK了?BR>              默认应用目录一般在D:\bea\user_projects\applications\mydomain\DefaultWebApp(注:d:为我PCZ安装weblogic的盘W,读者根据安装目录进行查??</P> <P>              试Q启动weblogic服务,然后输入<A href="http://localhost:7001">http://localhost:7001</A>可以看Cl性页面了?/P> <P><BR>        2.2.2Ҏ二:使用控制台创建应用目?BR>             使用q个Ҏ最好先要有一个可以发布的web应用Q比如大家做q的Ztomcat的项目。没有的话至要有webapp\WEB-INF\web.xml文gQweb.xml文gcM于:<BR>webapp<BR>|__WEB-INF/web.xml </P> <P>web.xml内容一般是: <BR><?xml version="1.0" ?>  <BR><!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "<A > <BR><web-app> <BR><welcome-file-list> <BR><welcome-file>index.html</welcome-file> <BR></web-app></P> <P> </P> <P>             创徏好如上的文gl构和web.xml后,启动weblogic服务,完成后在览器中输入<A >http://127.0.0.1:7001/console</A></P> <P>             在登录界面输入你创徏weblogic服务时的用户密码QwangnewtonQ。然后sign inQ在下面的页面中选择“Web Application Modules?/P> <P>             点击后进入该界面Q点击Deploy a new Web Application Module...</P> <P>             在“Location”下选择你刚才创建的appweb(注意q个目录一定要有WEB-INF目录Qƈ且在WEB-INF目录下一定要有web.xml文gQ否则不能够创徏应用目录)。选择后,点击”target module”,</P> <P>             q回Q可以看到当前weblogic服务中依成功创徏的应用目录了。然后再创徏一个index.html文攑֜appweb目录下,完成了应用目录的创建?/P> <P>             试Q启动weblogic服务,然后输入<A >http://127.0.0.1:7001/webapp/index.html</A>可以看到自p|的面了?/P> <P><BR>             PSQ相Ҏ_Ҏ二是实际目中用最多的一U配|方法?BR>             l箋PSQ如何设|项目ؓ默认启动路径Q?BR>                 对于刚才创徏的应用目录,总要通过<A >http://127.0.0.1:7001/webapp/index.html</A>Q能否直接设|成通过<A >http://127.0.0.1:7001/index.html</A>可以讉K的方式呢Q?/P> <P>Ҏ是在webapp\WEB-INF下新Z个weblogic.xml文gQ?BR>webapp<BR>|__WEB-INF/weblogic.xml </P> <P>weblogic.xml内容一般是: <BR><!DOCTYPE weblogic-web-app PUBLIC "-//BEA Systems, Inc.//DTD Web Application 8.1//EN" "<A ><BR><weblogic-web-app><BR><context-root>/</context-root><BR></weblogic-web-app></P> <P> </P> <P>三、weblogic q接池的配置<BR>     实例背景QSQL-SERVER 2000的数据库 + JDBC3.0<BR>     3.1 配置q接?BR>         q入控制?console) 可以看到该界?Q然后点?Connetion Pools</P> <P>         点击后进入该界面Q点击configure a new JDBC Conneciton Pool </P> <P>         点击后显C界面 因ؓ是用SQL-SERVER 2000 所以选择MS SQL Server<BR> <BR>         选择后,选择 MicroSoft’s MS SQL Server Driver (type) Version 。。。[倒数W三个^-^]然后点击Continue</P> <P>         按页面要求填入相关信?/P> <P>         此步骤完成后Q进入该面</P> <P><BR>         点击 Test Driver Configuration Q如果是成功昄该页</P> <P>    点击Create and deploy,</P> <P>     3.2 配置数据?BR>           q入控制収ͼ点击date source。。?/P> <P>        点击后显C?点击 configure a new JDBC Data Source</P> <P>        点击后进入该?/P> <P>        以下步骤都是默认选择后显C?/P> <P>        <BR>         由此Q数据源配|成功了Q记住这里的JNDIName配置为MyJNDIQ稍后将会在E序中被使用?/P> <P> </P> <P>四、weblogic q接池测试程?BR>     Z方便Q采用一个简单jspE序q行q接池的试Q连接池使用h不但可以提高pȝ吞吐量,而且q接E序也是很简单的。一般大家手头上都会有专业的数据库连接组Ӟ把这个组件修Ҏ为weblogicq接池的lg也是很简单的Q只需要执行简单几行代码替换就ok了。但作ؓ新手Q可以通过q个jsp试刚才建立的连接池讄?/P> <P><%@ page contentType="text/html;charset=GBK" %> <BR><%@ page import= "java.sql.* " %> <BR><%@ page import= "javax.sql.* " %> <BR><%@ page import= "javax.naming.* "%> <BR><HTML><BR><HEAD><BR><TITLE> </TITLE><BR><META NAME="Generator" CONTENT="EditPlus2.11"><BR></HEAD><BR><BODY><BR><%<BR>// 从weblogic 8 文档抄来<BR>Context ctx = null;<BR>Hashtable ht = new Hashtable();<BR>ht.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");<BR>ht.put(Context.PROVIDER_URL,"t3://127.0.0.1:7001");<BR>// ht.put(Context.SECURITY_PRINCIPAL, "admin");<BR>// ht.put(Context.SECURITY_CREDENTIALS, "11111111"); Connection conn = null;<BR>Statement stmt = null;<BR>ResultSet rs = null;<BR>try {<BR>ctx = new InitialContext(ht);<BR>DataSource ds = (DataSource)ctx.lookup ("MyJNDI"); <BR>conn = ds.getConnection();<BR>stmt = conn.createStatement();<BR>stmt.execute("select * from accounts");<BR>rs = stmt.getResultSet(); <BR>while ( rs.next()){<BR>out.println( rs.getString(1)+"___");<BR>out.println( rs.getString(2)+"___");<BR>out.println( rs.getString(3)+"<br>");<BR>} <BR>stmt.close();<BR>stmt=null;<BR>conn.close(); conn=null; <BR>}catch (Exception e) {<BR>out.println("错误 !! ERR !" );<BR>}<BR>finally { <BR>try {<BR>ctx.close();<BR>} catch (Exception e) {<BR>out.println("ctx ERR !" ); } <BR>try {<BR>if (rs != null) rs.close();<BR>} catch (Exception e) {<BR>out.println("rs ERR !" ); } <BR>try {<BR>if (stmt != null) stmt.close();<BR>} catch (Exception e) {<BR>out.println("stmt ERR !" ); } <BR>try {<BR>if (conn != null) conn.close();<BR>} catch (Exception e) {<BR>out.println("conn ERR !" ); } }<BR>%> <BR></BODY><BR></HTML> </P> <P><BR> </P><img src ="http://www.tkk7.com/lmsun/aggbug/11069.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/lmsun/" target="_blank">my java</a> 2005-08-25 15:45 <a href="http://www.tkk7.com/lmsun/articles/11069.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>log4j的配|与使用http://www.tkk7.com/lmsun/articles/10908.htmlmy javamy javaWed, 24 Aug 2005 05:15:00 GMThttp://www.tkk7.com/lmsun/articles/10908.htmlhttp://www.tkk7.com/lmsun/comments/10908.htmlhttp://www.tkk7.com/lmsun/articles/10908.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/10908.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/10908.html1.把log4j-1.2.8.jar攑ֈ你的lib?a置好classpath
2.d配置文g.
配置文g取名log4j.propertiesQ直接放到WEB-INF/classes下即?BR>例如:
log4j.rootLogger=DEBUG, ROOT

log4j.appender.ROOT=org.apache.log4j.RollingFileAppender
log4j.appender.ROOT.File=MMQB_Debug_Info.log
log4j.appender.ROOT.MaxFileSize=200KB
log4j.appender.ROOT.MaxBackupIndex=5
log4j.appender.ROOT.layout=org.apache.log4j.PatternLayout
log4j.appender.ROOT.layout.ConversionPattern=[%d] %c %-5p - %m%n
#log4j.logger.com.webage.ejbs=INFO

3.在程序中
protected Log log = LogFactory.getLog(this.getClass().getName());
log.debug("debug infomation");


首先建立一个servlet
/*
 * 创徏日期 2005-4-4
 *
 * TODO 要更Ҏ生成的文件的模板Q请转至
 * H口 Q?首选项 Q?Java Q?代码样式 Q?代码模板
 */
package cn.wst.common.log4j;


 

/*
 * 创徏日期 2005-3-8
 *
 * 源文? MyLog4jInit.java
 */

 
import java.io.IOException;
 
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.apache.log4j.xml.DOMConfigurator;
import org.apache.log4j.PropertyConfigurator;

/**
 * 用于初始化Log4j
 *
 * @author wst
 * @version 1.0
 */
public class MyLog4jInit extends HttpServlet {
 
     public void init(ServletConfig config) throws ServletException {
         super.init(config);
         String prefix = getServletContext().getRealPath("/");
         String file = getInitParameter("log4j"); // if the log4j-init-file is ot
         System.out.println("--------  Log4J Start [AddressBook] --------- ");
         if ( file != null ) {
             DOMConfigurator.configure(prefix + file);
       //   PropertyConfigurator.configure(prefix+file);

         }
     }
 
     protected void doGet(HttpServletRequest request,
             HttpServletResponse response) throws ServletException, IOException {
     }
 
 }
 
然后在web-inf里面的最开头配|servlet
 <servlet>
    <servlet-name>MyLog4jInit</servlet-name>
    <servlet-class>cn.wst.common.log4j.MyLog4jInit</servlet-class>
   <init-param>
    <param-name>log4j</param-name>
  <param-value>WEB-INF/log4j.xml</param-value>
  </init-param>
   <load-on-startup>1</load-on-startup><!--log4j的初始化-->
 </servlet>
相应在web-inf下的log4j.xmlQ?BR><?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j=" <appender name="cn.wst.file.log"
  class="org.apache.log4j.RollingFileAppender">
  <param name="File" value="C:/addrLog.txt" />
  <param name="Append" value="false" />
  <layout class="org.apache.log4j.PatternLayout">
   <param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss} [%C:%M()]-[%p] %m%n" />
  </layout>
 </appender>

 <appender name="cn.wst.console.log"
  class="org.apache.log4j.ConsoleAppender">
  <layout class="org.apache.log4j.PatternLayout">
   <param name="ConversionPattern" value="%5p  (%F:%L) - %m%n" />
  </layout>
 </appender>
 <!--  use this to turn on debug to a rolling file. -->
 <root>
  <level value="info" />
  <appender-ref ref="cn.wst.console.log" />
  <appender-ref ref="cn.wst.file.log " />
 </root>
 
</log4j:configuration>

在程序中使用使用Q假讄名ؓFind_hotel_servletQ则
先证明全局变量static Logger logger = Logger.getLogger(Find_hotel_servlet.class.getName());
然后使用只要Find_hotel_servlet.logger.info(Q*Q*Q?可以了



my java 2005-08-24 13:15 发表评论
]]>
HttpClient and FileUpload--Jakarta Commons 下的工具http://www.tkk7.com/lmsun/articles/10453.htmlmy javamy javaThu, 18 Aug 2005 09:11:00 GMThttp://www.tkk7.com/lmsun/articles/10453.htmlhttp://www.tkk7.com/lmsun/comments/10453.htmlhttp://www.tkk7.com/lmsun/articles/10453.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/10453.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/10453.htmlAugust 2004

Discuss this Article


Adapted from:
Pro Jakarta Commons, by Harshad Oak
Publisher: Apress
ISBN: 1590592832

All communication over the Internet happens using a standard set of protocols, such as File Transfer Protocol (FTP), Simple Mail Transfer Protocol (SMTP), Post Office Protocol (POP), Hypertext Transfer Protocol (HTTP), and so on. HTTP is one of the most popular of these protocols and is integral to the World Wide Web. It is also a protocol that many of today’s applications have to be aware of and use wisely. If a Java application has to interact using HTTP, the Commons HttpClient component can make things a bit easier. Using this component, you do not have to worry about all the technicalities of the protocol but just concern yourself with the various classes and methods provided by the HttpClient component. In this article you will have a look at the capabilities of the HttpClient component and also some hands-on examples.

You will also have a quick look at the FileUpload component, which simplifies file-upload tasks on the server side. Finally, you will work through an example where you use HttpClient and FileUpload together.

NOTE For all server-based examples in this article, I have used Tomcat version 4.0.6; however, you should not have any problems if you use another server that supports servlets and Java Server Page (JSP) technology.

Table 9-1 shows the details for the components covered in this article.

Table 9-1. Component Details

Name Version Package
HttpClient 2.0-rc1 org.apache.commons.httpclient
FileUpload 1.0 org.apache.commons.fileupload


Introducing HttpClient

HttpClient is an attempt to provide a simple Application Programming Interface (API) that Java developers can use to create code that communicates over HTTP. If you are developing a Web browser or just an application that occasionally needs some data from the Web, HttpClient can help you develop the client code that will communicate over HTTP. As the name suggests, HttpClient is meant only for HTTP client code and cannot be used to, say, develop a server that processes HTTP requests.

I recommend you use HttpClient instead of using the java.net classes because HttpClient is easier to work with, it supports some HTTP features that java.net does not, and it has a vibrant community backing it. Visit http://www.nogoop.com/product_16.html#compare to compare HttpClient, java.net, and a couple of other APIs.

With a number of Commons components, the Javadocs are the only real documentation that exists. However, with HttpClient some good documentation exists beyond the Javadocs. A short tutorial at http://jakarta.apache.org/commons/httpclient/tutorial.html can get you started with HttpClient.

These are some of the important features of HttpClient:

  • Implements HTTP versions 1.0 and 1.1
  • Implements all HTTP methods, such as GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE
  • Supports communication using HTTPS and connections through HTTP proxies
  • Supports authentication using Basic, Digest, and NT LAN Manager (NTLM) methods
  • Handles cookies

You will now see the various elements of the HttpClient component and how they fall into place to get you talking over HTTP.

Using HttpClient

HttpClient uses the Commons Logging component, so the only dependency for HttpClient to work properly is that the commons-logging component Java Archive (JAR) file be present. Using HttpClient to handle most requirements is fairly simple. You just need to understand a few key classes and interfaces. The following sections present a simple example of sending a GET request and then explain the classes that play a role in how the example works.

Using the GET Method

The GET method is the most common method used to send an HTTP request. Every time you click a hyperlink, you send an HTTP request using the GET method. You will now see an example of sending a GET request using HttpClient based Java code. The code in Listing 9-1 sends a GET request to the URL http://localhost:8080/validatorStrutsApp/userInfo.do and has three request parameters, firstname, lastname, and email.

Listing 9-1. HttpClientTrial
package com.commonsbook.chap9;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.GetMethod;

public class SubmitHttpForm {

    private static String url =
         "http://localhost:8080/validatorStrutsApp/userInfo.do";

    public static void main(String[] args) {

        //Instantiate an HttpClient
        HttpClient client = new HttpClient();

        //Instantiate a GET HTTP method
        HttpMethod method = new GetMethod(url);

        //Define name-value pairs to set into the QueryString
        NameValuePair nvp1= new NameValuePair("firstName","fname");
        NameValuePair nvp2= new NameValuePair("lastName","lname");
        NameValuePair nvp3= new NameValuePair("email","email@email.com");

        method.setQueryString(new NameValuePair[]{nvp1,nvp2, nvp3});

        try{
            int statusCode = client.executeMethod(method);

            System.out.println("QueryString>>> "+method.getQueryString());
            System.out.println("Status Text>>>"
                  +HttpStatus.getStatusText(statusCode));

            //Get data as a String
            System.out.println(method.getResponseBodyAsString());

            //OR as a byte array
            byte [] res  = method.getResponseBody();

            //write to file
            FileOutputStream fos= new FileOutputStream("donepage.html");
            fos.write(res);

            //release connection
            method.releaseConnection();
        }
        catch(IOException e) {
            e.printStackTrace();
        }
    }
}

The output on executing this piece of code will depend on the response you get to your GET request.

The following steps take place in the class SubmitHttpForm to invoke the URL specified, including passing the three parameters as part of the query string, displaying the response, and writing the response to a file:

  1. You first need to instantiate the HttpClient, and because you have specified no parameters to the constructor, by default the org.apache.commons.httpclient.SimpleHttpConnectionManager class is used to create a new HttpClient. To use a different ConnectionManager, you can specify any class implementing the interface org.apache.commons.httpclient.HttpConnectionManager as a parameter to the constructor. You can use the MultiThreadedHttpConnectionManager connection manager if more than one thread is likely to use the HttpClient. The code would then be new HttpClient(new MultiThreadedHttpConnectionManager()).
  2. Next you create an instance of HttpMethod. Because HttpClient provides implementations for all HTTP methods, you could very well have chosen an instance of PostMethod instead of GetMethod. Because you are using an HttpMethod reference and not a reference of an implementation class such as GetMethod or PostMethod, you intend to use no special features provided by implementations such as GetMethod or PostMethod.
  3. You define name/value pairs and then set an array of those name/value pairs into the query string.
  4. Once the groundwork is complete, you execute the method using the HttpClient instance you created in step 1. The response code returned is based on the success or failure of the execution.
  5. You get the response body both as a string and as a byte array. The response is printed to the console and also written to a file named donepage.html.

    NOTE The class org.apache.commons.httpclient.HttpStatus defines static int variables that map to HTTP status codes.

In this example, you can see how easily you can fire a request and get a response over HTTP using the HttpClient component. You might have noted that writing such code has a lot of potential to enable testing of Web applications quickly and to even load test them. This has led to HttpClient being used in popular testing framework such as Jakarta Cactus, HTMLUnit, and so on. You can find in the documentation a list of popular applications that use HttpClient.

You used the GET method to send name/value pairs as part of a request. However, the GET method cannot always serve your purpose, and in some cases using the POST method is a better option.

Using the POST Method

Listing 9-2 shows an example where you enclose an Extensible Markup Language (XML) file within a request and send it using the POST method to a JSP named GetRequest.jsp. The JSP will just print the request headers it receives. These headers will show if the request got across properly.

Listing 9-2. Sending an XML File Using the POST Method
package com.commonsbook.chap9;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;

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

public class PostAFile {
    private static String url =
         "http://localhost:8080/HttpServerSideApp/GetRequest.jsp";

    public static void main(String[] args) throws IOException {
        HttpClient client = new HttpClient();
        PostMethod postMethod = new PostMethod(url);

        client.setConnectionTimeout(8000);

        // Send any XML file as the body of the POST request
        File f = new File("students.xml");
        System.out.println("File Length = " + f.length());

        postMethod.setRequestBody(new FileInputStream(f));
        postMethod.setRequestHeader("Content-type",
            "text/xml; charset=ISO-8859-1");

        int statusCode1 = client.executeMethod(postMethod);

        System.out.println("statusLine>>>" + postMethod.getStatusLine());
        postMethod.releaseConnection();
    }
}

In Listing 9-2, I have stated the URL for GetRequest.jsp using a server I am running locally on port 8080. This URL will vary based on the server where the JSP is being maintained. In this example, you create an instance of the classes HttpClient and PostMethod. You set the connection timeout for the HTTP connection to 3,000 milliseconds and then set an XML file into the request body. I am using a file named students.xml however, the contents of the file are not relevant to the example, and you could very well use any other file. Because you are sending an XML file, you also set the Content-Type header to state the format and the character set. GetRequest.jsp contains only a scriptlet that prints the request headers. The contents of the JSP are as follows:

<%
        java.util.Enumeration e= request.getHeaderNames();
        while (e.hasMoreElements()) {
          String headerName=(String)e.nextElement();
          System.out.println(headerName +" = "+request.getHeader(headerName));
        }
%>

Upon executing the class PostAFile, the JSP gets invoked, and the output displayed on the server console is as follows:

content-type = text/xml; charset=ISO-8859-1
user-agent = Jakarta Commons-HttpClient/2.0rc1
host = localhost:8080
content-length = 279

The output shown on the console where the PostAFile class was executed is as follows:

File Length = 279
statusLine>>>HTTP/1.1 200 OK

Note that the output on the server shows the content length as 279 (bytes), the same as the length of the file students.xml that is shown on the application console. Because you are not invoking the JSP using any browser, the User-Agent header that normally states the browser specifics shows the HttpClient version being used instead.

NOTE In this example, you sent a single file over HTTP. To upload multiple files, the MultipartPostMethod class is a better alternative. You will look at it later in the “Introducing FileUpload?section.

Managing Cookies

HttpClient provides cookie management features that can be particularly useful to test the way an application handles cookies. Listing 9-3 shows an example where you use HttpClient to add a cookie to a request and also to list details of cookies set by the JSP you invoke using the HttpClient code.

The HttpState class plays an important role while working with cookies. The HttpState class works as a container for HTTP attributes such as cookies that can persist from one request to another. When you normally surf the Web, the Web browser is what stores the HTTP attributes.

Listing 9-3. CookiesTrial.java
package com.commonsbook.chap9;
import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.GetMethod;

public class CookiesTrial {

    private static String url =
         "http://127.0.0.1:8080/HttpServerSideApp/CookieMgt.jsp";

    public static void main(String[] args) throws Exception {

        //A new cookie for the domain 127.0.0.1
        //Cookie Name= ABCD   Value=00000   Path=/  MaxAge=-1   Secure=False
        Cookie mycookie = new Cookie("127.0.0.1", "ABCD", "00000", "/", -1, false);

        //Create a new HttpState container
        HttpState initialState = new HttpState();
        initialState.addCookie(mycookie);

        //Set to COMPATIBILITY for it to work in as many cases as possible
        initialState.setCookiePolicy(CookiePolicy.COMPATIBILITY);
        //create new client
        HttpClient httpclient = new HttpClient();
        //set the HttpState for the client
        httpclient.setState(initialState);

        GetMethod getMethod = new GetMethod(url);
        //Execute a GET method
        int result = httpclient.executeMethod(getMethod);

        System.out.println("statusLine>>>"+getMethod.getStatusLine());

        //Get cookies stored in the HttpState for this instance of HttpClient
        Cookie[] cookies = httpclient.getState().getCookies();

        for (int i = 0; i < cookies.length; i++) {
            System.out.println("\nCookieName="+cookies[i].getName());
            System.out.println("Value="+cookies[i].getValue());
            System.out.println("Domain="+cookies[i].getDomain());
        }

        getMethod.releaseConnection();
    }
}

In Listing 9-3, you use the HttpState instance to store a new cookie and then associate this instance with the HttpClient instance. You then invoke CookieMgt.jsp. This JSP is meant to print the cookies it finds in the request and then add a cookie of its own. The JSP code is as follows:

<%
        Cookie[] cookies= request.getCookies();

        for (int i = 0; i < cookies.length; i++) {
          System.out.println(cookies[i].getName() +" = "+cookies[i].getValue());
        }

        //Add a new cookie
        response.addCookie(new Cookie("XYZ","12345"));
%>

CAUTION HttpClient code uses the class org.apache.commons.httpclient.Cookie, and JSP and servlet code uses the class javax.servlet.http.Cookie.

The output on the application console upon executing the CookiesTrial class and invoking CookieMgt.jsp is as follows:

statusLine>>>HTTP/1.1 200 OK

CookieName=ABCD
Value=00000
Domain=127.0.0.1

CookieName=XYZ
Value=12345
Domain=127.0.0.1

CookieName=JSESSIONID
Value=C46581331881A84483F0004390F94508
Domain=127.0.0.1

In this output, note that although the cookie named ABCD has been created from CookiesTrial, the other cookie named XYZ is the one inserted by the JSP code. The cookie named JSESSIONID is meant for session tracking and gets created upon invoking the JSP. The output as displayed on the console of the server when the JSP is executed is as follows:

ABCD = 00000

This shows that when CookieMgt.jsp receives the request from the CookiesTrial class, the cookie named ABCD was the only cookie that existed. The sidebar “HTTPS and Proxy Servers?shows how you should handle requests over HTTPS and configure your client to go through a proxy.

HTTPS and Proxy Servers

Using HttpClient to try out URLs that involve HTTPS is the same as with ordinary URLs. Just state https://?/STRONG> as your URL, and it should work fine. You only need to have Java Secure Socket Extension (JSSE) running properly on your machine. JSSE ships as a part of Java Software Development Kit (JSDK) 1.4 and higher and does not require any separate download and installation.

If you have to go through a proxy server, introduce the following piece of code. Replace PROXYHOST with the host name and replace 9999 with the port number for your proxy server:

	  HttpClient client = new HttpClient();
HostConfiguration hConf= client.getHostConfiguration();
hConf.setProxy("PROXYHOST ", 9999);
If you also need to specify a username password for the proxy, you can do this using the setProxyCredentials method of the class HttpState. This method takes a Credentials object as a parameter. Credentials is a marker interface that has no methods and has a single implementation UsernamePasswordCredentials. You can use this class to create a Credentials object that holds the username and password required for Basic authentication.

You will now see the HttpClient component’s capability to use MultipartPostMethod to upload multiple files. You will look at this in tandem with the Commons FileUpload component. This Commons component is specifically meant to handle the server-side tasks associated with file uploads.

Introducing FileUpload

The FileUpload component has the capability of simplifying the handling of files uploaded to a server. Note that the FileUpload component is meant for use on the server side; in other words, it handles where the files are being uploaded to—not the client side where the files are uploaded from. Uploading files from an HTML form is pretty simple; however, handling these files when they get to the server is not that simple. If you want to apply any rules and store these files based on those rules, things get more difficult.

The FileUpload component remedies this situation, and in very few lines of code you can easily manage the files uploaded and store them in appropriate locations. You will now see an example where you upload some files first using a standard HTML form and then using HttpClient code.

Using HTML File Upload

The commonly used methodology to upload files is to have an HTML form where you define the files you want to upload. A common example of this HTML interface is the Web page you encounter when you want to attach files to an email while using any of the popular Web mail services.

In this example, you will create a simple HTML page where you provide for three files to be uploaded. Listing 9-4 shows the HTML for this page. Note that the enctype attribute for the form has the value multipart/form-data, and the input tag used is of type file. Based on the value of the action attribute, on form submission, the data is sent to ProcessFileUpload.jsp.

Listing 9-4. UploadFiles.html
<HTML>
  <HEAD>
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252"/>
    <TITLE>File Upload Page</TITLE>
  </HEAD>
  <BODY>Upload Files
    <FORM name="filesForm" action="ProcessFileUpload.jsp"
    method="post" enctype="multipart/form-data">
        File 1:<input type="file" name="file1"/><br/>
        File 2:<input type="file" name="file2"/><br/>
        File 3:<input type="file" name="file3"/><br/>
        <input type="submit" name="Submit" value="Upload Files"/>
    </FORM>
  </BODY>
</HTML>

You can use a servlet to handle the file upload. I have used JSP to minimize the code you need to write. The task that the JSP has to accomplish is to pick up the files that are sent as part of the request and store these files on the server. In the JSP, instead of displaying the result of the upload in the Web browser, I have chosen to print messages on the server console so that you can use this same JSP when it is not invoked through an HTML form but by using HttpClient-based code.

Listing 9-5 shows the JSP code. Note the code that checks whether the item is a form field. This check is required because the Submit button contents are also sent as part of the request, and you want to distinguish between this data and the files that are part of the request. You have set the maximum file size to 1,000,000 bytes using the setSizeMax method.

Listing 9-5. ProcessFileUpload.jsp
<%@ page contentType="text/html;charset=windows-1252"%>
<%@ page import="org.apache.commons.fileupload.DiskFileUpload"%>
<%@ page import="org.apache.commons.fileupload.FileItem"%>
<%@ page import="java.util.List"%>
<%@ page import="java.util.Iterator"%>
<%@ page import="java.io.File"%>
html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Process File Upload</title>
</head>
<%
        System.out.println("Content Type ="+request.getContentType());

        DiskFileUpload fu = new DiskFileUpload();
        // If file size exceeds, a FileUploadException will be thrown
        fu.setSizeMax(1000000);

        List fileItems = fu.parseRequest(request);
        Iterator itr = fileItems.iterator();

        while(itr.hasNext()) {
          FileItem fi = (FileItem)itr.next();

          //Check if not form field so as to only handle the file inputs
          //else condition handles the submit button input
          if(!fi.isFormField()) {
            System.out.println("\nNAME: "+fi.getName());
            System.out.println("SIZE: "+fi.getSize());
            //System.out.println(fi.getOutputStream().toString());
            File fNew= new File(application.getRealPath("/"), fi.getName());

            System.out.println(fNew.getAbsolutePath());
            fi.write(fNew);
          }
          else {
            System.out.println("Field ="+fi.getFieldName());
          }
        }
%>
<body>
Upload Successful!!
</body>
</html>

CAUTION With FileUpload 1.0 I found that when the form was submitted using Opera version 7.11, the getName method of the class FileItem returns just the name of the file. However, if the form is submitted using Internet Explorer 5.5, the filename along with its entire path is returned by the same method. This can cause some problems.

To run this example, you can use any three files, as the contents of the files are not important. Upon submitting the form using Opera and uploading three random XML files, the output I got on the Tomcat server console was as follows:

Content Type =multipart/form-data; boundary=----------rz7ZNYDVpN1To8L73sZ6OE

NAME: academy.xml
SIZE: 951
D:\javaGizmos\jakarta-tomcat-4.0.1\webapps\HttpServerSideApp\academy.xml

NAME: academyRules.xml
SIZE: 1211
D:\javaGizmos\jakarta-tomcat-4.0.1\webapps\HttpServerSideApp\academyRules.xml

NAME: students.xml
SIZE: 279
D:\javaGizmos\jakarta-tomcat-4.0.1\webapps\HttpServerSideApp\students.xml
Field =Submit
However, when submitting this same form using Internet Explorer 5.5, the output on the server console was as follows:
Content Type =multipart/form-data; boundary=---------------------------7d3bb1de0
2e4

NAME: D:\temp\academy.xml
SIZE: 951
D:\javaGizmos\jakarta-tomcat-4.0.1\webapps\HttpServerSideApp\D:\temp\academy.xml

The browser displayed the following message: “The requested resource (D:\javaGizmos\jakarta-tomcat-4.0.1\webapps\HttpServerSideApp\D:\temp\academy.xml (The filename, directory name, or volume label syntax is incorrect)) is not available.?/P>

This contrasting behavior on different browsers can cause problems. One workaround that I found in an article at http://www.onjava.com/pub/a/onjava/2003/06/25/commons.html is to first create a file reference with whatever is supplied by the getName method and then create a new file reference using the name returned by the earlier file reference. Therefore, you can insert the following code to have your code work with both browsers (I wonder who the guilty party is…blaming Microsoft is always the easy way out)

File tempFileRef  = new File(fi.getName());
File fNew = new File(application.getRealPath("/"),tempFileRef.getName());

In this section, you uploaded files using a standard HTML form mechanism. However, often a need arises to be able to upload files from within your Java code, without any browser or form coming into the picture. In the next section, you will look at HttpClient-based file upload.

Using HttpClient-Based FileUpload

Earlier in the article you saw some of the capabilities of the HttpClient component. One capability I did not cover was its ability to send multipart requests. In this section, you will use this capability to upload a few files to the same JSP that you used for uploads using HTML.

The class org.apache.commons.httpclient.methods.MultipartPostMethod provides the multipart method capability to send multipart-encoded forms, and the package org.apache.commons.httpclient.methods.multipart has the support classes required. Sending a multipart form using HttpClient is quite simple. In the code in Listing 9-6, you send three files to ProcessFileUpload.jsp.

Listing 9-6. HttpMultiPartFileUpload.java
package com.commonsbook.chap9;
import java.io.File;
import java.io.IOException;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.MultipartPostMethod;

public class HttpMultiPartFileUpload {
    private static String url =
      "http://localhost:8080/HttpServerSideApp/ProcessFileUpload.jsp";

    public static void main(String[] args) throws IOException {
        HttpClient client = new HttpClient();
        MultipartPostMethod mPost = new MultipartPostMethod(url);
        client.setConnectionTimeout(8000);

        // Send any XML file as the body of the POST request
        File f1 = new File("students.xml");
        File f2 = new File("academy.xml");
        File f3 = new File("academyRules.xml");

        System.out.println("File1 Length = " + f1.length());
        System.out.println("File2 Length = " + f2.length());
        System.out.println("File3 Length = " + f3.length());

        mPost.addParameter(f1.getName(), f1);
        mPost.addParameter(f2.getName(), f2);
        mPost.addParameter(f3.getName(), f3);

        int statusCode1 = client.executeMethod(mPost);

        System.out.println("statusLine>>>" + mPost.getStatusLine());
        mPost.releaseConnection();
    }
}

In this code, you just add the files as parameters and execute the method. The ProcessFileUpload.jsp file gets invoked, and the output is as follows:

Content Type =multipart/form-data; boundary=----------------31415926535897932384
6

NAME: students.xml
SIZE: 279
D:\javaGizmos\jakarta-tomcat-4.0.1\webapps\HttpServerSideApp\students.xml

NAME: academy.xml
SIZE: 951
D:\javaGizmos\jakarta-tomcat-4.0.1\webapps\HttpServerSideApp\academy.xml

NAME: academyRules.xml
SIZE: 1211
D:\javaGizmos\jakarta-tomcat-4.0.1\webapps\HttpServerSideApp\academyRules.xml

Thus, file uploads on the server side become quite a simple task if you are using the Commons FileUpload component.

Summary

In this article, you saw the HttpClient and FileUpload components. Although HttpClient can be useful in any kind of applications that use HTTP for communication, the FileUpload component has a much more specific scope. One important plus for HttpClient is the existence of a decent user guide and tutorial. The FileUpload component can be just what you are looking for if you are wondering what to use and how to manage files uploaded through your application.



my java 2005-08-18 17:11 发表评论
]]>
MD5 法的Java Bean 源代?/title><link>http://www.tkk7.com/lmsun/articles/10438.html</link><dc:creator>my java</dc:creator><author>my java</author><pubDate>Thu, 18 Aug 2005 07:46:00 GMT</pubDate><guid>http://www.tkk7.com/lmsun/articles/10438.html</guid><wfw:comment>http://www.tkk7.com/lmsun/comments/10438.html</wfw:comment><comments>http://www.tkk7.com/lmsun/articles/10438.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/lmsun/comments/commentRss/10438.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/lmsun/services/trackbacks/10438.html</trackback:ping><description><![CDATA[<P><BR>java<BR>/************************************************<BR>MD5 法的Java Bean<BR>@author:Topcat Tuppin<BR>Last Modified:10,Mar,2001<BR>*************************************************/<BR>package beartool;<BR>import java.lang.reflect.*;<BR>/*************************************************<BR>md5 cdCRSA Data Security, Inc.在提交给IETF<BR>的RFC1321中的MD5 message-digest 法?BR>*************************************************/</P> <P>public class MD5 {<BR> /* 下面q些S11-S44实际上是一?*4的矩阵,在原始的C实现中是?define 实现的,<BR> q里把它们实现成为static final是表CZ只读Q切能在同一个进E空间内的多?BR> Instance间共?/<BR>        static final int S11 = 7;<BR>        static final int S12 = 12;<BR>        static final int S13 = 17;<BR>        static final int S14 = 22;</P> <P>        static final int S21 = 5;<BR>        static final int S22 = 9;<BR>        static final int S23 = 14;<BR>        static final int S24 = 20;</P> <P>        static final int S31 = 4;<BR>        static final int S32 = 11;<BR>        static final int S33 = 16;<BR>        static final int S34 = 23;</P> <P>        static final int S41 = 6;<BR>        static final int S42 = 10;<BR>        static final int S43 = 15;<BR>        static final int S44 = 21;</P> <P>        static final byte[] PADDING = { -128, 0, 0, 0, 0, 0, 0, 0, 0,<BR>        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,<BR>        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,<BR>        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };<BR>        /* 下面的三个成员是MD5计算q程中用到的3个核心数据,在原始的C实现?BR>           被定义到MD5_CTXl构?BR>        <BR>         */<BR>        private long[] state = new long[4];  // state (ABCD)<BR>        private long[] count = new long[2];  // number of bits, modulo 2^64 (lsb first)<BR>        private byte[] buffer = new byte[64]; // input buffer<BR>        <BR> /* digestHexStr是MD5的唯一一个公共成员,是最Cơ计结果的<BR>   16q制ASCII表示.<BR> */<BR>        public String digestHexStr;<BR>        <BR>        /* digest,是最Cơ计结果的2q制内部表示Q表C?28bit的MD5?<BR> */<BR>        private byte[] digest = new byte[16];<BR>        <BR> /*<BR>   getMD5ofStr是类MD5最主要的公共方法,入口参数是你惌q行MD5变换的字W串<BR>   q回的是变换完的l果Q这个结果是从公共成员digestHexStr取得的.<BR> */<BR>        public String getMD5ofStr(String inbuf) {<BR>                md5Init();<BR>                md5Update(inbuf.getBytes(), inbuf.length());<BR>                md5Final();<BR>                digestHexStr = "";<BR>                for (int i = 0; i < 16; i++) {<BR>                        digestHexStr += byteHEX(digest[i]);<BR>                }<BR>                return digestHexStr;</P> <P>        }<BR>        // q是MD5q个cȝ标准构造函敎ͼJavaBean要求有一个public的ƈ且没有参数的构造函?BR>        public MD5() {<BR>                md5Init();</P> <P>                return;<BR>        }<BR>        </P> <P><BR>        /* md5Init是一个初始化函数Q初始化核心变量Q装入标准的qL */<BR>        private void md5Init() {<BR>                count[0] = 0L;<BR>                count[1] = 0L;<BR>                ///* Load magic initialization constants.</P> <P>                state[0] = 0x67452301L;<BR>                state[1] = 0xefcdab89L;<BR>                state[2] = 0x98badcfeL;<BR>                state[3] = 0x10325476L;</P> <P>                return;<BR>        }<BR>        /* F, G, H ,I ?个基本的MD5函数Q在原始的MD5的C实现中,׃它们?BR>        单的位运,可能Z效率的考虑把它们实现成了宏Q在java中,我们把它?BR>       实现成了privateҎQ名字保持了原来C中的?*/</P> <P>        private long F(long x, long y, long z) {<BR>                return (x & y) | ((~x) & z);</P> <P>        }<BR>        private long G(long x, long y, long z) {<BR>                return (x & z) | (y & (~z));</P> <P>        }<BR>        private long H(long x, long y, long z) {<BR>                return x ^ y ^ z;<BR>        }</P> <P>        private long I(long x, long y, long z) {<BR>                return y ^ (x | (~z));<BR>        }<BR>        <BR>       /* <BR>          FF,GG,HH和II调用F,G,H,Iq行q一步变?BR>          FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.<BR>          Rotation is separate from addition to prevent recomputation.<BR>       */  </P> <P>        private long FF(long a, long b, long c, long d, long x, long s,<BR>                long ac) {<BR>                a += F (b, c, d) + x + ac;<BR>                a = ((int) a << s) | ((int) a >>> (32 - s));<BR>                a += b;<BR>                return a;<BR>        }</P> <P>        private long GG(long a, long b, long c, long d, long x, long s,<BR>                long ac) {<BR>                a += G (b, c, d) + x + ac;<BR>                a = ((int) a << s) | ((int) a >>> (32 - s));<BR>                a += b;<BR>                return a;<BR>        }<BR>        private long HH(long a, long b, long c, long d, long x, long s,<BR>                long ac) {<BR>                a += H (b, c, d) + x + ac;<BR>                a = ((int) a << s) | ((int) a >>> (32 - s));<BR>                a += b;<BR>                return a;<BR>        }<BR>        private long II(long a, long b, long c, long d, long x, long s,<BR>                long ac) {<BR>                a += I (b, c, d) + x + ac;<BR>                a = ((int) a << s) | ((int) a >>> (32 - s));<BR>                a += b;<BR>                return a;<BR>        }<BR>        /*<BR>         md5Update是MD5的主计算q程Qinbuf是要变换的字节串Qinputlen是长度,q个<BR>         函数由getMD5ofStr调用Q调用之前需要调用md5initQ因此把它设计成private?BR>        */<BR>        private void md5Update(byte[] inbuf, int inputLen) {</P> <P>                int i, index, partLen;<BR>                byte[] block = new byte[64];<BR>                index = (int)(count[0] >>> 3) & 0x3F;<BR>                // /* Update number of bits */<BR>                if ((count[0] += (inputLen << 3)) < (inputLen << 3))<BR>                        count[1]++;<BR>                count[1] += (inputLen >>> 29);</P> <P>                partLen = 64 - index;</P> <P>                // Transform as many times as possible.<BR>                if (inputLen >= partLen) {<BR>                        md5Memcpy(buffer, inbuf, index, 0, partLen);<BR>                        md5Transform(buffer);</P> <P>                        for (i = partLen; i + 63 < inputLen; i += 64) {</P> <P>                                md5Memcpy(block, inbuf, 0, i, 64);<BR>                                md5Transform (block);<BR>                        }<BR>                        index = 0;</P> <P>                } else</P> <P>                        i = 0;</P> <P>                ///* Buffer remaining input */<BR>                md5Memcpy(buffer, inbuf, index, i, inputLen - i);</P> <P>        }<BR>        <BR>        /*<BR>          md5Final整理和填写输出结?BR>        */<BR>        private void md5Final () {<BR>                byte[] bits = new byte[8];<BR>                int index, padLen;</P> <P>                ///* Save number of bits */<BR>                Encode (bits, count, 8);</P> <P>                ///* Pad out to 56 mod 64.<BR>                index = (int)(count[0] >>> 3) & 0x3f;<BR>                padLen = (index < 56) ? (56 - index) : (120 - index);<BR>                md5Update (PADDING, padLen);</P> <P>                ///* Append length (before padding) */<BR>                md5Update(bits, 8);</P> <P>                ///* Store state in digest */<BR>                Encode (digest, state, 16);</P> <P>        }<BR>         <BR>        /* md5Memcpy是一个内部用的byte数组的块拯函数Q从input的inpos开始把len长度?BR>      字节拯到output的outpos位置开?<BR>        */</P> <P>        private void md5Memcpy (byte[] output, byte[] input,<BR>                int outpos, int inpos, int len)<BR>        {<BR>                int i;</P> <P>                for (i = 0; i < len; i++)<BR>                        output[outpos + i] = input[inpos + i];<BR>        }<BR>        <BR>        /*<BR>           md5Transform是MD5核心变换E序Q有md5Update调用Qblock是分块的原始字节<BR>        */<BR>        private void md5Transform (byte block[]) {<BR>                long a = state[0], b = state[1], c = state[2], d = state[3];<BR>                long[] x = new long[16];</P> <P>                Decode (x, block, 64);</P> <P>                /* Round 1 */<BR>                a = FF (a, b, c, d, x[0], S11, 0xd76aa478L); /* 1 */<BR>                d = FF (d, a, b, c, x[1], S12, 0xe8c7b756L); /* 2 */<BR>                c = FF (c, d, a, b, x[2], S13, 0x242070dbL); /* 3 */<BR>                b = FF (b, c, d, a, x[3], S14, 0xc1bdceeeL); /* 4 */<BR>                a = FF (a, b, c, d, x[4], S11, 0xf57c0fafL); /* 5 */<BR>                d = FF (d, a, b, c, x[5], S12, 0x4787c62aL); /* 6 */<BR>                c = FF (c, d, a, b, x[6], S13, 0xa8304613L); /* 7 */<BR>                b = FF (b, c, d, a, x[7], S14, 0xfd469501L); /* 8 */<BR>                a = FF (a, b, c, d, x[8], S11, 0x698098d8L); /* 9 */<BR>                d = FF (d, a, b, c, x[9], S12, 0x8b44f7afL); /* 10 */<BR>                c = FF (c, d, a, b, x[10], S13, 0xffff5bb1L); /* 11 */<BR>                b = FF (b, c, d, a, x[11], S14, 0x895cd7beL); /* 12 */<BR>                a = FF (a, b, c, d, x[12], S11, 0x6b901122L); /* 13 */<BR>                d = FF (d, a, b, c, x[13], S12, 0xfd987193L); /* 14 */<BR>                c = FF (c, d, a, b, x[14], S13, 0xa679438eL); /* 15 */<BR>                b = FF (b, c, d, a, x[15], S14, 0x49b40821L); /* 16 */</P> <P>                /* Round 2 */<BR>                a = GG (a, b, c, d, x[1], S21, 0xf61e2562L); /* 17 */<BR>                d = GG (d, a, b, c, x[6], S22, 0xc040b340L); /* 18 */<BR>                c = GG (c, d, a, b, x[11], S23, 0x265e5a51L); /* 19 */<BR>                b = GG (b, c, d, a, x[0], S24, 0xe9b6c7aaL); /* 20 */<BR>                a = GG (a, b, c, d, x[5], S21, 0xd62f105dL); /* 21 */<BR>                d = GG (d, a, b, c, x[10], S22, 0x2441453L); /* 22 */<BR>                c = GG (c, d, a, b, x[15], S23, 0xd8a1e681L); /* 23 */<BR>                b = GG (b, c, d, a, x[4], S24, 0xe7d3fbc8L); /* 24 */<BR>                a = GG (a, b, c, d, x[9], S21, 0x21e1cde6L); /* 25 */<BR>                d = GG (d, a, b, c, x[14], S22, 0xc33707d6L); /* 26 */<BR>                c = GG (c, d, a, b, x[3], S23, 0xf4d50d87L); /* 27 */<BR>                b = GG (b, c, d, a, x[8], S24, 0x455a14edL); /* 28 */<BR>                a = GG (a, b, c, d, x[13], S21, 0xa9e3e905L); /* 29 */<BR>                d = GG (d, a, b, c, x[2], S22, 0xfcefa3f8L); /* 30 */<BR>                c = GG (c, d, a, b, x[7], S23, 0x676f02d9L); /* 31 */<BR>                b = GG (b, c, d, a, x[12], S24, 0x8d2a4c8aL); /* 32 */</P> <P>                /* Round 3 */<BR>                a = HH (a, b, c, d, x[5], S31, 0xfffa3942L); /* 33 */<BR>                d = HH (d, a, b, c, x[8], S32, 0x8771f681L); /* 34 */<BR>                c = HH (c, d, a, b, x[11], S33, 0x6d9d6122L); /* 35 */<BR>                b = HH (b, c, d, a, x[14], S34, 0xfde5380cL); /* 36 */<BR>                a = HH (a, b, c, d, x[1], S31, 0xa4beea44L); /* 37 */<BR>                d = HH (d, a, b, c, x[4], S32, 0x4bdecfa9L); /* 38 */<BR>                c = HH (c, d, a, b, x[7], S33, 0xf6bb4b60L); /* 39 */<BR>                b = HH (b, c, d, a, x[10], S34, 0xbebfbc70L); /* 40 */<BR>                a = HH (a, b, c, d, x[13], S31, 0x289b7ec6L); /* 41 */<BR>                d = HH (d, a, b, c, x[0], S32, 0xeaa127faL); /* 42 */<BR>                c = HH (c, d, a, b, x[3], S33, 0xd4ef3085L); /* 43 */<BR>                b = HH (b, c, d, a, x[6], S34, 0x4881d05L); /* 44 */<BR>                a = HH (a, b, c, d, x[9], S31, 0xd9d4d039L); /* 45 */<BR>                d = HH (d, a, b, c, x[12], S32, 0xe6db99e5L); /* 46 */<BR>                c = HH (c, d, a, b, x[15], S33, 0x1fa27cf8L); /* 47 */<BR>                b = HH (b, c, d, a, x[2], S34, 0xc4ac5665L); /* 48 */</P> <P>                /* Round 4 */<BR>                a = II (a, b, c, d, x[0], S41, 0xf4292244L); /* 49 */<BR>                d = II (d, a, b, c, x[7], S42, 0x432aff97L); /* 50 */<BR>                c = II (c, d, a, b, x[14], S43, 0xab9423a7L); /* 51 */<BR>                b = II (b, c, d, a, x[5], S44, 0xfc93a039L); /* 52 */<BR>                a = II (a, b, c, d, x[12], S41, 0x655b59c3L); /* 53 */<BR>                d = II (d, a, b, c, x[3], S42, 0x8f0ccc92L); /* 54 */<BR>                c = II (c, d, a, b, x[10], S43, 0xffeff47dL); /* 55 */<BR>                b = II (b, c, d, a, x[1], S44, 0x85845dd1L); /* 56 */<BR>                a = II (a, b, c, d, x[8], S41, 0x6fa87e4fL); /* 57 */<BR>                d = II (d, a, b, c, x[15], S42, 0xfe2ce6e0L); /* 58 */<BR>                c = II (c, d, a, b, x[6], S43, 0xa3014314L); /* 59 */<BR>                b = II (b, c, d, a, x[13], S44, 0x4e0811a1L); /* 60 */<BR>                a = II (a, b, c, d, x[4], S41, 0xf7537e82L); /* 61 */<BR>                d = II (d, a, b, c, x[11], S42, 0xbd3af235L); /* 62 */<BR>                c = II (c, d, a, b, x[2], S43, 0x2ad7d2bbL); /* 63 */<BR>                b = II (b, c, d, a, x[9], S44, 0xeb86d391L); /* 64 */</P> <P>                state[0] += a;<BR>                state[1] += b;<BR>                state[2] += c;<BR>                state[3] += d;</P> <P>        }<BR>        <BR>        /*Encode把long数组按顺序拆成byte数组Q因为java的longcd?4bit的,<BR>          只拆?2bitQ以适应原始C实现的用?BR>        */<BR>        private void Encode (byte[] output, long[] input, int len) {<BR>                int i, j;</P> <P>                for (i = 0, j = 0; j < len; i++, j += 4) {<BR>                        output[j] = (byte)(input[i] & 0xffL);<BR>                        output[j + 1] = (byte)((input[i] >>> 8) & 0xffL);<BR>                        output[j + 2] = (byte)((input[i] >>> 16) & 0xffL);<BR>                        output[j + 3] = (byte)((input[i] >>> 24) & 0xffL);<BR>                }<BR>        }</P> <P>        /*Decode把byte数组按顺序合成成long数组Q因为java的longcd?4bit的,<BR>          只合成低32bitQ高32bit清零Q以适应原始C实现的用?BR>        */<BR>        private void Decode (long[] output, byte[] input, int len) {<BR>                int i, j;</P> <P><BR>                for (i = 0, j = 0; j < len; i++, j += 4)<BR>                        output[i] = b2iu(input[j]) |<BR>                                (b2iu(input[j + 1]) << 8) |<BR>                                (b2iu(input[j + 2]) << 16) |<BR>                                (b2iu(input[j + 3]) << 24);</P> <P>                return;<BR>        }<BR>       <BR>        /*<BR>          b2iu是我写的一个把byte按照不考虑正负L原则的"升位Q程序,因ؓjava没有unsignedq算<BR>        */<BR>        public static long b2iu(byte b) {<BR>                return b < 0 ? b & 0x7F + 128 : b;<BR>        }<BR>        <BR> /*byteHEX()Q用来把一个bytecd的数转换成十六进制的ASCII表示Q?BR>  因ؓjava中的byte的toString无法实现q一点,我们又没有C语言中的<BR>   sprintf(outbuf,"%02X",ib)<BR> */<BR>        public static String byteHEX(byte ib) {<BR>                char[] Digit = { '0','1','2','3','4','5','6','7','8','9',<BR>                'A','B','C','D','E','F' };<BR>                char [] ob = new char[2];<BR>                ob[0] = Digit[(ib >>> 4) & 0X0F];<BR>                ob[1] = Digit[ib & 0X0F];<BR>                String s = new String(ob);<BR>                return s;<BR>        }</P> <P>        public static void main(String args[]) {</P> <P><BR>                MD5 m = new MD5();<BR>                if (Array.getLength(args) == 0) {   //如果没有参数Q执行标准的Test Suite<BR>                <BR>                        System.out.println("MD5 Test suite:");<BR>                 System.out.println("MD5(\"\"):"+m.getMD5ofStr(""));<BR>                 System.out.println("MD5(\"a\"):"+m.getMD5ofStr("a"));<BR>                 System.out.println("MD5(\"abc\"):"+m.getMD5ofStr("abc"));<BR>                 System.out.println("MD5(\"message digest\"):"+m.getMD5ofStr("message digest"));<BR>                 System.out.println("MD5(\"abcdefghijklmnopqrstuvwxyz\"):"+<BR>                        m.getMD5ofStr("abcdefghijklmnopqrstuvwxyz"));<BR>                 System.out.println("MD5(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\"):"+<BR>                      m.getMD5ofStr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"));<BR>                }<BR>                else <BR>                       System.out.println("MD5(" + args[0] + ")=" + m.getMD5ofStr(args[0]));<BR>                <BR>         <BR>        }</P> <P>}</P> <P><BR>login.jsp<BR><%@ page language='java' %><BR><jsp:useBean id='oMD5' scope='request' class='beartool.MD5'/></P> <P><%@ page import='java.util.*'%><BR><%@ page import='java.sql.*'%><BR><html><BR><body><BR><%<BR>  String userid = request.getParameter("UserID");  //获取用户输入UserID<BR>  String password = request.getParameter("Password"); //获取用户输入的Password<BR>  <BR>  String pwdmd5 = oMD5.getMD5ofStr(password);  //计算MD5的?BR>  <BR>  PrintWriter rp = response.getWriter();<BR>  <BR>  Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");<BR>  <BR>  Connection con = DriverManager.getConnection("jdbc:odbc:community", "", "");<BR> <BR>  Statement stmt = con.createStatement();       <BR> <BR>  ResultSet rs = stmt.executeQuery("select * from users where userID ='"+userid+"' and pwdmd5= '" + pwdmd5+"'" );</P> <P>  if (rs.next()) <BR>    {<BR>      rp.print("Login OK");<BR>            <BR>    }<BR>  else<BR>    {<BR>      rp.print("Login Fail");<BR>    }<BR> <BR>  stmt.close();<BR>  con.close();<BR> <BR>%></P> <P></body></P> <P></html></P><img src ="http://www.tkk7.com/lmsun/aggbug/10438.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/lmsun/" target="_blank">my java</a> 2005-08-18 15:46 <a href="http://www.tkk7.com/lmsun/articles/10438.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MD5的Java Bean实现http://www.tkk7.com/lmsun/articles/10437.htmlmy javamy javaThu, 18 Aug 2005 07:39:00 GMThttp://www.tkk7.com/lmsun/articles/10437.htmlhttp://www.tkk7.com/lmsun/comments/10437.htmlhttp://www.tkk7.com/lmsun/articles/10437.html#Feedback0http://www.tkk7.com/lmsun/comments/commentRss/10437.htmlhttp://www.tkk7.com/lmsun/services/trackbacks/10437.html

~者的话:

虽然 MD5 {֐法?jdk 中早已实玎ͼ?MessageDigestc)Q但作者从 MD5 的原理分析讲q?MD5 具体法?Java实现q给Z个完整的CZE序Q我惌Ҏ们的读者来说还是会有很多帮助的?/I>

MD5?/SPAN>
MD5的全U是Message-Digest Algorithm 5Q在90q代初由MIT的计机U学实验室和RSA Data Security Inc发明Q经MD2、MD3和MD4发展而来?/P>

Message-Digest泛指字节?Message)的Hash变换Q就是把一个Q意长度的字节串变换成一定长的大整数。请注意我用了“字节串”而不是“字W串”这个词Q是因ؓq种变换只与字节的值有养I与字W集或编码方式无兟?/P>

MD5Q意长度的“字节串”变换成一?28bit的大整数Qƈ且它是一个不可逆的字符串变换算法,换句话说是Q即使你看到源程序和法描述Q也无法一个MD5的值变换回原始的字W串Q从数学原理上说Q是因ؓ原始的字W串有无I多个,q有点象不存在反函数的数学函数?/P>

MD5的典型应用是对一DMessage(字节?产生fingerprint(指纹)Q以防止被“篡改”。D个例子,你将一D话写在一个叫readme.txt文g中,q对q个readme.txt产生一个MD5的值ƈ记录在案Q然后你可以传播q个文gl别人,别h如果修改了文件中的Q何内容,你对q个文g重新计算MD5时就会发现。如果再有一个第三方的认证机构,用MD5q可以防止文件作者的“抵赖”,q就是所谓的数字{֐应用?/P>

MD5q广泛用于加密和解密技术上Q在很多操作pȝ中,用户的密码是以MD5|或类似的其它法Q的方式保存的,用户Login的时候,pȝ是把用户输入的密码计成MD5|然后再去和系l中保存的MD5D行比较,而系lƈ不“知道”用L密码是什么?/P>

一些黑客破莯U密码的Ҏ是一U被UCؓ“跑字典”的Ҏ。有两种Ҏ得到字典Q一U是日常搜集的用做密码的字符串表Q另一U是用排列组合方法生成的Q先用MD5E序计算些字兔R的MD5|然后再用目标的MD5值在q个字典中检索?/P>

即假设密码的最大长度ؓ8Q同时密码只能是字母和数字,?6+26+10=62个字W,排列l合出的字典的项数则是P(62,1)+P(62,2)?+P(62,8)Q那也已l是一个很天文的数字了Q存储这个字典就需要TBU的盘l,而且q种Ҏq有一个前提,是能获得目标̎L密码MD5值的情况下才可以?/P>

在很多电子商务和C֌应用中,理用户的Account是一U最常用的基本功能,管很多Application Server提供了这些基本组Ӟ但很多应用开发者ؓ了管理的更大的灵zL还是喜Ƣ采用关pL据库来管理用P懒惰的做法是用户的密码往往使用明文或简单的变换后直接保存在数据库中Q因此这些用L密码对Y件开发者或pȝ理员来说可以说毫无保密可言Q本文的目的是介lMD5的Java Bean的实玎ͼ同时l出用MD5来处理用LAccount密码的例子,q种Ҏ使得理员和E序设计者都无法看到用户的密码,管他们可以初始化它们。但重要的一Ҏ对于用户密码讄习惯的保护?/P>

有兴的读者可以从q里取得MD5也就是RFC 1321的文本。http://www.ietf.org/rfc/rfc1321.txt

实现{略
MD5的算法在RFC1321中实际上已经提供了C的实玎ͼ我们其实马上p惛_Q至有两种用Java实现它的ҎQ第一U是Q用Java语言重新写整个算法,或者再说简单点是把CE序改写成JavaE序。第二种是,用JNI(Java Native Interface)来实玎ͼ核心法仍然用这个CE序Q用Javacȝ它包个壳?/P>

但我个h认ؓQJNI应该是JavaZ解决某类问题时的没有办法的办法(比如与操作系l或I/O讑֤密切相关的应用)Q同时ؓ了提供和其它语言的互操作性的一个手Dc用JNI带来的最大问题是引入了^台的依赖性,打破了SUN所鼓吹的“一ơ编写到处运行”的Java好处。因此,我决定采取第一U方法,一来和大家一起尝试一下“一ơ编写到处运行”的好处Q二来检验一下Java 2现在对于比较密集的计的效率问题?

实现q程
限于q篇文章的篇q,同时也ؓ了更多的读者能够真正专注于问题本nQ我不想某一UJava集成开发环境来介绍q个Java Bean的制作过E,介绍一个方法时我发现步骤和命o很清晎ͼ我相信有M一UJava集成环境三天以上l验的读者都会知道如何把q些代码在集成环境中~译和运行。用集成环境讲述问题往往需要配很多屏幕截图Q这也是我一直对集成环境很头疼的原因。我使用了一个普通的文本~辑器,同时使用了Sun公司标准的JDK 1.3.0 for Windows NT?/P>

其实把C转换成Java对于一个有一定C语言基础的程序员q不困难Q这两个语言的基本语法几乎完全一_我大概花了一个小时的旉完成了代码的转换工作Q我主要作了下面几g事:

  1. 把必M用的一?define的宏定义变成Class中的final staticQ这样保证在一个进E空间中的多个Instance׃nq些数据
  2. 删去了一些无用的#if defineQ因为我只关心MD5Q这个推荐的C实现同时实现了MD2 MD3?MD4Q而且有些#if defineq和C不同~译器有?
  3. 一些计宏转换成final static 成员函数?
  4. 所有的变量命名与原来C实现中保持一_在大写上作一些符合Java习惯的变化,计算q程中的C函数变成了privateҎ(成员函数)?
  5. 关键变量的位长调?
  6. 定义了类和方?

需要注意的是,很多早期的C~译器的intcd?6 bit的,MD5使用了unsigned long intQƈ认ؓ它是32bit的无W号整数。而在Java中int?2 bit的,long?4 bit的。在MD5的C实现中,使用了大量的位操作。这里需要指出的一ҎQ尽Java提供了位操作Q由于Java没有unsignedcdQ对于右UM操作多提供了一个无W号右移Q?gt;>>Q等价于C中的 >> 对于unsigned 数的处理?/P>

因ؓJava不提供无W号数的q算Q两个大int数相加就会溢出得C个负数或异常Q因此我一些关键变量在Java中改成了longcd(64bit)。我个h认ؓq比自己去重新定义一l无W号数的cd旉载那些运符要方便,同时效率高很多ƈ且代码也易读QOO(Object Oriented)的滥用反而会D效率低下?/P>

限于幅Q这里不再给出原始的C代码Q有兴趣对照的读者朋友可以去看RFC 1321?MD5.java源代?/A>


在RFC 1321中,l出了Test suite用来验你的实现是否正:


MD5 ("") = d41d8cd98f00b204e9800998ecf8427e

MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661

MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72

MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0

MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b

…?

q些输出l果的含义是指:I字W串””的MD5值是d41d8cd98f00b204e9800998ecf8427eQ字W串”a”的MD5值是
0cc175b9c0f1b6a831c399e269772661…?
~译q运行我们的E序Q?


				
        javac –Cd . MD5.java
java beartool.MD5
			
      

Z来不与别h的同名程序冲H,我在我的E序的第一行用了package beartool;

因此~译命o javac KCd . MD5.java 命o在我们的工作目录下自动徏立了一?beartool 目录Q目录下攄~译成功?MD5.class

我们得到和Test suite同样的结果。当然还可以l箋试你感兴趣的其它MD5变换Q例如:


				
        java beartool.MD5 1234
			
      

给?234的MD5倹{?/P>

可能是我的计机知识是从Apple II和Z80单板机开始的Q我对大写十六进制代码有偏好Q如果您想用小写的Digest String只需要把byteHEX函数中的A、B、C、D、E、FҎa、b?c、d、e、f可以了?/P>

MD5据称是一U比较耗时的计,我们的Java版MD5一闪就出来了Q没遇到什么障,而且用肉眼感觉不出来Java版的MD5比C版的慢?/P>

Z试它的兼容性,我把q个MD5.class文g拯到我的另一台Linux+IBM JDK 1.3的机器上Q执行后得到同样l果Q确实是“一ơ编写到处运行了”?

Java Beanq?/SPAN>
现在Q我们已l完成ƈ单测试了q个Java ClassQ我们文章的标题是做一个Java Bean?/P>

其实普通的Java Bean很简单,q不是什么全新的或伟大的概念Q就是一个Java的ClassQ尽?Sun规定了一些需要实现的ҎQ但q不是强制的。而EJB(Enterprise Java Bean)无非规定了一些必d玎ͼ非常cM于响应事Ӟ的方法,q些Ҏ是供EJB Container使用(调用)的?/P>

在一个Java Application或Applet里用这个bean非常单,最单的Ҏ是你要用这个类的源码工作目录下Z个beartool目录Q把q个class文g拯q去Q然后在你的E序中import beartool.MD5可以了。最后打包成.jar?war是保持这个相对的目录关系p了?/P>

Javaq有一个小的好处是你q不需要摘除我们的MD5cM那个mainҎQ它已经是一个可以工作的Java Bean了。Java有一个非常大的优Ҏ她允许很方便地让多种q行形式在同一l代码中共存Q比如,你可以写一个类Q它x一个控制台Application和GUI ApplicationQ同时又是一个AppletQ同时还是一个Java BeanQ这对于试、维护和发布E序提供了极大的方便Q这里的试Ҏmainq可以放C个内部类中?

q里讲述了把试和示例代码放在一个内部静态类的好处,是一U不错的工程化技巧和途径?

把Java Bean装到JSP?/SPAN>
正如我们在本文开头讲q的那样Q我们对q个MD5 Bean的应用是Z一个用L理,q里我们假设了一个虚拟社区的用户loginq程Q用L信息保存在数据库的个名ؓusers的表中。这个表有两个字D和我们的这个例子有养Iuserid :char(20)和pwdmd5 :char(32)Quserid是这个表的Primary KeyQpwdmd5保存密码的MD5ԌMD5值是一?28bit的大整数Q表C成16q制的ASCII需?2个字W?/P>

q里l出两个文gQ?login.html是用来接受用戯入的formQ?login.jsp 用来模拟使用MD5 Bean的loginq程?

Z使我们的试环境单v见,我们在JSP中用了JDK内置的JDBC-ODBC Bridge DriverQcommunity是ODBC的DSN的名字,如果你用其它的JDBC DriverQ替换掉login.jsp中的
Connection con= DriverManager.getConnection("jdbc:odbc:community", "", "");
卛_?

login.jsp的工作原理很单,通过post接收用户输入的UserID和PasswordQ然后将Password变换成MD5Ԍ然后在users表中LUserID和pwdmd5Q因为UserID是users表的Primary KeyQ如果变换后的pwdmd5与表中的记录不符Q那么SQL查询会得C个空的结果集?/P>

q里需要简单介l的是,使用q个Bean只需要在你的JSP应用E序的WEB-INF/classes下徏立一个beartool目录Q然后将MD5.class拯到那个目录下可以了。如果你使用一些集成开发环境,请参考它们的deploy工具的说明。在JSP使用一个java Bean关键的一句声明是E序中的W?行:

<jsp:useBean id='oMD5' scope='request' class='beartool.MD5'/>
q是所有JSP规范要求JSP容器开发者必L供的标准Tag?

id=实际上是指示JSP Container创徏Bean的实例时用的实例变量名。在后面?lt;%?>之间的JavaE序中,你可以引用它。在E序中可以看刎ͼ通过 pwdmd5=oMD5.getMD5ofStr (password) 引用了我们的MD5 Java Bean提供的唯一一个公共方? getMD5ofStr?/B>

Java Application Server执行.JSP的过E是先把它预~译?javaQ那些Tag在预~译时会成ؓjava语句Q,然后再编译成.class。这些都是系l自动完成和l护的,那个.class也称为Servlet。当Ӟ如果你愿意,你也可以帮助Java Application Serverd本该它干的事情,自己直接dServletQ但用Servlet去输出HTML那简直是回到了用C写CGIE序的恶梦时代?/P>

如果你的输出是一个复杂的表格Q比较方便的Ҏ我想q是用一个你所熟悉的HTML~辑器编写一个“模李쀝,然后在把JSP代码“嵌入”进厅R尽这UJSP代码被有些专家指责ؓ“空心粉”,它的有个缺Ҏ代码比较隄理和重复使用Q但是程序设计永q需要的是q样的权衡。我个h认ؓQ对于中、小型项目,比较理想的结构是把数据表C(或不严格地称作WEB界面相关Q的部分用JSP写,和界面不相关的放在Bean里面Q一般情况下是不需要直接写Servlet的?/P>

如果你觉得这U方法不是非常的OO(Object Oriented)Q你可以l承QextendsQ它一把,再写一个bean把用L理的功能包进厅R?

到底能不能兼容?
我测试了三种Java应用服务器环境,Resin 1.2.3、Sun J2EE 1.2、IBM WebSphere 3.5Q所q的是这个Java Bean都没有Q何问题,原因其实是因为它仅仅是个计算E序Q不涉及操作pȝQI/O讑֤。其实用其它语言也能单地实现它的兼容性的QJava的唯一优点是,你只需提供一个Ş态的q行码就可以了。请注意“Ş态”二字,现在很多计算l构和操作系l除了语a本n之外都定义了大量的代码Ş态,很简单的一DC语言核心代码Q{换成不同形态要考虑很多问题Q用很多工P同时受很多限Ӟ有时候学习一U新的“Ş态”所p的精力可能比解决问题本nq多。比如光Windows有EXE、Service、的普通DLL、COM DLL以前q有OCX{等{等Q在Unix上虽说要单一些,但要也要提供一?h定义一大堆宏,q要考虑不同q_~译器版本的位长度问题。我惌是JavaҎ来说的一个非帔R要的力吧?

参考资?

IETF RFC 1321 http:// http://www.ietf.org/rfc/rfc1321.txt q是关于MD5最原始和权威的文档Q同时包含了完整的C语言实现。这份文是1992q提交的Q它的CE序q不是ANSI标准语法的,有些老Unix的亲切感。在Windows下编译这个CE序要小改动一下?

J2EE教程 http://java.sun.com/j2ee/tutorial/doc/information/resources.html SUN的J2EE教程~得很不错,a意赅Qؓ全面了解Java Bean和JSP背后的体pȝ构提供了一个不错的L或烦引?

Bruce Eckel《Think in Java 2 ndEdition?q也是Developer Works推荐下蝲的一本不错的Java教科书,我个本书是写l至有一U程序设计语al验的程序员的?

关于作?/SPAN>
作者本Z1991q毕业于武汉绘U技大学计算机科学与工程p,毕业后被分配C国计机软g与技术服务d司,从事国Unixpȝ开发和金融pȝ应用Q三q后辞职创业Q但至今未成大器。自中学时代开始接触Apple IIQ经历了中国软g业到目前为止的完整发展历E,在十多年的Y件工作生涯中Q主要从事银行、零售业pȝ的开发、体pL构设计和目理Q曾l成功地d开发和实施q多个大中型POSpȝ目、银行业务系l和企业MISpȝQ现p业者,主要q固定客户从事Y仉目的技术咨询工作,同时作ؓ自由撰稿Zؓ一些网站和电子媒体介绍一些新的企业计技术。此外,自己建立了一个小型的个h新技术实验室Q有若干台装有不同^台的电脑q且q成一个小型的Intranet。最大的爱好是不断地去弄明白层ZIL软g技术和概念?



my java 2005-08-18 15:39 发表评论
]]>
JAVA 的MD5加密法源代?/title><link>http://www.tkk7.com/lmsun/articles/10435.html</link><dc:creator>my java</dc:creator><author>my java</author><pubDate>Thu, 18 Aug 2005 07:35:00 GMT</pubDate><guid>http://www.tkk7.com/lmsun/articles/10435.html</guid><wfw:comment>http://www.tkk7.com/lmsun/comments/10435.html</wfw:comment><comments>http://www.tkk7.com/lmsun/articles/10435.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/lmsun/comments/commentRss/10435.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/lmsun/services/trackbacks/10435.html</trackback:ping><description><![CDATA[<div id="a00u0gs" class=postText> <P><SPAN id=ArticleContent1_ArticleContent1_lblContent><SPAN id=ArticleContent1_ArticleContent1_lblContent>import java.security.*;<BR>import java.security.spec.*; </P> <P>class MD5_Test{</P> <P>   public final static String MD5(String s){<BR>     char hexDigits[] = {<BR>         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',<BR>         'e', 'f'};<BR>     try {<BR>       byte[] strTemp = s.getBytes();<BR>       MessageDigest mdTemp = MessageDigest.getInstance("MD5");<BR>       mdTemp.update(strTemp);<BR>       byte[] md = mdTemp.digest();<BR>       int j = md.length;<BR>       char str[] = new char[j * 2];<BR>       int k = 0;<BR>       for (int i = 0; i < j; i++) {<BR>         byte byte0 = md[i];<BR>         str[k++] = hexDigits[byte0 >>> 4 & 0xf];<BR>         str[k++] = hexDigits[byte0 & 0xf];<BR>         }<BR>         return new String(str);<BR>       }<BR>       catch (Exception e){<BR>         return null;<BR>       }<BR>}<BR> public static void main(String[] args){<BR> //MD5_Test aa = new MD5_Test();</P> <P> System.out.print(MD5_Test.MD5("XX"));<BR> }<FONT color=#800080><U><BR></FONT></U></P></SPAN></SPAN></DIV>}<A id=viewpost1_TitleUrl HREF="/relax/archive/2005/02/02/923.html"></A><img src ="http://www.tkk7.com/lmsun/aggbug/10435.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/lmsun/" target="_blank">my java</a> 2005-08-18 15:35 <a href="http://www.tkk7.com/lmsun/articles/10435.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://51ruilon.com" target="_blank">jzzijzzij߹ۿ츾</a>| <a href="http://smalody.com" target="_blank">ŷձ</a>| <a href="http://csl-chinga.com" target="_blank">޳ߵӰ</a>| <a href="http://www-44455588.com" target="_blank">պav</a>| <a href="http://caocl1024liu.com" target="_blank">ձһѹۿ</a>| <a href="http://www96008.com" target="_blank">˾Ʒۺں</a>| <a href="http://xa69.com" target="_blank">ղĻ</a>| <a href="http://88bgbg.com" target="_blank">ձѾþþþþþվ</a>| <a href="http://24aabb.com" target="_blank">AVվ </a>| <a href="http://yanhx.com" target="_blank">þþþþþþ</a>| <a href="http://uu313.com" target="_blank">ձ˻ʿxxxxƵ</a>| <a href="http://520xiang.com" target="_blank">͵Ƶ߹ۿ</a>| <a href="http://yangguang882.com" target="_blank">޹ۺ</a>| <a href="http://bying100.com" target="_blank">Ƶ߹ۿѿƬ</a>| <a href="http://8953y.com" target="_blank">þþþþһƷƷѿ </a>| <a href="http://xzdlgp.com" target="_blank">δav</a>| <a href="http://www-070755.com" target="_blank">ۺ˵ɫ</a>| <a href="http://bjfljg.com" target="_blank">av߹ۿһ</a>| <a href="http://hbjpxnyqckj.com" target="_blank">һ24޿</a>| <a href="http://kanzhelu23.com" target="_blank">ƵС˵</a>| <a href="http://aa7852.com" target="_blank">Ƶ</a>| <a href="http://airou08.com" target="_blank">Ʒþþþþþþþ</a>| <a href="http://22youjizz.com" target="_blank">2019Ļѿ</a>| <a href="http://juytv.com" target="_blank">69˾ƷƵ </a>| <a href="http://szjmlr.com" target="_blank">ëƬav߲һ</a>| <a href="http://321fafa.com" target="_blank">Ļ˾þ</a>| <a href="http://963315.com" target="_blank">պvavaŷva</a>| <a href="http://vip98888.com" target="_blank">av츾߲</a>| <a href="http://chinashineway.com" target="_blank">ŮƵַ</a>| <a href="http://imfakaixin.com" target="_blank">Ļһ</a>| <a href="http://1ygogo.com" target="_blank">AVɫ߹ۿ</a>| <a href="http://tjbdyx.com" target="_blank">yellowƵ߹ۿ</a>| <a href="http://by2988.com" target="_blank">þþƷ</a>| <a href="http://xianzznn.com" target="_blank">þùƵ</a>| <a href="http://6668889.com" target="_blank">ƷƵվ</a>| <a href="http://ax445.com" target="_blank">˳7777777</a>| <a href="http://nit8.com" target="_blank">ղ2021</a>| <a href="http://myzhoubian.com" target="_blank">Ʒav벻</a>| <a href="http://szgyk.com" target="_blank">йvideosԸ</a>| <a href="http://iguasheng.com" target="_blank">Ƶ㶮</a>| <a href="http://815389.com" target="_blank">Ƭ߹ۿƵ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>