网络编程
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