精华内容
下载资源
问答
  • 一个发送短信验证码的功能,使用的是信易通的短信平台接口,然后在Java中使用HttpClient模拟POST请求或者GET请求(看短信平台要求,一般的情况下都是POST请求),调用短信平台提供的接口(遵循短信平台的接口规范即可)...

    一个发送短信验证码的功能,使用的是信易通的短信平台接口,然后在Java中使用HttpClient模拟POST请求或者GET请求(看短信平台要求,一般的情况下都是POST请求),调用短信平台提供的接口(遵循短信平台的接口规范即可)。具体看代码:

    使用HttpClient的时候需要在项目中引入:

    commons-httpclient-3.1.jar

    这个jar包,

    项目结构:

    88c1d4edb3ddc65b5b8fbf443a2c0f2d.png

    1、创建一个Http的模拟请求工具类,然后写一个POST方法或者GET方法

    /**

    * 文件说明

    * @Description:扩展说明

    * @Copyright: 2015 dreamtech.com.cn Inc. All right reserved

    * @Version: V6.0

    */

    package com.demo.util;

    import java.io.IOException;

    import java.util.Map;

    import org.apache.commons.httpclient.HttpClient;

    import org.apache.commons.httpclient.HttpException;

    import org.apache.commons.httpclient.SimpleHttpConnectionManager;

    import org.apache.commons.httpclient.methods.GetMethod;

    import org.apache.commons.httpclient.methods.PostMethod;

    /**

    * @Author: feizi

    * @Date: 2015年4月17日 上午9:26:34

    * @ModifyUser: feizi

    * @ModifyDate: 2015年4月17日 上午9:26:34

    * @Version:V6.0

    */

    public class HttpRequestUtil {

    /**

    * HttpClient 模拟POST请求

    * 方法说明

    * @Discription:扩展说明

    * @param url

    * @param params

    * @return String

    * @Author: feizi

    * @Date: 2015年4月17日 下午7:15:59

    * @ModifyUser:feizi

    * @ModifyDate: 2015年4月17日 下午7:15:59

    */

    public static String postRequest(String url, Map params) {

    //构造HttpClient的实例

    HttpClient httpClient = new HttpClient();

    //创建POST方法的实例

    PostMethod postMethod = new PostMethod(url);

    //设置请求头信息

    postMethod.setRequestHeader("Connection", "close");

    //添加参数

    for (Map.Entry entry : params.entrySet()) {

    postMethod.addParameter(entry.getKey(), entry.getValue());

    }

    //使用系统提供的默认的恢复策略,设置请求重试处理,用的是默认的重试处理:请求三次

    httpClient.getParams().setBooleanParameter("http.protocol.expect-continue", false);

    //接收处理结果

    String result = null;

    try {

    //执行Http Post请求

    httpClient.executeMethod(postMethod);

    //返回处理结果

    result = postMethod.getResponseBodyAsString();

    } catch (HttpException e) {

    // 发生致命的异常,可能是协议不对或者返回的内容有问题

    System.out.println("请检查输入的URL!");

    e.printStackTrace();

    } catch (IOException e) {

    // 发生网络异常

    System.out.println("发生网络异常!");

    e.printStackTrace();

    } finally {

    //释放链接

    postMethod.releaseConnection();

    //关闭HttpClient实例

    if (httpClient != null) {

    ((SimpleHttpConnectionManager) httpClient.getHttpConnectionManager()).shutdown();

    httpClient = null;

    }

    }

    return result;

    }

    /**

    * HttpClient 模拟GET请求

    * 方法说明

    * @Discription:扩展说明

    * @param url

    * @param params

    * @return String

    * @Author: feizi

    * @Date: 2015年4月17日 下午7:15:28

    * @ModifyUser:feizi

    * @ModifyDate: 2015年4月17日 下午7:15:28

    */

    public static String getRequest(String url, Map params) {

    //构造HttpClient实例

    HttpClient client = new HttpClient();

    //拼接参数

    String paramStr = "";

    for (String key : params.keySet()) {

    paramStr = paramStr + "&" + key + "=" + params.get(key);

    }

    paramStr = paramStr.substring(1);

    //创建GET方法的实例

    GetMethod method = new GetMethod(url + "?" + paramStr);

    //接收返回结果

    String result = null;

    try {

    //执行HTTP GET方法请求

    client.executeMethod(method);

    //返回处理结果

    result = method.getResponseBodyAsString();

    } catch (HttpException e) {

    // 发生致命的异常,可能是协议不对或者返回的内容有问题

    System.out.println("请检查输入的URL!");

    e.printStackTrace();

    } catch (IOException e) {

    // 发生网络异常

    System.out.println("发生网络异常!");

    e.printStackTrace();

    } finally {

    //释放链接

    method.releaseConnection();

    //关闭HttpClient实例

    if (client != null) {

    ((SimpleHttpConnectionManager) client.getHttpConnectionManager()).shutdown();

    client = null;

    }

    }

    return result;

    }

    }

    2、在创建一个类,生成验证码,然后传递相应的参数(不同的短信平台接口会有不同的参数要求,这个一般短信平台提供的接口文档中都会有的,直接看文档然后按要求来即可)

    /**

    * 文件说明

    * @Description:扩展说明

    * @Copyright: 2015 dreamtech.com.cn Inc. All right reserved

    * @Version: V6.0

    */

    package com.demo.util;

    import java.net.URLEncoder;

    import java.util.HashMap;

    import java.util.Map;

    /**

    * @Author: feizi

    * @Date: 2015年4月17日 上午9:24:48

    * @ModifyUser: feizi

    * @ModifyDate: 2015年4月17日 上午9:24:48

    * @Version:V6.0

    */

    public class SendMsgUtil {

    /**

    * 发送短信消息

    * 方法说明

    * @Discription:扩展说明

    * @param phones

    * @param content

    * @return

    * @return String

    * @Author: feizi

    * @Date: 2015年4月17日 下午7:18:08

    * @ModifyUser:feizi

    * @ModifyDate: 2015年4月17日 下午7:18:08

    */

    @SuppressWarnings("deprecation")

    public static String sendMsg(String phones,String content){

    //短信接口URL提交地址

    String url = "短信接口URL提交地址";

    Map params = new HashMap();

    params.put("zh", "用户账号");

    params.put("mm", "用户密码");

    params.put("dxlbid", "短信类别编号");

    params.put("extno", "扩展编号");

    //手机号码,多个号码使用英文逗号进行分割

    params.put("hm", phones);

    //将短信内容进行URLEncoder编码

    params.put("nr", URLEncoder.encode(content));

    return HttpRequestUtil.getRequest(url, params);

    }

    /**

    * 随机生成6位随机验证码

    * 方法说明

    * @Discription:扩展说明

    * @return

    * @return String

    * @Author: feizi

    * @Date: 2015年4月17日 下午7:19:02

    * @ModifyUser:feizi

    * @ModifyDate: 2015年4月17日 下午7:19:02

    */

    public static String createRandomVcode(){

    //验证码

    String vcode = "";

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

    vcode = vcode + (int)(Math.random() * 9);

    }

    return vcode;

    }

    /**

    * 测试

    * 方法说明

    * @Discription:扩展说明

    * @param args

    * @return void

    * @Author: feizi

    * @Date: 2015年4月17日 下午7:26:36

    * @ModifyUser:feizi

    * @ModifyDate: 2015年4月17日 下午7:26:36

    */

    public static void main(String[] args) {

    // System.out.println(SendMsgUtil.createRandomVcode());

    // System.out.println("&ecb=12".substring(1));

    System.out.println(sendMsg("18123456789,15123456789", "尊敬的用户,您的验证码为" + SendMsgUtil.createRandomVcode() + ",有效期为60秒,如有疑虑请详询400-069-2886(客服电话)【XXX中心】"));

    }

    }

    然后执行一下,一般的情况下参数传递正确,按照接口文档的规范来操作的话,都会发送成功的,手机都能收到验证码的,然后可能会出现的问题就是:发送的短信内容有可能会出现中文乱码,然后就会发送不成功,按照短信平台的要求进行相应的编码即可。一般都会是UTF-8编码。

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    展开全文
  • Java / Android 基于Http多线程下载的实现

    万次阅读 多人点赞 2014-05-26 00:07:21
    有个朋友需要个多线程现在的例子,就帮忙实现了,在此分享下~ 先说下原理,原理明白了,其实很简单: a、对于网络上的一个资源,首先发送一个请求,从返回的Content-Length中回去需要下载文件的大小,然后根据文件...

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/26994463

    有个朋友需要个多线程现在的例子,就帮忙实现了,在此分享下~

    先说下原理,原理明白了,其实很简单:

    a、对于网络上的一个资源,首先发送一个请求,从返回的Content-Length中回去需要下载文件的大小,然后根据文件大小创建一个文件。

    this.fileSize = conn.getContentLength();// 根据响应获取文件大小
    File dir = new File(dirStr);
    this.localFile = new File(dir, filename);
    RandomAccessFile raf = new RandomAccessFile(this.localFile, "rw");
    raf.setLength(fileSize);
    raf.close();

    b、根据线程数和文件大小,为每个线程分配下载的字节区间,然后每个线程向服务器发送请求,获取这段字节区间的文件内容。

    conn.setRequestProperty("Range", "bytes=" + startPos + "-"
    						+ endPos);// 设置获取实体数据的范围

    c、利用RandomAccessFile的seek方法,多线程同时往一个文件中写入字节。

    raf.seek(startPos);
    while ((len = is.read(buf)) != -1)
    {
    	raf.write(buf, 0, len);
    }
    分析完了原理就很简单了,我封装了一个类,利用这个类的实例进行下载,所需参数:下载资源的URI, 本地文件路径,线程的数量。

    package com.zhy.mutilthread_download;
    
    import java.io.File;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.RandomAccessFile;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    public class MultipartThreadDownloador
    {
    
    	/**
    	 * 需要下载资源的地址
    	 */
    	private String urlStr;
    	/**
    	 * 下载的文件
    	 */
    	private File localFile;
    	/**
    	 * 需要下载文件的存放的本地文件夹路径
    	 */
    	private String dirStr;
    	/**
    	 * 存储到本地的文件名
    	 */
    	private String filename;
    
    	/**
    	 * 开启的线程数量
    	 */
    	private int threadCount;
    	/**
    	 * 下载文件的大小
    	 */
    	private long fileSize;
    
    	public MultipartThreadDownloador(String urlStr, String dirStr,
    			String filename, int threadCount)
    	{
    		this.urlStr = urlStr;
    		this.dirStr = dirStr;
    		this.filename = filename;
    		this.threadCount = threadCount;
    	}
    
    	public void download() throws IOException
    	{
    		createFileByUrl();
    
    		/**
    		 * 计算每个线程需要下载的数据长度
    		 */
    		long block = fileSize % threadCount == 0 ? fileSize / threadCount
    				: fileSize / threadCount + 1;
    
    		for (int i = 0; i < threadCount; i++)
    		{
    			long start = i * block;
    			long end = start + block >= fileSize ? fileSize : start + block - 1;
    
    			new DownloadThread(new URL(urlStr), localFile, start, end).start();
    		}
    
    	}
    
    	/**
    	 * 根据资源的URL获取资源的大小,以及在本地创建文件
    	 */
    	public void createFileByUrl() throws IOException
    	{
    		URL url = new URL(urlStr);
    		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    		conn.setConnectTimeout(15 * 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", urlStr);
    		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();
    
    		if (conn.getResponseCode() == 200)
    		{
    			this.fileSize = conn.getContentLength();// 根据响应获取文件大小
    			if (fileSize <= 0)
    				throw new RuntimeException(
    						"the file that you download has a wrong size ... ");
    			File dir = new File(dirStr);
    			if (!dir.exists())
    				dir.mkdirs();
    			this.localFile = new File(dir, filename);
    			RandomAccessFile raf = new RandomAccessFile(this.localFile, "rw");
    			raf.setLength(fileSize);
    			raf.close();
    
    			System.out.println("需要下载的文件大小为 :" + this.fileSize + " , 存储位置为: "
    					+ dirStr + "/" + filename);
    
    		} else
    		{
    			throw new RuntimeException("url that you conneted has error ...");
    		}
    	}
    
    	private class DownloadThread extends Thread
    	{
    		/**
    		 * 下载文件的URI
    		 */
    		private URL url;
    		/**
    		 * 存的本地路径
    		 */
    		private File localFile;
    		/**
    		 * 是否结束
    		 */
    		private boolean isFinish;
    		/**
    		 * 开始的位置
    		 */
    		private Long startPos;
    		/**
    		 * 结束位置
    		 */
    		private Long endPos;
    
    		public DownloadThread(URL url, File savefile, Long startPos, Long endPos)
    		{
    			this.url = url;
    			this.localFile = savefile;
    			this.startPos = startPos;
    			this.endPos = endPos;
    		}
    
    		@Override
    		public void run()
    		{
    			System.out.println(Thread.currentThread().getName() + "开始下载...");
    			try
    			{
    				HttpURLConnection conn = (HttpURLConnection) url
    						.openConnection();
    				conn.setConnectTimeout(15 * 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", url.toString());
    				conn.setRequestProperty("Charset", "UTF-8");
    				conn.setRequestProperty("Range", "bytes=" + startPos + "-"
    						+ endPos);// 设置获取实体数据的范围
    
    				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();
    
    				/**
    				 * 代表服务器已经成功处理了部分GET请求
    				 */
    				if (conn.getResponseCode() == 206)
    				{
    					InputStream is = conn.getInputStream();
    					int len = 0;
    					byte[] buf = new byte[1024];
    
    					RandomAccessFile raf = new RandomAccessFile(localFile,
    							"rwd");
    					raf.seek(startPos);
    					while ((len = is.read(buf)) != -1)
    					{
    						raf.write(buf, 0, len);
    					}
    					raf.close();
    					is.close();
    					System.out.println(Thread.currentThread().getName()
    							+ "完成下载  : " + startPos + " -- " + endPos);
    					this.isFinish = true;
    				} else
    				{
    					throw new RuntimeException(
    							"url that you conneted has error ...");
    				}
    			} catch (IOException e)
    			{
    				e.printStackTrace();
    			}
    		}
    
    	}
    
    	
    
    }
    

    createFileByUrl方法,就是我们上述的原理的步骤1,得到文件大小和创建本地文件。我在程序使用了一个内部类DownloadThread继承Thread,专门负责下载。download()方法,根据线程数量和文件大小计算每个线程需要下载的字节区间,然后开启线程去下载。

    服务器端:我就扔了几个文件在Tomcat根目录做实验,下面是测试代码:

    package com.zhy.mutilthread_download;
    
    import java.io.IOException;
    
    public class Test
    {
    
    	public static void main(String[] args)
    	{
    		try
    		{
    			new MultipartThreadDownloador("http://localhost:8080/nexus.zip",
    					"f:/backup/nexus", "nexus.zip", 2).download();
    		} catch (IOException e)
    		{
    			e.printStackTrace();
    		}
    
    	}
    }
    

    输出结果:

    需要下载的文件大小为 :31143237 , 存储位置为: f:/backup/nexus/nexus.zip
    Thread-1开始下载...
    Thread-2开始下载...
    Thread-3开始下载...
    Thread-4开始下载...
    Thread-4完成下载  : 23357430 -- 31143237
    Thread-2完成下载  : 7785810 -- 15571619
    Thread-1完成下载  : 0 -- 7785809
    Thread-3完成下载  : 15571620 -- 23357429
    

    截图:



    ok,多线程下载介绍完毕,如果代码设计不合理,以及方法使用错误,欢迎各位留言,,,



    源码点击下载





    展开全文
  • 本文探讨基于tesseract的多线程OCR服务器的JAVA实现,可同时对多个android手机客户端提供图片OCR服务  project源码下载 http://download.csdn.net/user/yangliuy   最近接手一个项目,项目的背景是要开发一个CS...

    本文探讨基于tesseract的多线程OCR服务器的JAVA实现,可同时对多个android手机客户端提供图片OCR服务 

    project源码下载 http://download.csdn.net/user/yangliuy   

    最近接手一个项目,项目的背景是要开发一个CS架构的发票真伪识别系统,客户端为android手机,采集发票图像传到服务器做OCR识别,识别出来的发票号码和发票密码发送到国税局官网发票真伪查询页面,然后将真伪信息返回给手机用户。为了开发一个多线程OCR服务器,我研究了JAVA图像处理及OCR技术。JAVA的强大的图形处理相关库如java.awt.image等为采集图像的裁剪、放缩、二值化、去噪等提供了良好的基础,而OCR主要采用了Goolge tesseract开源OCR引擎,tesseract安装在本地后可以用cmd命令行调用,而JAVA支持cmd命令的调用。此外还用到了JAVA线程池、互斥锁等多线程编程技术及socket等网络编程技术。源码如下

    多线程Server端 Server.java

    package com.serverMain;
    import java.net.ServerSocket;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.io.IOException;
    
    /**
     * @author yangliuis@pku.edu.cn
     *
     */
    
    public class Server extends Thread{
    	private int port ;
    	private ServerSocket server;
    	private ExecutorService threadPool;//线程池
    	
    	public Server(int port) {
    		super();
    		this.port = port;
    	}
    	
    	public void startServer ()throws IOException{
    		server = new ServerSocket(port);
    		threadPool = Executors.newCachedThreadPool();
    		System.out.println("欢迎使用Helios系统,服务器启动");
    		this.start();
    	}
    	
    	public void run(){
    		while(true){ 
    			try {
    				ServerRun task = new ServerRun(server.accept());
    				threadPool.execute(task);
    			} catch (IOException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    	}
    	/**
    	 * @param args
    	 * @throws IOException 
    	 */
    	public static void main(String[] args) throws IOException {
    		// TODO Auto-generated method stub
    		Server server = new Server(8089);
    		server.startServer();
    	}
    }
    

    Server端任务ServerRun.java

    package com.serverMain;
    import java.net.Socket;
    import java.net.URL;
    import java.net.URLConnection;
    import java.io.BufferedReader;
    import java.io.DataInputStream;
    import java.io.BufferedOutputStream;
    import java.io.FileOutputStream;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    
    import com.imageHandle.OperateImage;
    import com.imageHandle.SoundBinImage;
    
    /**
     * @author yangliuis@pku.edu.cn
     *
     */
    
    public class ServerRun extends Thread implements Runnable{
    	private static Integer invoicePicNum = 0;//发票图片序号
    	//private static Integer captchasPicNum = 0;//验证码图片序号
    	private Socket socket;
    	private final String  invoiceDir = "F://Helios//data//invoice_image//";
    	//private final String  captchasDir = "F://Helios//data//captchas_image//";
    		
    	public ServerRun(Socket socket){
    		this.socket = socket;
    	}
    	
    	public void run(){
    		String invoicePicFilename = invoiceDir+"invoice_image_";
    		invoicePicFilename += invoicePicNum+".jpg";		
    		try {
    			DataInputStream dis = new DataInputStream(socket.getInputStream());
    			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(invoicePicFilename));
    			byte buffer[] = new byte[1024];
    			int eof = 0;
    			while((eof = dis.read(buffer, 0, 1024)) != -1) {
    				bos.write(buffer, 0 ,eof);
    			}
    			System.out.println("收到图片"+invoicePicFilename+"开始识别该图片");
    			String invoiceInfo[] = new String[10];
    			//发票信息包括发票代码、发票号码、发票密码
    			String invoiceResult;//识别结果
    			invoiceInfo = doOCRInvoice(invoicePicFilename);
    			invoiceResult = postCheckInvoice(invoiceInfo);
    			System.out.println("发票验证结束,验证结果为:"+invoiceResult);
    			bos.close();
    			dis.close();
    			socket.close();
    			synchronized (invoicePicNum){
    			//invoicePicNum是图片序号,需要加锁,是多个线程操作互斥
    				invoicePicNum++;
    			}
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}	
    	}
    
    	/**
    	 * @param invoiceInfo
    	 */
    	private String postCheckInvoice(String[] invoiceInfo) throws IOException{
    		// TODO Auto-generated method stub
    		String fpdm = invoiceInfo[0];
    		String fphm = invoiceInfo[1];
    		//String fphm = "27404666";//实验假发票的情况
    		String fpmm = invoiceInfo[2];
    		String result = "发票为假!";
    		URL url;	
    		url = new URL("http://www.bjtax.gov.cn/ptfp/turn.jsp");
    		URLConnection connection = url.openConnection();
    		connection.setDoOutput(true);
    		OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(),"8859_1");
    		String post = "fpdm="+fpdm+"&fphm="+fphm+"&fpmm="+fpmm+"&yzms=111111&sfzh=11111111111111111111&ip=127.0.0.1&isFrist=1";
    		out.write(post);	
    		out.flush();
    		out.close();
    		String sCurrentLine = "";
    		String sTotalString = "";
    		InputStream l_urlStream = connection.getInputStream();
    		BufferedReader l_reader = new BufferedReader(new InputStreamReader(l_urlStream, "utf-8"));
    		while((sCurrentLine = l_reader.readLine()) != null)
    		{
    			sTotalString = sCurrentLine +"\r\n";
    			if(sTotalString.indexOf("正确查询")!=-1)
    				result = "发票为真!";		
    		}	
    		return result;	
    	}
    
    	/**
    	 * @param String invoicePicFilename
    	 * @return String[] invoiceInfo
    	 * @throws InterruptedException 
    	 * @throws IOException 
    	 */
    	private String[] doOCRInvoice(String invoicePicFilename) throws InterruptedException, IOException {
    		// TODO Auto-generated method stub
    		String invoiceInfo[] = new String[10];
    		//图像裁剪
            OperateImage oPassword  =   new  OperateImage(700,2450,400,170);
            try {
            oPassword.setSrcpath(invoicePicFilename);  
            oPassword.setSubpath( invoiceDir+"password"+invoicePicNum+".jpg");
            oPassword.cut() ; 
            OperateImage oNumber  =   new  OperateImage(320,80,800,300);
            oNumber.setSrcpath(invoicePicFilename);  
            oNumber.setSubpath(invoiceDir+"number"+invoicePicNum+".jpg");
            oNumber.cut() ;    
            } catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} 
    		//过滤背景色及图像二值化
            new SoundBinImage().releaseSound(invoiceDir+"password"+invoicePicNum+".jpg",invoiceDir+"binpassword"+invoicePicNum+".png",60);
            new SoundBinImage().releaseSound(invoiceDir+"number"+invoicePicNum+".jpg",invoiceDir+"binnumber"+invoicePicNum+".png",130);//png识别准确度更高
            
    		//OCR识别
            String invoiceBinNumberFileName = invoiceDir+"binnumbertxt"+invoicePicNum;
            String invoiceBinPasswordFileName = invoiceDir+"binpasswordtxt"+invoicePicNum;
            Runtime run = Runtime.getRuntime();       
            Process pr1 = run.exec("cmd.exe /c tesseract "+invoiceDir+"binnumber"+invoicePicNum+".png"+" "+invoiceBinNumberFileName+" -l eng");
            Process pr2 = run.exec("cmd.exe /c tesseract "+invoiceDir+"binpassword"+invoicePicNum+".png"+" "+invoiceBinPasswordFileName+" -l eng");
            pr1.waitFor();//让调用线程阻塞,直到exec调用OCR完毕,否则会报错找不到txt文件
            pr2.waitFor();
            String line;
            int i = 0;
            //注意这里生成txt是需要时间的,所有进程需要等待直到返回再继续执行,否则就会找不到文件
            FileReader frNum = new FileReader(invoiceBinNumberFileName+".txt");
            FileReader frPass = new FileReader(invoiceBinPasswordFileName+".txt");
            BufferedReader brNum = new BufferedReader(frNum);
            while ((line = brNum.readLine()) != null)
            {
            	invoiceInfo[i++] = line;
            }
            BufferedReader brPass = new BufferedReader(frPass);
            i--;
            while ((line = brPass.readLine()) != null)
            {
            	invoiceInfo[i++] = line;
            }
            brNum.close();
            brPass.close(); 
            frNum.close();
            frPass.close();
            System.out.println("OCR识别结果:"+invoiceInfo[0]+" "+invoiceInfo[1]+" "+invoiceInfo[2]);
    		return invoiceInfo;
    	}
    
    }
    

    图形处理类
    图像过滤背景色及黑白二值化 SoundBinImage.java

    package com.imageHandle;
     
    import java.awt.image.BufferedImage;
    import java.awt.image.Raster;
    import java.awt.image.WritableRaster;
    import java.io.File;
    import java.io.IOException;
    import javax.imageio.ImageIO;
     
    public class SoundBinImage {
    	public void releaseSound(String filepath,String destpath, int Threshold){
    		//过滤背景色进行黑白二值化处理
    		try {
    			BufferedImage bi=ImageIO.read(new File(filepath));
    			int width=bi.getWidth();
    			int height=bi.getHeight();
     			BufferedImage bi2=new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
    			Raster raster=bi.getRaster();
    			WritableRaster wr=bi2.getRaster();
    			for(int i=0;i<width;i++){
    				for(int j=0;j<height;j++){
    					int[] a=new int[4];
    					raster.getPixel(i, j, a);
    					//System.out.println("("+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+")");
    					if((a[0]+a[1]+a[2])/3>Threshold){
    						a[0]=255;
    						a[1]=255;
    						a[2]=255;
    						a[3]=255;
    						wr.setPixel(i, j, a);
    					}else{
    						a[0]=0;
    						a[1]=0;
    						a[2]=0;
    						a[3]=255;
    						wr.setPixel(i, j, a);
     
    					}
    				}
    			}
    			ImageIO.write(bi2, "PNG", new File(destpath));
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    	public static void main(String[] args) {
    		new SoundBinImage().releaseSound("C:\\deletesound\\password1.jpg","C:\\deletesound\\result.png", 60);
    	}
    }

    图片裁剪 OperateImage.java

    package com.imageHandle;
    
    import java.awt.Rectangle;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.util.Iterator;
    
    import javax.imageio.ImageIO;
    import javax.imageio.ImageReadParam;
    import javax.imageio.ImageReader;
    import javax.imageio.stream.ImageInputStream;
    
    
    public class OperateImage {
           
        //===源图片路径名称如:c:/1.jpg 
        private String srcpath ;
             
        //===剪切图片存放路径名称.如:c:/2.jpg
        private String subpath ;
        
        //===剪切点x坐标
        private int x ;
        
        private int y ;    
          
        //===剪切点宽度
        private int width ;
         
        private int height ;
        
        public OperateImage(){
                
        }  
        public OperateImage(int x,int y,int width,int height){
             this.x = x ;
             this.y = y ;
             this.width = width ;   
             this.height = height ;
        }
        
        /** 
         * 对图片裁剪,并把裁剪完蛋新图片保存 。
         */
        public void cut() throws IOException{ 
             
            FileInputStream is = null ;
            ImageInputStream iis =null ;
         
            try{   
                //读取图片文件
                is = new FileInputStream(srcpath); 
                
                /*
                 * 返回包含所有当前已注册 ImageReader 的 Iterator,这些 ImageReader 
                 * 声称能够解码指定格式。 参数:formatName - 包含非正式格式名称 .
                 *(例如 "jpeg" 或 "tiff")等 。 
                 */
                Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName("jpg");  
                ImageReader reader = it.next(); 
                //获取图片流 
                iis = ImageIO.createImageInputStream(is);
                   
                /* 
                 * <p>iis:读取源.true:只向前搜索 </p>.将它标记为 ‘只向前搜索’。
                 * 此设置意味着包含在输入源中的图像将只按顺序读取,可能允许 reader
                 *  避免缓存包含与以前已经读取的图像关联的数据的那些输入部分。
                 */
                reader.setInput(iis,true);
                
                /* 
                 * <p>描述如何对流进行解码的类<p>.用于指定如何在输入时从 Java Image I/O 
                 * 框架的上下文中的流转换一幅图像或一组图像。用于特定图像格式的插件
                 * 将从其 ImageReader 实现的 getDefaultReadParam 方法中返回 
                 * ImageReadParam 的实例。  
                 */
                ImageReadParam param = reader.getDefaultReadParam(); 
                 
                /*
                 * 图片裁剪区域。Rectangle 指定了坐标空间中的一个区域,通过 Rectangle 对象
                 * 的左上顶点的坐标(x,y)、宽度和高度可以定义这个区域。 
                 */ 
                Rectangle rect = new Rectangle(x, y, width, height); 
                
                  
                //提供一个 BufferedImage,将其用作解码像素数据的目标。 
                param.setSourceRegion(rect); 
    
                /*
                 * 使用所提供的 ImageReadParam 读取通过索引 imageIndex 指定的对象,并将
                 * 它作为一个完整的 BufferedImage 返回。
                 */
                BufferedImage bi = reader.read(0,param);                
          
                //保存新图片 
                ImageIO.write(bi, "jpg", new File(subpath));     
            }
            
            finally{
                if(is!=null)
                   is.close() ;       
                if(iis!=null)
                   iis.close();  
            } 
            
             
         
        }
    
        public int getHeight() {
            return height;
        }
    
        public void setHeight(int height) {
            this.height = height;
        }
    
        public String getSrcpath() {
            return srcpath;
        }
    
        public void setSrcpath(String srcpath) {
            this.srcpath = srcpath;
        }
    
        public String getSubpath() {
            return subpath;
        }
    
        public void setSubpath(String subpath) {
            this.subpath = subpath;
        }
    
        public int getWidth() {
            return width;
        }
    
        public void setWidth(int width) {
            this.width = width;
        }
    
        public int getX() {
            return x;
        }
    
        public void setX(int x) {
            this.x = x;
        }
    
        public int getY() {
            return y;
        }
    
        public void setY(int y) {
            this.y = y;
        } 
        public static void main(String[] args)throws Exception{
        	 String name  =   "C:\\caijian\\bb.jpg" ;
             OperateImage oPassword  =   new  OperateImage(700,2450,400,170);
             oPassword.setSrcpath(name);  
             oPassword.setSubpath( "C:\\caijian\\bbpassword.jpg" );
             oPassword.cut() ;  
             OperateImage oNumber  =   new  OperateImage(320,80,800,300);
             oNumber.setSrcpath(name);  
             oNumber.setSubpath( "C:\\caijian\\bbnumber.jpg" );
             oNumber.cut() ;     
        }
    
    
    }
    

    测试客户端Client.java 大家测试的话注意修改服务器地址为本机地址,待识别图片为F://Helios//android//invoice_test.jpg

    package com.serverMain;
    import java.io.BufferedInputStream;
    import java.io.DataOutputStream;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.net.Socket;
    
    /**
     * @author yangliuis@pku.edu.cn
     *
     */
    
    public class Client {
    	private Socket socket;
    	public Client(){
    		
    	}
    	public void SendImage() throws IOException{
    		String imageFileName = "F://Helios//android//invoice_test.jpg";
    		socket = new Socket("192.168.1.102", 8089);
    		try {
    			BufferedInputStream bis =new BufferedInputStream(new FileInputStream(imageFileName));
    			DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
    			byte buffer[] = new byte[1024];//一次读1K,循环读写图片字节流
    			int eof = 0;
    			while((eof = bis.read(buffer, 0 ,1024)) != -1){
    				dos.write(buffer, 0, eof);
    			}
    			dos.close();
    			bis.close();
    			socket.close();
    		} catch (FileNotFoundException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    
    	public static void main(String s[]) throws IOException {
    		Client client = new Client();
    		client.SendImage();
    	}
    }
    





    展开全文
  • 有个朋友需要个多线程现在的例子,就帮忙实现了,在此分享下~先说下原理,原理明白了,其实很简单:a、对于网络上的一个资源,首先发送一个请求,从返回的Content-Length中回去需要下载文件的大小,然后根据文件大小...

    有个朋友需要个多线程现在的例子,就帮忙实现了,在此分享下~

    先说下原理,原理明白了,其实很简单:

    a、对于网络上的一个资源,首先发送一个请求,从返回的Content-Length中回去需要下载文件的大小,然后根据文件大小创建一个文件。

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

    File dir = new File(dirStr);

    this.localFile = new File(dir, filename);

    RandomAccessFile raf = new RandomAccessFile(this.localFile, "rw");

    raf.setLength(fileSize);

    raf.close();

    b、根据线程数和文件大小,为每个线程分配下载的字节区间,然后每个线程向服务器发送请求,获取这段字节区间的文件内容。

    conn.setRequestProperty("Range", "bytes=" + startPos + "-"

    + endPos);// 设置获取实体数据的范围

    c、利用RandomAccessFile的seek方法,多线程同时往一个文件中写入字节。

    raf.seek(startPos);

    while ((len = is.read(buf)) != -1)

    {

    raf.write(buf, 0, len);

    }分析完了原理就很简单了,我封装了一个类,利用这个类的实例进行下载,所需参数:下载资源的URI, 本地文件路径,线程的数量。

    package com.zhy.mutilthread_download;

    import java.io.File;

    import java.io.IOException;

    import java.io.InputStream;

    import java.io.RandomAccessFile;

    import java.net.HttpURLConnection;

    import java.net.URL;

    public class MultipartThreadDownloador

    {

    /**

    * 需要下载资源的地址

    */

    private String urlStr;

    /**

    * 下载的文件

    */

    private File localFile;

    /**

    * 需要下载文件的存放的本地文件夹路径

    */

    private String dirStr;

    /**

    * 存储到本地的文件名

    */

    private String filename;

    /**

    * 开启的线程数量

    */

    private int threadCount;

    /**

    * 下载文件的大小

    */

    private long fileSize;

    public MultipartThreadDownloador(String urlStr, String dirStr,

    String filename, int threadCount)

    {

    this.urlStr = urlStr;

    this.dirStr = dirStr;

    this.filename = filename;

    this.threadCount = threadCount;

    }

    public void download() throws IOException

    {

    createFileByUrl();

    /**

    * 计算每个线程需要下载的数据长度

    */

    long block = fileSize % threadCount == 0 ? fileSize / threadCount

    : fileSize / threadCount + 1;

    for (int i = 0; i < threadCount; i++)

    {

    long start = i * block;

    long end = start + block >= fileSize ? fileSize : start + block - 1;

    new DownloadThread(new URL(urlStr), localFile, start, end).start();

    }

    }

    /**

    * 根据资源的URL获取资源的大小,以及在本地创建文件

    */

    public void createFileByUrl() throws IOException

    {

    URL url = new URL(urlStr);

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

    conn.setConnectTimeout(15 * 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", urlStr);

    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();

    if (conn.getResponseCode() == 200)

    {

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

    if (fileSize <= 0)

    throw new RuntimeException(

    "the file that you download has a wrong size ... ");

    File dir = new File(dirStr);

    if (!dir.exists())

    dir.mkdirs();

    this.localFile = new File(dir, filename);

    RandomAccessFile raf = new RandomAccessFile(this.localFile, "rw");

    raf.setLength(fileSize);

    raf.close();

    System.out.println("需要下载的文件大小为 :" + this.fileSize + " , 存储位置为: "

    + dirStr + "/" + filename);

    } else

    {

    throw new RuntimeException("url that you conneted has error ...");

    }

    }

    private class DownloadThread extends Thread

    {

    /**

    * 下载文件的URI

    */

    private URL url;

    /**

    * 存的本地路径

    */

    private File localFile;

    /**

    * 是否结束

    */

    private boolean isFinish;

    /**

    * 开始的位置

    */

    private Long startPos;

    /**

    * 结束位置

    */

    private Long endPos;

    public DownloadThread(URL url, File savefile, Long startPos, Long endPos)

    {

    this.url = url;

    this.localFile = savefile;

    this.startPos = startPos;

    this.endPos = endPos;

    }

    @Override

    public void run()

    {

    System.out.println(Thread.currentThread().getName() + "开始下载...");

    try

    {

    HttpURLConnection conn = (HttpURLConnection) url

    .openConnection();

    conn.setConnectTimeout(15 * 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", url.toString());

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

    conn.setRequestProperty("Range", "bytes=" + startPos + "-"

    + endPos);// 设置获取实体数据的范围

    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();

    /**

    * 代表服务器已经成功处理了部分GET请求

    */

    if (conn.getResponseCode() == 206)

    {

    InputStream is = conn.getInputStream();

    int len = 0;

    byte[] buf = new byte[1024];

    RandomAccessFile raf = new RandomAccessFile(localFile,

    "rwd");

    raf.seek(startPos);

    while ((len = is.read(buf)) != -1)

    {

    raf.write(buf, 0, len);

    }

    raf.close();

    is.close();

    System.out.println(Thread.currentThread().getName()

    + "完成下载 : " + startPos + " -- " + endPos);

    this.isFinish = true;

    } else

    {

    throw new RuntimeException(

    "url that you conneted has error ...");

    }

    } catch (IOException e)

    {

    e.printStackTrace();

    }

    }

    }

    }

    createFileByUrl方法,就是我们上述的原理的步骤1,得到文件大小和创建本地文件。我在程序使用了一个内部类DownloadThread继承Thread,专门负责下载。download()方法,根据线程数量和文件大小计算每个线程需要下载的字节区间,然后开启线程去下载。

    服务器端:我就扔了几个文件在Tomcat根目录做实验,下面是测试代码:

    package com.zhy.mutilthread_download;

    import java.io.IOException;

    public class Test

    {

    public static void main(String[] args)

    {

    try

    {

    new MultipartThreadDownloador("http://localhost:8080/nexus.zip",

    "f:/backup/nexus", "nexus.zip", 2).download();

    } catch (IOException e)

    {

    e.printStackTrace();

    }

    }

    }

    输出结果:

    需要下载的文件大小为 :31143237 , 存储位置为: f:/backup/nexus/nexus.zip

    Thread-1开始下载...

    Thread-2开始下载...

    Thread-3开始下载...

    Thread-4开始下载...

    Thread-4完成下载 : 23357430 -- 31143237

    Thread-2完成下载 : 7785810 -- 15571619

    Thread-1完成下载 : 0 -- 7785809

    Thread-3完成下载 : 15571620 -- 23357429

    截图:

    e98845829cd80d7500387ac78be61381.png

    ok,多线程下载介绍完毕,如果代码设计不合理,以及方法使用错误,欢迎各位留言,,,

    展开全文
  • 当我们执行一个比较耗时的方法时,http请求得不到响应甚至会超时,这时如果业务上允许数据的延迟,我们可以使用多线程来进行处理比较耗时的方法。这样前端发送了请求,后端令开启了一个线程去处理任务,就不会阻塞...
  • 如何使用java多线程处理http请求 1、客户端浏览器发送一个http请求给servlet 2、servlet接到请求将这个使用10个子线程去处理 3、10个子线程处理完成后将结果汇总返回给你客户端 这样的话可以采用CountDownLatch...
  • java使用socket实现一个多线程web服务器除了服务器类,还包括请求类和响应类请求类:获取客户的HTTP请求,分析客户所需要的文件响应类:获得用户请求后将用户需要的文件读出,添加上HTTP应答头。发送给客户端。...
  • 根据http协议的会话过程,实验实现了GET请求的web服务器的方法:通过创建ServerSocket类对象。侦听用户指定端口,等待并接受客户机请求到端口。创建与Socket相关联的输入流输出流,然后读取客户机的请求信息。若请求...
  • 多线程Java

    2020-07-13 16:25:07
    1异步的实现发送短信,快速提高响应,对用户的体验就非常好 2.异步的记录日志 3.对我们后端接口中比较耗时间的代码都可以采用异步实现。 为什么需要用到多线程 http属于同步,整个过程基于请求和响应的过程,如果...
  • 除了服务器类,还包括请求类和响应类请求类:获取客户的HTTP请求,分析客户所需要的文件响应类:获得用户请求后将用户需要的文件...//使用Socket创建一个WEB服务器,本程序是多线程系统以提高反应速度。class Web...
  • 有个朋友须要个多线程如今的样例,就帮忙实现了。在此分享下~ 先说下原理,原理明确了,事实上非常easy: a、对于网络上的一个资源,首先发送一个请求,从返回的Content-Length中回去须要下载文件的大小。然后依据...
  • 所谓爬虫程序,就是模拟浏览器发送http请求给web网站。这里我们实现一个这样的爬虫程序:列出segmentfault网站中指定用户所有文章及其阅读人数的程序基本思路是这样的:1我们进入某用户的文章列表页2获得文章列表3对...
  • 链接地址:...其中采用Java 5的ExecutorService来进行线程池的方式实现多线程,模拟客户端多用户向同一服务器端发送请求. 1.服务端 package stern

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 139
精华内容 55
关键字:

java实现多线程发送http

java 订阅