几个常用的JAVA类(坚持“不要重复发明轮子”的原则,留着重用)

转载 2012年03月27日 21:27:50

(1)从输入流中获取数据并以字节数组返回,这种输入流可以来自Android本地也可以来自网络

import java.io.ByteArrayOutputStream;
 
  import java.io.InputStream;
 
 
 
  public class StreamTool {
 
  /**
 
 * 从输入流获取数据
 
 * @param inputStream
 
 * @return
 
 * @throws Exception
 
 */
 
  public static byte[] readInputStream(InputStream inputStream) throws Exception {
 
  byte[] buffer = new byte[1024]; //你可以根据实际需要调整缓存大小
  
  int len = -1;
 
 ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
 
  while( (len = inputStream.read(buffer)) != -1 ){
 
 outSteam.write(buffer, 0, len);
 
 }
 
 outSteam.close();
 
 inputStream.close();
 
  return outSteam.toByteArray();
 
 }
 
 }

(2)通过Android客户端上传数据到服务器:可以上传简单的表单,也可以方便的上传带有附件的文件,此类远远比Android自身的HttpClient更高效、更易于使用

import java.io.DataOutputStream;

import java.io.InputStream;

import java.net.HttpURLConnection;

import java.net.URL;

import java.net.URLEncoder;

import java.util.ArrayList;

import java.util.List;

import java.util.Map;


import org.apache.http.HttpResponse;

import org.apache.http.NameValuePair;

import org.apache.http.client.HttpClient;

import org.apache.http.client.entity.UrlEncodedFormEntity;

import org.apache.http.client.methods.HttpPost;

import org.apache.http.impl.client.DefaultHttpClient;

import org.apache.http.message.BasicNameValuePair;


public class HttpRequester {


/**

* 直接通过HTTP协议提交数据到服务器,实现如下面表单提交功能:

* <FORM METHOD=POST ACTION="http://192.168.0.200:8080/ssi/fileload/test.do" enctype="multipart/form-data">

<INPUT TYPE="text" NAME="name">

<INPUT TYPE="text" NAME="id">

<input type="file" name="imagefile"/>

<input type="file" name="zip"/>

</FORM>

* @param actionUrl 上传路径(注:避免使用localhost或127.0.0.1这样的路径测试,因为它会指向手机模拟器,你可以使用http://www.cnblogs.com/guoshiandroid或http://192.168.1.10:8080这样的路径测试)

* @param params 请求参数 key为参数名,value为参数值

* @param file 上传文件

*/

public static String post(String actionUrl, Map<String, String> params, FormFile[] files) {

try { 

String BOUNDARY = "---------7d4a6d158c9"; //数据分隔线

String MULTIPART_FORM_DATA = "multipart/form-data";


URL url = new URL(actionUrl);

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setConnectTimeout(5* 1000);

conn.setDoInput(true);//允许输入

conn.setDoOutput(true);//允许输出

conn.setUseCaches(false);//不使用Cache

conn.setRequestMethod("POST"); 

conn.setRequestProperty("Connection", "Keep-Alive");

conn.setRequestProperty("Charset", "UTF-8");

conn.setRequestProperty("Content-Type", MULTIPART_FORM_DATA + "; boundary=" + BOUNDARY);


StringBuilder sb = new StringBuilder();

for (Map.Entry<String, String> entry : params.entrySet()) {//构建表单字段内容

sb.append("--");

sb.append(BOUNDARY);

sb.append("\r\n");

sb.append("Content-Disposition: form-data; name=\""+ entry.getKey() + "\"\r\n\r\n");

sb.append(entry.getValue());

sb.append("\r\n");

}

DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());

outStream.write(sb.toString().getBytes());//发送表单字段数据

for(FormFile file : files){//发送文件数据

StringBuilder split = new StringBuilder();

split.append("--");

split.append(BOUNDARY);

split.append("\r\n");

split.append("Content-Disposition: form-data;name=\""+ file.getFormname()+"\";filename=\""+ file.getFilname() + "\"\r\n");

split.append("Content-Type: "+ file.getContentType()+"\r\n\r\n");

outStream.write(split.toString().getBytes());

if(file.getInStream()!=null){

byte[] buffer = new byte[1024];

int len = 0;

while((len = file.getInStream().read(buffer))!=-1){

outStream.write(buffer, 0, len);

}

file.getInStream().close();

}else{

outStream.write(file.getData(), 0, file.getData().length);

}

outStream.write("\r\n".getBytes());

}

byte[] end_data = ("--" + BOUNDARY + "--\r\n").getBytes();//数据结束标志 

outStream.write(end_data);

outStream.flush();

int cah = conn.getResponseCode();

if (cah != 200) throw new RuntimeException("请求url失败");

InputStream is = conn.getInputStream();

int ch;

StringBuilder b = new StringBuilder();

while( (ch = is.read()) != -1 ){

b.append((char)ch);

} 

outStream.close();

conn.disconnect();

return b.toString();

} catch (Exception e) {

throw new RuntimeException(e);

}

}


/**

* 提交数据到服务器

* @param actionUrl 上传路径(注:避免使用localhost或127.0.0.1这样的路径测试,因为它会指向手机模拟器,你可以使用http://www.cnblogs.com/guoshiandroid或http://192.168.1.10:8080这样的路径测试)

* @param params 请求参数 key为参数名,value为参数值

* @param file 上传文件

*/

public static String post(String actionUrl, Map<String, String> params, FormFile file) {

return post(actionUrl, params, new FormFile[]{file});

}


public static byte[] postFromHttpClient(String path, Map<String, String> params, String encode) throws Exception{

List<NameValuePair> formparams = new ArrayList<NameValuePair>();//用于存放请求参数

for(Map.Entry<String, String> entry : params.entrySet()){

formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));

} 

UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, "UTF-8");

HttpPost httppost = new HttpPost(path);

httppost.setEntity(entity);

HttpClient httpclient = new DefaultHttpClient();//看作是浏览器

HttpResponse response = httpclient.execute(httppost);//发送post请求 

return StreamTool.readInputStream(response.getEntity().getContent());

}


/**

* 发送请求

* @param path 请求路径

* @param params 请求参数 key为参数名称 value为参数值

* @param encode 请求参数的编码

*/

public static byte[] post(String path, Map<String, String> params, String encode) throws Exception{

//String params = "method=save&name="+ URLEncoder.encode("国士工作室", "UTF-8")+ "&age=28&";//需要发送的参数

StringBuilder parambuilder = new StringBuilder("");

if(params!=null && !params.isEmpty()){

for(Map.Entry<String, String> entry : params.entrySet()){

parambuilder.append(entry.getKey()).append("=")

.append(URLEncoder.encode(entry.getValue(), encode)).append("&");

}

parambuilder.deleteCharAt(parambuilder.length()-1);

}

byte[] data = parambuilder.toString().getBytes();

URL url = new URL(path);

HttpURLConnection conn = (HttpURLConnection)url.openConnection();

conn.setDoOutput(true);//允许对外发送请求参数

conn.setUseCaches(false);//不进行缓存

conn.setConnectTimeout(5 * 1000);

conn.setRequestMethod("POST");

//下面设置http请求头

conn.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");

conn.setRequestProperty("Accept-Language", "zh-CN");

conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");

conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

conn.setRequestProperty("Content-Length", String.valueOf(data.length));

conn.setRequestProperty("Connection", "Keep-Alive");


//发送参数

DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());

outStream.write(data);//把参数发送出去

outStream.flush();

outStream.close();

if(conn.getResponseCode()==200){

return StreamTool.readInputStream(conn.getInputStream());

}

return null;

}

}

(3)下面的类是文件下载类,支持文件的多线程断点续传,使用该类的即可安全、高效的下载任何类型的二进制文件:

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.RandomAccessFile;

import java.net.HttpURLConnection;

import java.net.URL;

import java.util.LinkedHashMap;

import java.util.Map;

import java.util.Properties;

import java.util.UUID;

import java.util.concurrent.ConcurrentHashMap;

import java.util.regex.Matcher;

import java.util.regex.Pattern;


import cn.itcast.service.FileService;


import android.content.Context;

import android.util.Log;

/**

* 文件下载器

*/

public class FileDownloader {

private Context context;

private FileService fileService;


private static final String TAG = "FileDownloader";

/* 已下载文件大小 */

private int downloadSize = 0;

/* 原始文件大小 */

private int fileSize = 0;

/* 线程数 */

private DownloadThread[] threads;

/* 下载路径 */

private URL url;

/* 本地保存文件 */

private File saveFile;

/* 下载记录文件 */

private File logFile;

/* 缓存各线程最后下载的位置*/

private Map<Integer, Integer> data = new ConcurrentHashMap<Integer, Integer>();

/* 每条线程下载的大小 */

private int block;

private String downloadUrl;//下载路径

/**

* 获取线程数

*/

public int getThreadSize() {

return threads.length;

}

/**

* 获取文件大小

* @return

*/

public int getFileSize() {

return fileSize;

}

/**

* 累计已下载大小

* @param size

*/

protected synchronized void append(int size) {

downloadSize += size;

}

/**

* 更新指定线程最后下载的位置

* @param threadId 线程id

* @param pos 最后下载的位置

*/

protected void update(int threadId, int pos) {

this.data.put(threadId, pos);

}

/**

* 保存记录文件

*/

protected synchronized void saveLogFile() {

this.fileService.update(this.downloadUrl, this.data);

}

/**

* 构建文件下载器

* @param downloadUrl 下载路径

* @param fileSaveDir 文件保存目录

* @param threadNum 下载线程数

*/

public FileDownloader(Context context, String downloadUrl, File fileSaveDir, int threadNum) {

try {

this.context = context;

this.downloadUrl = downloadUrl;

fileService = new FileService(context);

this.url = new URL(downloadUrl);

if(!fileSaveDir.exists()) fileSaveDir.mkdirs();

this.threads = new DownloadThread[threadNum]; 

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setConnectTimeout(6*1000);

conn.setRequestMethod("GET");

conn.setRequestProperty("Accept", "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");

conn.setRequestProperty("Accept-Language", "zh-CN");

conn.setRequestProperty("Referer", downloadUrl); 

conn.setRequestProperty("Charset", "UTF-8");

conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");

conn.setRequestProperty("Connection", "Keep-Alive");

conn.connect();

printResponseHeader(conn);

if (conn.getResponseCode()==200) {

this.fileSize = conn.getContentLength();//根据响应获取文件大小

if (this.fileSize <= 0) throw new RuntimeException("1无法获知文件大小 ");


String filename = getFileName(conn);

this.saveFile = new File(fileSaveDir, filename);/* 保存文件 */

Map<Integer, Integer> logdata = fileService.getData(downloadUrl);

if(logdata.size()>0){

for(Map.Entry<Integer, Integer> entry : logdata.entrySet())

data.put(entry.getKey(), entry.getValue()+1);

}

this.block = this.fileSize / this.threads.length + 1;

if(this.data.size()==this.threads.length){

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

this.downloadSize += this.data.get(i+1)-(this.block * i);

}

print("已经下载的长度"+ this.downloadSize);

} 

}else{

throw new RuntimeException("2服务器响应错误 ");

}

} catch (Exception e) {

print(e.toString());

throw new RuntimeException("3连接不到下载路径 ");

}

}

/**

* 获取文件名

*/

private String getFileName(HttpURLConnection conn) {

String filename = this.url.toString().substring(this.url.toString().lastIndexOf('/') + 1);

if(filename==null || "".equals(filename.trim())){//如果获取不到文件名称

for (int i = 0;; i++) {

String mine = conn.getHeaderField(i);

if (mine == null) break;

if("content-disposition".equals(conn.getHeaderFieldKey(i).toLowerCase())){

Matcher m = Pattern.compile(".*filename=(.*)").matcher(mine.toLowerCase());

if(m.find()) return m.group(1);

}

}

filename = UUID.randomUUID()+ ".tmp";//默认取一个文件名

}

return filename;

}


/**

* 开始下载文件

* @param listener 监听下载数量的变化,如果不需要了解实时下载的数量,可以设置为null

* @return 已下载文件大小

* @throws Exception

*/

public int download(DownloadProgressListener listener) throws Exception{

try { 

if(this.data.size() != this.threads.length){

this.data.clear();

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

this.data.put(i+1, this.block * i);

}

}

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

int downLength = this.data.get(i+1) - (this.block * i);

if(downLength < this.block && this.data.get(i+1)<this.fileSize){ //该线程未完成下载时,继续下载

RandomAccessFile randOut = new RandomAccessFile(this.saveFile, "rw");

if(this.fileSize>0) randOut.setLength(this.fileSize); 

randOut.seek(this.data.get(i+1));

this.threads[i] = new DownloadThread(this, this.url, randOut, this.block, this.data.get(i+1), i+1);

this.threads[i].setPriority(7);

this.threads[i].start();

}else{

this.threads[i] = null;

}

}

this.fileService.save(this.downloadUrl, this.data);

boolean notFinish = true;//下载未完成

while (notFinish) {// 循环判断是否下载完毕

Thread.sleep(900);

notFinish = false;//假定下载完成

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

if (this.threads[i] != null && !this.threads[i].isFinish()) {

notFinish = true;//下载没有完成

if(this.threads[i].getDownLength() == -1){//如果下载失败,再重新下载

RandomAccessFile randOut = new RandomAccessFile(this.saveFile, "rw");

randOut.seek(this.data.get(i+1));

this.threads[i] = new DownloadThread(this, this.url, randOut, this.block, this.data.get(i+1), i+1);

this.threads[i].setPriority(7);

this.threads[i].start();

}

}

} 

if(listener!=null) listener.onDownloadSize(this.downloadSize);

}

fileService.delete(this.downloadUrl);

} catch (Exception e) {

print(e.toString());

throw new Exception("下载失败");

}

return this.downloadSize;

}

/**

* 获取Http响应头字段

* @param http

* @return

*

转自:http://www.cnblogs.com/guoshiandroid/archive/2010/06/05/1752150.html

相关文章推荐

JDK提供的Arrays的几个减少重复造轮子的方法

前两周学习了Java的数组,了解到Java有ArrayList类有很多方法可以直接调用,ArrayList是继承自Arrays类的,这里就简单介绍几个他可以直接调用的方法吧 一、数组复制...

几个java常用的类

  • 2011年11月15日 17:52
  • 3KB
  • 下载

几个常用的Swift Extension:防止按钮重复点击、增加友盟页面统计、Dispatch_once Swift实现

//  防止按钮重复点击 //  UIButton+extension.swift // //  Created by pilgrim on 2017/2/23. //  Copyright ...

字符串String类在Java开发中常用的几个重要方法

Java中String类包含了50多个方法。令人惊讶的绝大多数的方法都很有用,在实际软件开发过程中用的频率也非常之多,下面我来总结最常用(最重要)的String类方法。 1.length(),返回值...
  • qian_ch
  • qian_ch
  • 2016年12月26日 13:08
  • 244

关于不要重复造轮子的二三事

“不要重复造轮子 Stop Trying to Reinvent the Wheel”, 可能是每个程序员入行被告知的第一条准则。我自己也会对新人反复灌输这个概念,写程序其实是一个最能“偷懒”的工作:...

黑马程序员 知识点总结-Java中几个常用的类(二)

---------------------- ASP.Net+Android+IOS">http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发...

JAVA基础:面向对象编程的几个原则

JAVA基础:面向对象编程的几个原则   1. 开闭原则(the Open Closed Principle OCP)   一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的。因此在进行面...

Java设计模式——面向对象的几个基本原则

1. 面向抽象原则 1.1 抽象类 1.2 接口 1.3 面向抽象 2. 开-闭原则 3. 多用组合少用继承原则 3.1 继承与复用 3.2 组合与复用 4. 高内聚-低耦合原则...
  • ayhlay
  • ayhlay
  • 2013年09月04日 18:24
  • 4568

JAVA中去重复的几个典型的方法

不多废话,以说起去重复,大部分人直接想到的就是遍历,比较……从来不考虑程序效率问题,下面把几种常用的比较好理解的去重复的处理方式记录一下, 从简单到难: 1、最简单的,List 这种形式,如果Li...

【Java JVM】Java虚拟机内存分配几个原则

1、大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC 2、大对象直接进入老年代。大对象指需要大量连续内存空间的Java对象,最典型的大对...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:几个常用的JAVA类(坚持“不要重复发明轮子”的原则,留着重用)
举报原因:
原因补充:

(最多只允许输入30个字)