⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 contentfactory.java

📁 Oracle 10g数据库Java开发 源码
💻 JAVA
字号:
package Information;

import java.io.*;
import comm.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.sql.*;
import oracle.jdbc.*;

/**存放报文内容的类,提供类似于 ServletRequest 中的部分 get 方法
*你必须在 html 页面的窗体(form)中指定 enctype="multipart/form-data"。
*才可以正确的使用这个类。**
**/
public class ContentFactory  extends HttpServlet 
{
        /**
    **返回根据当前请求生成的一个 ContentFactory 实例
    **@param request 提交的请求
    **@param maxLength 数据包的最大长度,默认为1024*1024
    **@return 返回根据当前请求生成的一个 ContentFactory 实例,如果 request
    数据包的内容不是以 mutilpart/form-data 型编码,则返回 null。
    **@throws ContentFactoryException 当提交的数据和文件太大时抛出,
    **根据 Content-Length 判断,默认的许可值为 1024* 1024。
    **/
	//HttpServletRequest提供访问有关请求信息的方法,例如表单数据、HTTP请求头等等。
public int getContentFactory(HttpServletRequest request, int maxLength) 
throws ContentFactoryException,IOException
  {
    //类HttpServletRequest用来处理客户端通过HTTP协议提交的请求
    //取得上传数据的类型
    String contentType=request.getContentType();
    //取得上传数据的长度
    int contentLength = request.getContentLength(); 
    //如果上传数据超长,则抛出异常
    if (contentLength>maxLength) {
      ContentFactoryException e=new ContentFactoryException("上传数据太多,请不要选择太大的文件");
      throw e;
    }
    //上传数据类型必须以"multipart/form-data"开头,服务器才能识别是上传数据
    if(contentType==null || !contentType.startsWith("multipart/form-data")) { 
      ContentFactoryException e=new ContentFactoryException("请确认页面中表单的编码为 multipart/form-data 形式!");
      throw e;
    }
    //在接收到的输入流中除了包含上传文件数据外,还有一些说明信息,
    //需要手工编写读取和分离Stream中的内容的代码
    //在上传数据类型中定位boundary=,boundary=定义说明信息和真实上传数据的界线
    int start=contentType.indexOf("boundary=");
    //将contentType对象中boundary=后面的数据保存在boundary对象中
    int boundaryLen=new String("boundary=").length();
    String boundary=contentType.substring(start+boundaryLen);
    //传过来的分界符比读取的分界符多两个--,所以要添加到boundary
    boundary="--"+boundary;
    //用字节表示,以免 String  和 byte 数组的长度不一致
    boundaryLen=bytesLen(boundary);
    //把request 中的数据读入一个byte数组
    byte buffer[] = new byte[contentLength]; 
    int once = 0; 
    int total = 0; 
    //定义DataInputStream对象in,用来从输入流request.getInputStream中读取数据到buffer对象中
    //类DataInputStream的功能是使应用程序可以读取数据输入流中的Java数据
    DataInputStream in = new DataInputStream(request.getInputStream()); 
    while ((total<contentLength) && (once>=0)) { 
      //read()方法的功能是从in对象中读取数据到buffer
      //read()方法会从位置total开始,尽量读取contentLength长度的数据
      //但是实际读取的数据可能要小于contentLength,实际读取数据将做为函数值返回到once
      once = in.read(buffer,total,contentLength); 
      //设置下一次读取数据的位置
      total += once; 
    }
    //上传文件头的语法结构,使用它与buffer中的数据匹配,可以找到上传数据名,文件名及数据内容等信息
    String[] tokens={"name=\"","\"; filename=\"", "\"\r\n","Content-Type: ","\r\n\r\n"};
    int[] position=new int[tokens.length];
    //依次将tokens[]中的数据与buffer进行匹配,并将位置结果保存在position[]数组中	
    for (int i=0;i<tokens.length ;i++ ) {
      position[i]=byteIndexOf(buffer,tokens[i],0);
    }
    //用来保存上传文件的数据。
    byte[] b=new byte[1024*1024*2];
    //如果找到name=",并且出现在filename="之前,则说明存在有效的数据
    if (position[1]>0 && position[1]<position[2]) {
      String name =subBytesString(buffer,position[0]+bytesLen(tokens[0]),position[1]);
      //2.得到文件名
      String file= subBytesString(buffer,position[1]+bytesLen(tokens[1]),position[2]);
      if (file.equals("")) return -1;
        file=new File(file).getName();     //this is the way to get the name from a path string
      //3.得到 Content-Type
      contentType=subBytesString(buffer,position[3]+bytesLen(tokens[3]),position[4]);
      //4.得到文件内容
      b=subBytes(buffer,position[4]+bytesLen(tokens[4]),buffer.length);
    }
    else {
      ContentFactoryException e=new ContentFactoryException("你的文件大小为0,请重新传!");
      return -1;
    }
    //连接数据库
    DBOper o_DBOper = new DBOper();
    Connection conn ;
    ResultSet rs = null;
    try {
      o_DBOper.connectDB();
      conn = o_DBOper.getConnection();
      conn.setAutoCommit(false);
      // 将一个空的blob对象插入数据库
      String sql="INSERT INTO Images(ImageId,Image) VALUES(S_ImgId.nextval,empty_blob())";
      Statement stmt = conn.createStatement();
      stmt.executeUpdate(sql);
      conn.commit();
      stmt.close();
      int imid = getImageId();
      // 使用SELECT定位要写入图片的记录,FOR UPDATE表示要对此记录进行更新操作
      sql="Select Image from Images where ImageId=" + imid + " for update";
      stmt = conn.createStatement();
      rs=stmt.executeQuery(sql);
      //将图片数据写入clob字段
      if (rs.next()) {
      // 二进制方式取得image字段信息
      Blob blob = rs.getBlob(1);
      // oracle.sql.BLOB是Oracle提供的JDBC包
      //getBinaryOutputStream()方法将从流中读取数据写入BLOB字段
      OutputStream blobOs = ( (oracle.sql.BLOB)blob).getBinaryOutputStream();
      // 数据写入blob对象,即写入数据库
      blobOs.write(b,0,b.length); 
      blobOs.close();
    }
    //关闭连接
    rs.close();
    o_DBOper.close();
  }
  catch(Exception e) {
    e.printStackTrace();
  }
  return 1;
}

 //返回布尔值,判断boundary[]数组是否是line[]数组的开始部分。
 //如果是,则返回true,否则返回false。参数length表示数组line[]的长度
 private static boolean startWithBoundary(byte[] line, byte[] boundary, int length)
 {
   for (int i=0;i<length;i++){
     if (line[i]!=boundary[i])
       return false;
   }
   return true;
 }

  /**
    **用于从一个字节数组中提取一个字节数组
    **类似于 String 类的substring()
    **/
    private static byte[] subBytes(byte[] source,int from,int end)
    {
        byte[] result=new byte[end-from];
        System.arraycopy(source,from,result,0,end-from);
        return result;
    }

    /**
    **用于从一个字节数组中提取一个字符串
    **类似于 String 类的substring()
    **/
    private static String subBytesString(byte[] source,int from,int end)
    {
        return new String(subBytes(source,from,end));
    }

    /**
    **返回字符串S转换为字节数组后的长度
    **/
    private static int bytesLen(String s)
    {
        return s.getBytes().length;
    }

	 /**字节数组中的 indexof 函数,与 String 类中的 indexOf类似
    **@para source 源字节数组
    **@para search 目标字符串
    **@para start 搜索的起始点
    **@return 如果找到,返回search的第一个字节在buffer中的下标,没有则返回-1
    **/
    private static int byteIndexOf (byte[] source,String search,int start)
    {
        return byteIndexOf(source,search.getBytes(),start);
    }
	
	private static int byteIndexOf (byte[] source,byte[] search,int start)
    {
        int i;
        if (search.length==0)
        {
            return 0;
        }
        int max=source.length-search.length;
        if (max<0)
            return -1;
        if (start>max)
            return -1;
        if (start<0)
            start=0;
    // 在source中找到search的第一个元素
    searchForFirst:
        for (i=start;i<=max ; i++)
        {
            if (source[i]==search[0])
            {
                //找到了search中的第一个元素后,比较剩余的部分是否相等
                int k=1;
                while(k<search.length)
                {
                    if (source[k+i]!=search[k])
                    {
                        continue searchForFirst;
                    }
                    k++;
                }
                return i;
            }
        }
        return -1;
    }

	public int getImageId() throws Exception
    {
        DBOper o_DBOper = new DBOper();
        ResultSet rs = null;

        String sql = "Select Max(ImageId) as mks from Images";
//	System.out.println("UPDATE SQL :"+sql);
        try
        {
			rs = o_DBOper.getResultSet(sql);
			if (rs.next())
				return rs.getInt("mks");
           
        }
        catch(Exception e)
        {
            throw new Exception(e.getMessage());
        }
	    finally
	    {
            try {o_DBOper.close();} catch (Exception e) { System.out.print(e.toString());}
	    }
		return 1;
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -