翻译工具开发学习札记

requestresponse及文件的上传下载

一般在服务器用request.getparameter(“”)获取服务器端form表单传递的数据,在服务器端则通过request.setattribute(“”);来设置将传递的参数,再有客户端通过request.getattribute(“”);来获取服务器传递过来参数。

注意点如下:form表单有getpost两种方式,GET请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,参数之间以&相连,如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0%E5%A5%BD。如果数据是英文字母/数字,原样发送,如果是空格,转换为+如果是中文/其他字符,则直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII而POST把提交的数据则放置在是HTTP包的包体中。

1.get传送的数据量较小,不能大于2KBpost传送的数据量较大,一般被默认为不受限制。在传递含有中文时应尽量用post而不是get方式,防止出现乱码。在表单内有<imput type=”file”>属性时,需要设置表单的enctype,且用post方式。如下:

<form action=""  method="post" enctype="multipart/form-data">

<input name="fileInPath" type="hidden" value="">

<input name="fileName" type="hidden" value="">  

<input id="FI" name="file_id" type="hidden" value="<%=file_id%>"/>

</form>

表单中enctype="multipart/form-data"的意思,是设置表单的MIME编码。默认情况,这个编码格式是application/x-www-form-urlencoded,不能用于文件上传;只有使用了multipart/form-data,才能完整的传递文件数据,进行下面的操作
enctype="multipart/form-data"是上传二进制数据; form里面的input的值以2进制的方式传过去。因而此时将无法用request.getparameter(“”)获取该表单内的非表单属性(如fileName值)。

解决办法如下

1.在action后添加需要传递的参数值(”&userName=’ss’&fileInPath=’aa’”);考虑到值会动态变化,可在javaScript中操作;

2.分析包体内的数据,将非文件类的参数分离出。核心内容如下:

需要的包有


if(ServletFileUpload.isMultipartContent(request)){  

DiskFileItemFactory dff = new DiskFileItemFactory();//创建该对象  

ff.setRepository(tmpDir);//指定上传文件的临时目录  

dff.setSizeThreshold(1024000);//指定在内存中缓存数据大小,单位为byte  

ServletFileUpload sfu = new ServletFileUpload(dff);//创建该对象  

sfu.setFileSizeMax(5000000);//指定单个上传文件的最大尺寸  

sfu.setSizeMax(10000000);//指定一次上传多个文件的总尺寸  

ServletFileUpload sfu1 = new ServletFileUpload(dff);//创建该对象  

sfu1.setFileSizeMax(5000000);//指定单个上传文件的最大尺寸  

sfu1.setSizeMax(10000000);//指定一次上传多个文件的总尺寸  

List<?> items = sfu1.parseRequest(request);  

Iterator iter = items.iterator();  

while (iter.hasNext()) {  

           FileItem item = (FileItem) iter.next();  

           if (item.isFormField()) {  

               //如果是普通表单字段  

               String name = item.getFieldName();  

             if(name.equals("fileInPath")){

             fileInPath=item.getString();

             }else {}

else{//处理表单字段

 String fieldName = item.getFieldName(); //文件的idname 

         String fileName2 = item.getName(); //文件的namefileName2=fileName2.substring(fileName2.lastIndexOf("\\")+1);

         System.out.println(fileName2.length());

         ile_id=fileName2.substring(0, fileName2.length()-17);

              // String contentType = item.getContentType();  

             //  boolean isInMemory = item.isInMemory();  

             //  long sizeInBytes = item.getSize();  

               // Process a file upload  

          InputStream uploadedStream = item.getInputStream(); 

  InputStreamReader read = new InputStreamReader(uploadedStream);

...

}

 

文件的下载如下:

<%  

  //关于文件下载时采用文件流输出的方式处理:  

  //加上response.reset(),并且所有的%>后面不要换行,包括最后一个;

  response.reset();//可以加也可以不加  

  response.setContentType("application/x-download"); 

//application.getRealPath("/main/mvplayer/CapSetup.msi");获取的物理路径   

  String filedownload = request.getParameter("filePath")+".zip";//文件完整路径  

    String filedisplay = request.getParameter("file_id")+".zip";//默认文件名

  filedisplay = URLEncoder.encode(filedisplay,"UTF-8");  

  //response.setHeader("Content-disposition","attachment; filename="+URLEncoder.encode(filedisplay, "UTF-8"));

  //response.setHeader("Content-disposition","attachment; filename="+new String(filedisplay.getBytes("UTF-8"),"iso8859-1"));

  response.addHeader("Content-Disposition","attachment;filename=" + filedisplay);  

  java.io.OutputStream outp = null;  

  java.io.FileInputStream in = null;  

  try  

  {  

  outp = response.getOutputStream();  

  in = new FileInputStream(new File(filedownload));

  

  byte[] b = new byte[1024];  

  int i = 0;  

  

  while((i = in.read(b)) > 0)  

  {  

  outp.write(b, 0, i);  

  }  

//    

outp.flush();

//要加以下两句话,否则会报错 

//java.lang.IllegalStateException: getOutputStream() has already been called for //this response    

out.clear();  

out = pageContext.pushBody();  

}  

  catch(Exception e)  

  {  

  System.out.println("Error!");  

  e.printStackTrace();  

  }  

  finally  

  {  

  if(in != null)  

  {  

  in.close();  

  in = null;  

  }  

//这里不能关闭    

//if(outp != null)  

  //{  

  //outp.close();  

  //outp = null;

  //}  

  }  

%>

注意事项有:1.见代码内的注释。在servlet中,文件的结束会涉及到对内置对象的处理,调用了response.getwrite()方法,此方法与outp = response.getOutputStream();中getOutputStream方法两者只能存一,解决方法是加下

 

response.reset();//可以加也可以不加 

out.clear();  

out = pageContext.pushBody(); 

三句,但是在如此处理后依旧出现getOutputStream() has already been called for 错误,原因发现是由servlet跳转到servlet/jsp出现这样的错误的,处理的方法是downloadServlet跳转到一个中间过度的jsp页面,该页面设定为自动跳转到含有上述代码的jsp页面,解决了上述问题。此外跳转后不知何原因无法自动跳转回来,于是设置form表单的target="_blank",表示为点击按钮后另开一新的窗口显示,该属性默认值target="_self"。今后可以适当使用该属性,使数据流图变得更简单。

 

关于文件压缩

文件压缩的函数如下:

Strs表示所压缩的多个文件的绝对路径的字符串值;zipname表示压缩文件的默认名

filePath表示压缩后文件的所在目录

private static void writeZip(String[] strs,String zipname,String filePath) throws IOException {

        String[] files = strs;

        OutputStream os = new BufferedOutputStream( new FileOutputStream( filePath+".zip" ) );

        ZipOutputStream zos = new ZipOutputStream( os );

        byte[] buf = new byte[8192];

        int len;

        for (int i=0;i<files.length;i++) {

            File file = new File( files[i] );

            if ( !file.isFile() ) continue;

            ZipEntry ze = new ZipEntry( file.getName() );

            zos.putNextEntry( ze );

            BufferedInputStream bis = new BufferedInputStream( new FileInputStream( file ) );

            while ( ( len = bis.read( buf ) ) > 0 ) {

                zos.write( buf, 0, len );

            }

            zos.closeEntry();

            bis.close();//少此条语句文件将无法删除

        }

        //zos.setEncoding("GBK");

        zos.closeEntry();

        zos.close();

        

        for(int i=0;i<files.length;i++){

         File file= new File(files[i]);

         if (file.isFile() && file.exists()) {

          file.delete();//文件流若没有关闭将无法删除

         }

        }

    }

 

 

读取properties属性文件的方法

Properties pro = new Properties();

InputStream in = this.getClass().getClassLoader().getResourceAsStream("a.properties");

pro.load(in);

String path=pro.getProperty(properName);

//properName为文件内属性的变量//名,若无则放回值为null

 

多线程处理问题

对于与主线程无关的问题,如日志文件等,可以启动另一线程处理,提高主线程的运行速度

Jdbc操作的问题

插入大量数据时考虑使用批处理,oracle默认是自动提交的,设置

private Connection conn=

DriverManager.getConnection(url,username,password);

conn.setAutoCommit(flase);可关闭自动提交

通过语句private PreparedStatement pstmt=null;

this.pstmt = this.conn.prepareStatement(sql);

this.pstmt.addBatch();//增加一条批处理语句

最后调用this.pstmt.executeBatch();//处理语句

this.conn.commit();//提交更改到数据库

可大幅度提升插入语句的效率,在实践过程中出现只提交了最后一条语句,没有全部更改,是PreparedStatement pstmt=null;可能这个变量在处理的时候被引用为新的对象了,由于处理的数据不大,找到大致原因,未做修改,提供参考。

 

 

 

关于转发与重定向的小段文章

getRequestDispatcher()与sendRedirect()的区别

1.request.getRequestDispatcher()是请求转发,前后页面共享一个request ; 
response.sendRedirect()是重新定向,前后页面不是一个requestrequest.getRequestDispather();返回的是一个RequestDispatcher对象。2.RequestDispatcher.forward()是在服务器端运行; 
HttpServletResponse.sendRedirect()是通过向客户浏览器发送命令来完成. 
所以RequestDispatcher.forward()对于浏览器来说是“透明的”; 
而HttpServletResponse.sendRedirect()则不是。3.ServletContext.getRequestDispatcher(String url)中的url只能使用绝对路径; 而ServletRequest.getRequestDispatcher(String url)中的url可以使用相对路径。因为ServletRequest具有相对路径的概念;而ServletContext对象无次概念。RequestDispatcher对象从客户端获取请求request,并把它们传递给服务器上的servlet,html或jsp。它有两个方法:
3.1  void forward(ServletRequest request,ServletResponse response) 
用来传递request的,可以一个Servlet接收request请求,另一个Servlet用这个request请求来产生response。request传递的请求,response是客户端返回的信息。forward要在response到达客户端之前调用,也就是 before response body output has been flushed。如果不是的话,它会报出异常。

3  void include(ServletRequest request,ServletResponse response) 
用来记录保留request和response,以后不能再修改response里表示状态的信息。如果需要把请求转移到另外一个Web App中的某个地址,可以按下面的做法: 
1. 获得另外一个Web App的ServletConext对象(currentServletContext.getContext(uripath)). 

2. 调用ServletContext.getRequestDispatcher(String url)方法。  

关于字符串

如这个字符串“D:\ss\ss.txr”,在java中定义这样的字符串是不合法的,因为\是转移字符,有人会说可以写成“D:\\ss\\ss.txt”但是有时我们得到的却就是这样一个字符串,就不如<inpute type=”file” value=””>选择文件后,该值即为文件的路径,并不给你机会处理该字符串(ps:value为客户端的文件路径,文件上传时获取后给服务器也没有多大意义,而且得到file的路径有其他相关方法去处理,此处为举例该字符串的特殊性),在该问题中,若需要处理该字符串,可以在强大的JavaScript内处理,处理方法为:document.getElementById("file1").value.replace(/\\/g"\\\\");

括号内是正则表达式g表示全部替换,相关知识请自行查阅资料。此外还有一点补充:Windows下的路径分隔符和Linux下的路径分隔符是不一样的,当直接使用绝对路径时,跨平台会暴出“No such file or diretory”的异常。

比如说要在temp目录下建立一个test.txt文件,在Windows下应该这么写:
File file1 = new File ("C:\tmp\test.txt");
Linux下则是这样的:
File file2 = new File ("/tmp/test.txt");

如果要考虑跨平台,则最好是这么写:
File myFile = new File("C:" + File.separator + "tmp" + File.separator, "test.txt");

 

注意使用:File.separator

 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值