网络编程框架

网络编程

Socket网络通信编程

在这里插入图片描述

Socket主要解决一个网间进程通信(不同主机进程间的相互通信问题)。

提供进程通信的端点,一个程序将一段信息写入Socket中,该Socket将这段信息发送给另外一个Socket中,使这段信息能传送到其他程序中。

Socket实现需要解决的两个问题:网间进程标识与多重协议的识别

Socket三种类型:原始式套接字,流式套接字、数据报式套接字。

原始式套接字(Sock_RAW):该接口允许对较低层次协议,如IP直接访问,可以接收本机网卡上的数据帧或数据包,对监听网络流量和分析很有用。

流式套接字(SOCK_STREAM):提供了一个面向连接,可靠的数据传输服务,数据无差错,无重复的发生,且按发送顺序接收,内设流量控制,避免超限。(TCP协议,类似打电话,有人呼叫,有人应答)。Java平台封装的流式套接字类:Socket类和ServerSocket类。

数据报式套节奏(SOCK_DGRAM):无连接服务,数据报以独立包形式被发送,不提供无差错保证,数据可能丢失或重复,并且接收顺序无需,对应的是UDP协议。

一个完整的网间通信需要一个五元组来标识:协议,本地地址,本地端口,远程地址,远程端口

http://c.biancheng.net/view/2125.html

TCP连接

在这里插入图片描述

ServerSocket与Socket

每个Socket实例会关联一个InputStream和OutputStream对象,我们通过将字节写入套接字的OutputStream来发送数据,并通过从InputStream来接收数据。

先开服务端再启动客户端。

ServerSocket服务器端

1)ServerSocket(int port) 创建对象server并指定监听端口。

2)accept()阻塞等待客户端连接,获取客户端Socket对象。此方法在客户端连接之前一直阻塞。

3)读/写

读:getOutputStream()

读对象需要反序列化

写:getInputStream()

4)colsed()关闭socket,关闭server。

Socket客户端

1)Socket(String host, int port) 创建对象socket,

2 )SocketAddress address= new InetSocketAddress(String host, int port);指定服务器的IP及端口。

3)socket.connect(address);

4)读/写

读:getInputStream()

写:getOutputStream()

传送对象需要序列化

5)colsed()关闭socket。

/**
* 判断是否断开连接,断开返回true,没有返回false
* 
* @param socket
* @return
*/
public Boolean isServerClose(Socket socket) {
    try {
        // 发送1个字节的紧急数据,默认情况下,服务器端没有开启紧急数据处理,不影响正常通信
        socket.sendUrgentData(0);
        return false;
    } catch (Exception e) {
        return true;
    }
}

Netty

https://juejin.im/post/5bdaf8ea6fb9a0227b02275a

UDP连接

在这里插入图片描述

DatagramPacket类包装要发送的信息;DatagramSocket类完成信息的发送。

服务器端:
DatagramPacket(byte[]buf, intlength , InetAddressaddress , intport)	实例化对象;指定数据,数据长度,目标地址和端口。
getData()	获取接收的数据
getLength()	获取发送或者接收数据的长度
客户端:
DatagramSocket(int	port)	创建对象,并指定端口
send(DatagramPacket dp)	发送数据报
receive(DatagramPacket dp)	接收数据报

其他

MulticastSocket 多播数据报
DatagramSocket
DatagramPacket
InetSocketAddress 类

Netty

net网络通信包

InetAddress

通过主机名来获取ip地址,也可以通过ip地址来获取主机。还可以通过InetAddress.getLocalHost()方法来获取本地的ip地址和主机名,但要注意地是,这里的查询结果是登记在本地dns中的信息。而不是枚举本地网卡。

InetAddress方法作用
getByName(主机名)通过主机名获取主机ip
getLocalHost通过本机得到InetAddress对象
getHostName获取IP地址
getHostAddress()获取本机IP
isReachable(int time)判断地址是否可以到达,并指定超时时间
getAddress
getPort
getData
getOffset
getLength
setData
setAddress
setSocketAddress
setLength
getSocketAddress

URL 统一资源定位符

1)URL类与URLConnection类
2)URLEncoder类的encode(String data,String enc)将字符串编码;

URLDecoder类的decoder(String data,String enc)将字符串解码;

NetworkInterface本地网络接口

代表 实际的硬件(网卡)或虚拟的网络地址。可以使用getNetworkInterfaces方法来枚举本地所有的网络接口。也可以通过传入网卡名(如eth0或lo)来获得本类的实例。

没有public的构造方法。因此,必须通过它的两个静态方法来创建NetworkInterface对象。可以使用两种方法来创建NetworkInterface对象:网络接口名(getByName方法)和IP地址(getByInetAddress方法)。

getByName

通过网络接口名来创建NetworkInterface对象。这个网络接口名并不是计算机名,而是用于标识物理或逻辑网络接口的名字,一般是由操作系统设置的。网络接口名在大多数操作系统上(包括Windows、Linux和Unix)是以eth开头,后面是网络接口的索引号,从0开始。如本机安了三块网卡,那么网络接口名就依次是eth0、eth1和eth2。

getByInetAddress

来确定一个IP地址属于哪一个网络接口。由于getByInetAddress方法必须使用一个InetAddress对象封装的IP地址来作为参数,因此,在使用getByInetAddress方法之前,必须先创建一个InetAddress对象。但要注意不能使用远程的IP的域名来创建InetAddress对象,否则getByInetAddress将返回null。

public static String getIP_IPV4() throws SocketException{
    Enumeration<NetworkInterface> n = NetworkInterface.getNetworkInterfaces();
    String ipAddr = "";
    for (; n.hasMoreElements();){
        NetworkInterface e = n.nextElement();
        //查找以eth开头的设备
        if(e.getName().startsWith("eth")){
            System.out.println("interface: "+e.getName());
            Enumeration<InetAddress> a = e.getInetAddresses();
            for (; a.hasMoreElements();){
                InetAddress addr = a.nextElement();
                System.out.println("  "+addr.getHostAddress());
                if(addr.getHostAddress().indexOf(":")>=0){
                    ipAddr = addr.getHostAddress();
                    break;
                }
            }
        }
        if(ipAddr.length()>0) break;
    }
    return ipAddr;
}

HTTP

HttpURLConnectin

1.下载远端文件

package com.alipay.util;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
 
/**
 * @Name: RemoteFile.java
 * @Description: Java下载远程文件到本地。
 * @Author: PeiFeng
 * @Create Date: 2017-8-12
 */
public class RemoteFile {
 
    public static void main(String[] args) throws Exception {
 
        downRemoteFile(
                "https://image.baidu.com/search/down?tn=download&ipn=dwnl&word=download&ie=utf8&fr=result&url=http%3A%2F%2Fh.hiphotos.baidu.com%2Fzhidao%2Fpic%2Fitem%2F060828381f30e9240ff2cd434c086e061d95f76a.jpg&thumburl=https%3A%2F%2Fss2.bdstatic.com%2F70cFvnSh_Q1YnxGkpoWK1HF6hhy%2Fit%2Fu%3D2504031429%2C1727248259%26fm%3D26%26gp%3D0.jpg",
                "sssss.jpg", "D:/sss");
 
    }
 
    /**
     * @Name: downRemoteFile。
     * @Description: 下载远程文件。
     * @Parameters: remoteFileUrl,要下载的远程文件地址。
     * @Parameters: saveFileName,下载后保存的文件名。
     * @Parameters: saveDir,下载后保存的文件路径。
     * @Return: String,文件保存的地址。
     * @Author: PeiFeng
     * @Version: V1.00
     * @Create Date: 2017-8-12
     */
    public static String downRemoteFile(String remoteFileUrl, String saveFileName, String saveDir) {
 
        HttpURLConnection conn = null;
        OutputStream oputstream = null;
        InputStream iputstream = null;
 
        try {
            // 创建保存文件的目录
            File savePath = new File(saveDir);
            if (!savePath.exists()) {
                savePath.mkdir();
            }
            // 创建保存的文件
            File file = new File(savePath + "/" + saveFileName);
            if (file != null && !file.exists()) {
                file.createNewFile();
            }
 
            URL url = new URL(remoteFileUrl);
            // 将url以open方法返回的urlConnection连接强转为HttpURLConnection连接(标识一个url所引用的远程对象连接)
            // 此时cnnection只是为一个连接对象,待连接中
            conn = (HttpURLConnection) url.openConnection();
            // 设置是否要从 URL连接读取数据,默认为true
            conn.setDoInput(true);
            // 建立连接
            // (请求未开始,直到connection.getInputStream()方法调用时才发起,以上各个参数设置需在此方法之前进行)
            conn.connect();
            // 连接发起请求,处理服务器响应 (从连接获取到输入流)
            iputstream = conn.getInputStream();
            // 创建文件输出流,用于保存下载的远程文件
            oputstream = new FileOutputStream(file);
            //  用来存储响应数据
            byte[] buffer = new byte[4 * 1024];
            int byteRead = -1;
            //  循环读取流
            while ((byteRead = (iputstream.read(buffer))) != -1) {
                oputstream.write(buffer, 0, byteRead);
            }
            //  输出完成后刷新并关闭流
            oputstream.flush();
 
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                //  重要且易忽略步骤 (关闭流,切记!)
                if (iputstream != null) {
                    iputstream.close();
                }
                if (oputstream != null) {
                    oputstream.close();
                }
                // 销毁连接
                if (conn != null) {
                    conn.disconnect();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // 返回保存后的文件路径
        return saveDir + "/" + saveFileName;
    }
}

2.获取HTTP地址响应信息

public static void sendData(final String urlStr, final String msg, final boolean flag) throws Exception{
	HttpURLConnection connection = null;
	URL url = null;
	PrintWriter pw = null;
	InputStream inputStream = null;
	try{
		url = new URL(urlStr); // 1. 获取访问地址URL
		connection = (HttpURLConnection) url.openConnection(); // 2. 创建HttpURLConnection对象
		/* 3. 设置请求参数 */
		connection.setRequestMethod("POST");// 请求方式
		// 设置使用标准编码格式编码参数的名-值对
		//方式一:覆盖已经存在的key的所有values,有清零重新赋值的作用
		connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
		//方式二:在原来key的基础上继续添加其他value。
		connection.addRequestProperty();
		connection.setDoOutput(true);// 设置是否输出
		connection.setConnectTimeout(3000);// 超时时间
		connection.setDoInput(true);// 设置是否读入
		connection.setUseCaches(false);// 设置是否使用缓存
		connection.setInstanceFollowRedirects(true);// 设置此 HttpURLConnection 实例是否应该自动执行 HTTP 重定向
		
		pw = new PrintWriter(new OutputStreamWriter(connection.getOutputStream(),"utf-8"), true);// 发送URL请求
		pw.println(msg);// 把参数写入
		inputStream = connection.getInputStream();
		if (flag){
			int code = connection.getResponseCode();// 得到响应状态码的返回值;code为200时代表正常响应
		}
	}catch (MalformedURLException e){
		e.printStackTrace();
		throw e;
	}catch (IOException e){
		e.printStackTrace();
		throw e;
	}finally{
		if (null != pw){
			pw.flush();
			pw.close();
			pw = null;
		}
		if (null != inputStream){
			try{
				inputStream.close();
			}catch (IOException e){
				e.printStackTrace();
			}
		}
		if(connection!=null){
			connection.disconnect(); // 5. 断开连接
		}
	}
}


//发送http数据
HttpURLConnection connection = null;
URL url = null;
PrintWriter pw = null;
InputStream inputStream = null;
try {
    // 1. 获取访问地址URL
    url = new URL("URL");
    // 2. 创建HttpURLConnection对象
    connection = (HttpURLConnection) url.openConnection();
    /* 3. 设置请求参数等 */
    // 请求方式
    connection.setRequestMethod("POST");
    // 超时时间
    connection.setConnectTimeout(3000);
    // 设置是否输出
    connection.setDoOutput(true);
    // 设置是否读入
    connection.setDoInput(true);
    // 设置是否使用缓存
    connection.setUseCaches(false);
    // 设置此 HttpURLConnection 实例是否应该自动执行 HTTP 重定向
    connection.setInstanceFollowRedirects(true);
    // 设置使用标准编码格式编码参数的名-值对
    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    // 连接
    connection.connect();
    /* 4. 处理输入输出 */
    // 写入参数到请求中
    String params = "username=test&password=123456";
    OutputStream out = connection.getOutputStream();
    out.write(params.getBytes());
    out.flush();
    out.close();
    // 从连接中读取响应信息
    String msg = "";
    int code = connection.getResponseCode();
    if (code == 200) {
        BufferedReader reader = new BufferedReader(
            new InputStreamReader(connection.getInputStream()));
        String line;

        while ((line = reader.readLine()) != null) {
            msg += line + "\n";
        }
        reader.close();
    }
    // 5. 断开连接
    connection.disconnect();

    // 处理结果
    System.out.println(msg);
} catch (MalformedURLException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}finally
{
    if (null != pw)
    {
        pw.flush();
        pw.close();
        pw = null;
    }
    if (null != inputStream)
    {
        try
        {
            inputStream.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
    if(connection!=null){
        connection.disconnect();
    }
}
}


//使用GET方式访问HTTP
try {
     // 1. 得到访问地址的URL
     URL url = new URL("URL");
     // 2. 得到网络访问对象java.net.HttpURLConnection
     HttpURLConnection connection = (HttpURLConnection) url.openConnection();
     /* 3. 设置请求参数(过期时间,输入、输出流、访问方式),以流的形式进行连接 */
     // 设置是否向HttpURLConnection输出
     connection.setDoOutput(false);
     // 设置是否从httpUrlConnection读入
     connection.setDoInput(true);
     // 设置请求方式
     connection.setRequestMethod("GET");
     // 设置是否使用缓存
     connection.setUseCaches(true);
     // 设置此 HttpURLConnection 实例是否应该自动执行 HTTP 重定向
     connection.setInstanceFollowRedirects(true);
     // 设置超时时间
     connection.setConnectTimeout(3000);
     // 连接
     connection.connect();
     // 4. 得到响应状态码的返回值 responseCode
     int code = connection.getResponseCode();
     // 5. 如果返回值正常,数据在网络中是以流的形式得到服务端返回的数据
     String msg = "";
     if (code == 200) { // 正常响应
         // 从流中读取响应信息
         BufferedReader reader = new BufferedReader(
             new InputStreamReader(connection.getInputStream()));
         String line = null;

         while ((line = reader.readLine()) != null) { // 循环从流中读取
             msg += line + "\n";
         }
         reader.close(); // 关闭流
     }
     // 6. 断开连接,释放资源
     connection.disconnect();
     // 显示响应结果
     System.out.println(msg);
 } catch (IOException e) {
     e.printStackTrace();
 }
}
HttpClient 框架
EntityUtils

https://blog.csdn.net/ron_2016/article/details/81587492

// 获取https协议的连接
public static URLConnection getHttpsConnection(String urlStr) {

		if (StringUtils.isEmpty(urlStr))

			return null;

		URL url = null;

		SSLContext sslContext = null;

		HttpsURLConnection urlConnection = null;

		try {

			sslContext = SSLContext.getDefault();

			SSLSocketFactory sf = sslContext.getSocketFactory();

			url = new URL(urlStr);

			urlConnection = (HttpsURLConnection) url.openConnection();

            urlConnection.setConnectTimeout(TIMEOUT * 1000);// 设置连接超时时间

            urlConnection.setReadTimeout(TIMEOUT * 1000); // 读取超时,避免僵死

            urlConnection.setRequestProperty("Accept-Charset", encoding);

            urlConnection.setRequestProperty("User-Agent", HttpClientUtil.USER_AGENT_VALUE);

            urlConnection.setUseCaches(false);// 不使用缓存

            urlConnection.setDoInput(true); // 允许输入输出

            urlConnection.setDoOutput(true);

		   urlConnection.setSSLSocketFactory(sf);
	
} catch (MalformedURLException e) {
		logger.error("getHttpsConnection MalformedURLException", e);
	} catch (IOException e) {
		logger.error("getHttpsConnection IOException", e);
	} catch (NoSuchAlgorithmException e) {
		logger.error("getHttpsConnection NoSuchAlgorithmException", e);
	}
	return urlConnection;
}

套接字:ip地址+端口号。

(1)SSLContext: 此类的实例表示安全套接字协议的实现, 它是SSLSocketFactory、SSLServerSocketFactory和SSLEngine的工厂

SSLContext.getProtocol(): 返回当前SSLContext对象的协议名称

SSLContext.init(): 初始化当前SSLContext对象。 三个参数均可以为null。 详见JDK文档。

SSLEngine.getSupportedProtocols()等几个方法可以返回些 Engine上支持/已启用的协议、支持/已启用的加密套件

(2)SSLSocket: 扩展自Socket

(3)SSLServerSocket: 扩展自ServerSocket

(4)SSLSocketFactory: 抽象类,扩展自SocketFactory, SSLSocket的工厂

(5)SSLServerSocketFactory: 抽象类,扩展自ServerSocketFactory, SSLServerSocket的工厂

(6)KeyStore: 表示密钥和证书的存储设施

(7)KeyManager: 接口,JSSE密钥管理器

(8)TrustManager: 接口,信任管理器

(9)X590TrustedManager: TrustManager的子接口,管理X509证书,验证远程安全套接字

import java.io.BufferedInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.security.KeyManagementException;import java.security.NoSuchAlgorithmException;import java.util.ArrayList;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern;import javax.net.ssl.SSLContext;import javax.net.ssl.TrustManager;import javax.net.ssl.X509TrustManager;import org.apache.http.Header;import org.apache.http.HttpEntity;import org.apache.http.NameValuePair;import org.apache.http.client.entity.UrlEncodedFormEntity;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpPost;import org.apache.http.config.Registry;import org.apache.http.config.RegistryBuilder;import org.apache.http.conn.socket.ConnectionSocketFactory;import org.apache.http.conn.socket.PlainConnectionSocketFactory;import org.apache.http.conn.ssl.SSLConnectionSocketFactory;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;import org.apache.http.message.BasicNameValuePair;import org.apache.http.protocol.HTTP;public class HtmlTool {    public static String getHtmlFilterScript(String URL) {        CloseableHttpResponse response = null;        String body ="<html><head></head><body>数据无法显示,请稍后再试!</body></html>";        BufferedInputStream in = null;        ByteArrayOutputStream out = null;        StringBuffer sb = new StringBuffer();        //采用绕过验证的方式处理https请求        SSLContext sslcontext = createIgnoreVerifySSL();        // 设置协议http和https对应的处理socket链接工厂的对象        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()            .register("http", PlainConnectionSocketFactory.INSTANCE)            .register("https", new SSLConnectionSocketFactory(sslcontext))            .build();        PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);        HttpClients.custom().setConnectionManager(connManager);        //创建自定义的httpclient对象        CloseableHttpClient client = HttpClients.custom().setConnectionManager(connManager).build();        //创建post方式请求对象        HttpPost httpPost = new HttpPost(URL);        // 建立一个NameValuePair数组,用于存储传送的数据        List<NameValuePair> nvps = new ArrayList<NameValuePair>();        nvps.add(new BasicNameValuePair("键", "值")); // 添加参数        try {            // 设置参数与编码到请求对象中            httpPost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));            // 设置header信息            // 指定报文头【Content-type】、【User-Agent】            httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");            httpPost.setHeader("User-Agent",                               "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");            response = client.execute(httpPost);// 执行请求操作,并拿到结果(同步阻塞)            HttpEntity entity = response.getEntity(); // 获取结果实体            if (entity != null) {                Header header = entity.getContentType();// 读取实体头部信息Content-Type;                if (header != null) {                    // 获取头部信息meta的value;例如 text/html; charset=utf-8                    encode = header.getValue();                    int index = encode.indexOf("charset=");                    encode = index == -1 ? null : encode.substring(index + 8);// 截取编码方式                }                in = new BufferedInputStream(entity.getContent());// 从实体中读取内容写入                out = new ByteArrayOutputStream();                byte[] temp = new byte[2048];                int size = 0;                while ((size = in.read(temp)) != -1) {                    out.write(temp, 0, size);                }                byte[] content = out.toByteArray(); // 得到实体的内容                if (encode == null) {// 如果获取头部信息的编码方式失败,那就设置默认为utf-8                    String html_utf8 = new String(content, "utf-8");                    Pattern p = Pattern.compile("(?i)<meta.+?charset=[\"\']?(.*?)[\"\'][^/]*?/?>");                     // (?i)不区分大小写 [^/]除/之外的字符                    Matcher m = p.matcher(html_utf8);                    while (m.find()) {                        encode = m.group(1);// 得到匹配到的<meta>之前的所有信息                        break;                    }                }                // 设置实体的编码                String str = new String(content, encode == null ? "utf-8" : encode);                // 得到http://xxxxxxxx/或者https://xxxxxxx/形式的url                String uri = URL.substring(0, URL.indexOf("/", 8) + 1);                if (URL.equalsIgnoreCase("http://www.baidu.com/")                        || URL.matches("http://www.baidu.com/index.(php|html|htm)(\\?.*)?")                        || str.matches("(?i).*?</head>\\s*<body>\\s*</body>\\s*</html>\\s*")) {                    sb.append(body); // body内为空时显示默认提示                } else {                    // 去掉script(去掉js);把src路径全部换成之前得到的uri;去掉meta中的http-equiv与content防止服务器将把名称/值对添加到发送给浏览器的内容头部                    sb.append(str                            .replaceAll("(?i)<(\\\\?/?)script(.*?)>", "<$1noscript$2>")                            .replaceAll("(?i)src=([\"\'])/", "src=$1" + uri)                            .replaceAll(                                    "(?i)(<meta.+?http-equiv=[\"\']refresh[\"\'].*?content=[\"\'].*?url=)/?(.*?[\"\'][^/]*?/?>)",""));                }            }        } catch (IOException e) {            e.printStackTrace();        } finally {            try {                if (out != null)                    out.close();                if (in != null)                    in.close();                if (response != null)                    response.close();            } catch (IOException e) {                e.printStackTrace();            }        }        String result = sb.toString();        if (result.length() == 0)            result = body;        return result;    }    /**	 * 绕过SSL验证	 * 	 * @return	 * @throws NoSuchAlgorithmException	 * @throws KeyManagementException	 */    private static SSLContext createIgnoreVerifySSL() {        SSLContext sc = null;        try {            sc = SSLContext.getInstance("TLS");            // 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法            X509TrustManager trustManager = new X509TrustManager() {                @Override                public void checkClientTrusted(                    java.security.cert.X509Certificate[] paramArrayOfX509Certificate,                    String paramString) {}                @Override                public void checkServerTrusted(                    java.security.cert.X509Certificate[] paramArrayOfX509Certificate,                    String paramString) {}                @Override                public java.security.cert.X509Certificate[] getAcceptedIssuers() {                    return null;                }            };            sc.init(null, new TrustManager[] {trustManager}, null);        } catch (KeyManagementException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (NoSuchAlgorithmException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        return sc;    }}
HttpServletResponse

文件下载

文件下载功能的实现思路:

1.获取要下载的文件的绝对路径

2.获取要下载的文件名

3.设置content-disposition响应头控制浏览器以下载的形式打开文件

4.获取要下载的文件输入流

5.创建数据缓冲区

6.通过response对象获取OutputStream流

7.将FileInputStream流写入到buffer缓冲区

8.使用OutputStream将缓冲区的数据输出到客户端浏览器

public String downloadFile(String outFilePath,String fileName) {    HttpServletResponse resp = ServletActionContext.getResponse();    DataInputStream in = null;    OutputStream out = null;    try {        int beginIndex = attachName.lastIndexOf("_");        int endIndex = attachName.lastIndexOf(".");        String resultFileName = attachName.substring(0, beginIndex)            + attachName.substring(endIndex, attachName.length());        resultFileName = URLEncoder.encode(resultFileName, "UTF-8");        resp.setCharacterEncoding("UTF-8");        // 设定输出文件头        resp.setHeader("Content-disposition", "attachment; filename=" + fileName);        resp.setContentType("application/msexcel");        // 定义输出类型        File file = new File(outFilePath);        if(!file.exists()){            logger.debug(outFilePath+"文件不存在");            throw new Exception();        }        // 输入流:本地文件路径        in = new DataInputStream(new FileInputStream(file));        // 输出流        out = resp.getOutputStream();        // 输出文件        int bytes = 0;        byte[] bufferOut = new byte[1024];        while ((bytes = in.read(bufferOut)) != -1) {            out.write(bufferOut, 0, bytes);        }    } catch (Exception e) {        resp.reset();        try {            OutputStreamWriter writer = new                 OutputStreamWriter(resp.getOutputStream(), "UTF-8");            String data = "<script language='javascript'>                alert(\"\\u64cd\\u4f5c\\u5f02\\u5e38\\uff01\");</script>";            writer.write(data);            writer.close();        } catch (IOException e1) {            e1.printStackTrace();        }    } finally {        if (null != in) {            try {                in.close();            } catch (IOException e) {                e.printStackTrace();            }        }        if (null != out) {            try {                out.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }    return SUCCESS;}
HttpPost

.execute(request)报错

NameValuePair 键值对节点

多用于Java像url发送Post请求。在发送post请求时用该list来存放参数。

//建立HttpPost对象HttpPost httppost=new HttpPost("访问网址"); //建立一个NameValuePair数组,用于存储传送的数据List<NameValuePair> nvps=new ArrayList<NameValuePair>();//添加参数nvps.add(new BasicNameValuePair("键","值")); //设置编码httppost.setEntity(new UrlEncodedFormEntity(nvps,HTTP.UTF_8));//发送Post,并返回一个HttpResponse对象HttpResponse response=new DefaultHttpClient().execute(httppost);

Jsoup 抓取网页内容

HTTPClient+HtmlParser/Jsoup

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值