网络编程
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连接读取数据,默认为trueconn.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. 获取访问地址URLconnection = (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. 获取访问地址URLurl = 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. 得到访问地址的URLURL url = new URL("URL");// 2. 得到网络访问对象java.net.HttpURLConnectionHttpURLConnection 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. 得到响应状态码的返回值 responseCodeint 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