目录
4.1 连接到服务器
4.1.1 使用telnet
telnet time-a.nist.gov 13
当你开始使用time-a.nost.gov在端口13上建立telnet对话时,网络软件中有一段代码非常清楚的知道应该将字符串“time-a.nist.gov"转换为正确的IP地址129.6.15.28
4.1.2 用Java连接服务器
package Section4;
import java.net.*;
import java.util.Scanner;
import java.io.*;
public class test1 {
public static void main(String []args) throws IOException {
try(Socket s= new Socket("time-a.nist.gov",13)){
Scanner in = new Scanner(s.getInputStream(),"UTF-8");
{
while(in.hasNextLine()) {
String line=in.nextLine();
System.out.println(line);
}
}
}
}
}
UnkownHostException是IOException的一个子类。
实际上,java.net包提供的编程接口与操作文件时所用的接口基本相同
java.net.Socket:
-
-
Modifier and Type Method and Description void
bind(SocketAddress bindpoint)
将套接字绑定到本地地址。
void
close()
关闭此套接字。
void
connect(SocketAddress endpoint)
将此套接字连接到服务器。
void
connect(SocketAddress endpoint, int timeout)
将此套接字连接到具有指定超时值的服务器。
SocketChannel
getChannel()
返回与此套接字相关联的唯一的
SocketChannel
对象(如果有)。InetAddress
getInetAddress()
返回套接字所连接的地址。
InputStream
getInputStream()
返回此套接字的输入流。
boolean
getKeepAlive()
测试是否启用了
SO_KEEPALIVE
。InetAddress
getLocalAddress()
获取套接字所绑定的本地地址。
int
getLocalPort()
返回此套接字绑定到的本地端口号。
SocketAddress
getLocalSocketAddress()
返回此套接字绑定到的端点的地址。
boolean
getOOBInline()
测试是否启用了
SO_OOBINLINE
。OutputStream
getOutputStream()
返回此套接字的输出流。
int
getPort()
返回此套接字连接到的远程端口号。
int
getReceiveBufferSize()
获取这个
Socket
的SO_RCVBUF
选项的值,即平台在此Socket
上输入的缓冲区大小。SocketAddress
getRemoteSocketAddress()
返回此套接字连接,或端点的地址
null
如果是未连接。boolean
getReuseAddress()
测试是否启用了
SO_REUSEADDR
。int
getSendBufferSize()
获取此
Socket
的SO_SNDBUF
选项的值,即该平台在此Socket
上输出使用的缓冲区大小。int
getSoLinger()
SO_LINGER
的退货设置。int
getSoTimeout()
SO_TIMEOUT
的退货设置。boolean
getTcpNoDelay()
测试是否启用了
TCP_NODELAY
。int
getTrafficClass()
在从此Socket发送的数据包的IP头中获取流量类或服务类型
boolean
isBound()
返回套接字的绑定状态。
boolean
isClosed()
返回套接字的关闭状态。
boolean
isConnected()
返回套接字的连接状态。
boolean
isInputShutdown()
返回套接字连接的一半是否关闭。
boolean
isOutputShutdown()
返回套接字连接的写半是否关闭。
void
sendUrgentData(int data)
在套接字上发送一个字节的紧急数据。
void
setKeepAlive(boolean on)
启用/禁用
SO_KEEPALIVE
。void
setOOBInline(boolean on)
启用/禁用
SO_OOBINLINE
(接收TCP紧急数据)默认情况下,此选项被禁用,并且在套接字上接收的TCP紧急数据被静默地丢弃。void
setPerformancePreferences(int connectionTime, int latency, int bandwidth)
设置此套接字的性能首选项。
void
setReceiveBufferSize(int size)
设置
SO_RCVBUF
选项为这个指定的值Socket
。void
setReuseAddress(boolean on)
启用/禁用
SO_REUSEADDR
套接字选项。void
setSendBufferSize(int size)
设置
SO_SNDBUF
选项为这个指定的值Socket
。static void
setSocketImplFactory(SocketImplFactory fac)
设置应用程序的客户端套接字实现工厂。
void
setSoLinger(boolean on, int linger)
启用/禁用
SO_LINGER
,具有指定的逗留时间(以秒为单位)。void
setSoTimeout(int timeout)
启用/禁用 指定超时的
SO_TIMEOUT
(以毫秒为单位)。void
setTcpNoDelay(boolean on)
启用/禁用
TCP_NODELAY
(禁用/启用Nagle的算法)。void
setTrafficClass(int tc)
在从此Socket发送的数据包的IP头中设置流量类或服务类型字节。
void
shutdownInput()
将此套接字的输入流放置在“流的末尾”。
void
shutdownOutput()
禁用此套接字的输出流。
String
toString()
将此套接字转换为
String
。
-
4.1.3 套接字超时
对于不同的应用,应该确认合理的超时值。
package Section4;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Scanner;
public class test2 {
public static void main(String []args) throws IOException {
try{
Socket s= new Socket("time-a.nist.gov",13);//会一直阻塞到连接到服务器,
//添加超时这样做
Socket s1=new Socket();
s1.connect(new InetSocketAddress("time-a.nist.gov",13),10);
s.setSoTimeout(10000); //10s超时
//这些操作会在超时时抛出SocketTimeoutException异常
Scanner in = new Scanner(s.getInputStream(),"UTF-8");
{
while(in.hasNextLine()) {
String line=in.nextLine();
System.out.println(line);
}
}
}finally {
}
}
}
4.1.1 因特网地址
package Section4;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class test3 {
public static void main(String []args) throws UnknownHostException{
if(args.length>0) {
String host=args[0];
InetAddress[] addressed=InetAddress.getAllByName(host);
for(InetAddress a:addressed) {
System.out.println(a);
}
}else {
InetAddress addressed=InetAddress.getLocalHost();
System.out.println(addressed);
}
}
}
java.net.InetAddress:
-
-
Modifier and Type Method and Description boolean
equals(Object obj)
将此对象与指定对象进行比较。
byte[]
getAddress()
返回此
InetAddress
对象的原始IP地址。static InetAddress[]
getAllByName(String host)
给定主机的名称,根据系统上配置的名称服务返回其IP地址数组。
static InetAddress
getByAddress(byte[] addr)
给出原始IP地址的
InetAddress
对象。static InetAddress
getByAddress(String host, byte[] addr)
根据提供的主机名和IP地址创建InetAddress。
static InetAddress
getByName(String host)
确定主机名称的IP地址。
String
getCanonicalHostName()
获取此IP地址的完全限定域名。
String
getHostAddress()
返回文本显示中的IP地址字符串。
String
getHostName()
获取此IP地址的主机名。
static InetAddress
getLocalHost()
返回本地主机的地址。
static InetAddress
getLoopbackAddress()
返回回送地址。
int
hashCode()
返回此IP地址的哈希码。
boolean
isAnyLocalAddress()
检查通配符地址中的InetAddress的实用程序。
boolean
isLinkLocalAddress()
检查InetAddress是否是链接本地地址的实用程序。
boolean
isLoopbackAddress()
检查InetAddress是否是一个环回地址的实用程序。
boolean
isMCGlobal()
检查多播地址是否具有全局范围的实用程序。
boolean
isMCLinkLocal()
检查组播地址是否具有链路范围的实用程序。
boolean
isMCNodeLocal()
检查多播地址是否具有节点范围的实用程序。
boolean
isMCOrgLocal()
检查组播地址是否具有组织范围的实用程序。
boolean
isMCSiteLocal()
检查多播地址是否具有站点范围的实用程序。
boolean
isMulticastAddress()
检查InetAddress是否是IP组播地址的实用程序。
boolean
isReachable(int timeout)
测试该地址是否可达。
boolean
isReachable(NetworkInterface netif, int ttl, int timeout)
测试该地址是否可达。
boolean
isSiteLocalAddress()
检查InetAddress是否是站点本地地址的实用程序。
String
toString()
将此IP地址转换为
String
。
-
4.2 实现服务器
4.2.1 服务器套接字
package Section4;
import java.io.*;
import java.util.*;
import java.net.*;
public class test4 {
public static void main(String[] args) throws IOException{
// TODO Auto-generated method stub
//建立服务器套接字,建立一个负责监控端口8189的服务器
try(ServerSocket s = new ServerSocket(8189)){
//等待客户连接。直到有人通过网络发送了正确的连接请求,并以此连接到了端口上。该方法返回一个已经建立的Socket对象
try(Socket incoming = s.accept()){
InputStream inStream = incoming.getInputStream();
OutputStream outStream = incoming.getOutputStream();
//本章中,通过套接字发送文本,所以将流转换成扫描器和写入?
try(Scanner in = new Scanner(inStream,"UTF-8")){
PrintWriter out= new PrintWriter(new OutputStreamWriter(outStream,"UTF-8"),true);
out.println("Hello,Welcom to Roe Wang。Enter BYE to Exit");
//客户输入
boolean done=false;
while(!done&&in.hasNextLine()) {
String line = in.nextLine();
out.println("Echo: "+line);
if(line.trim().equals("BYE")) done = true;
}
}
}
}
}
}
编译运行程序。在命令行界面中执行
telnet localhost 8189
java.net.ServerSocket:
-
-
Modifier and Type Method and Description Socket
accept()
侦听要连接到此套接字并接受它。
void
bind(SocketAddress endpoint)
将
ServerSocket
绑定到特定地址(IP地址和端口号)。void
bind(SocketAddress endpoint, int backlog)
将
ServerSocket
绑定到特定地址(IP地址和端口号)。void
close()
关闭此套接字。
ServerSocketChannel
getChannel()
返回与此套接字相关联的唯一的
ServerSocketChannel
对象(如果有)。InetAddress
getInetAddress()
返回此服务器套接字的本地地址。
int
getLocalPort()
返回此套接字正在侦听的端口号。
SocketAddress
getLocalSocketAddress()
返回此套接字绑定到的端点的地址。
int
getReceiveBufferSize()
获取此
ServerSocket
的SO_RCVBUF
选项的值,即将用于从该ServerSocket
接受的套接字的建议缓冲区大小。boolean
getReuseAddress()
测试是否启用了
SO_REUSEADDR
。int
getSoTimeout()
检索
SO_TIMEOUT
的设置。protected void
implAccept(Socket s)
ServerSocket的子类使用这个方法来覆盖accept()来返回自己的套接字子类。
boolean
isBound()
返回ServerSocket的绑定状态。
boolean
isClosed()
返回ServerSocket的关闭状态。
void
setPerformancePreferences(int connectionTime, int latency, int bandwidth)
设置此ServerSocket的性能首选项。
void
setReceiveBufferSize(int size)
设置从
ServerSocket
接受的套接字的SO_RCVBUF
选项的默认建议值。void
setReuseAddress(boolean on)
启用/禁用
SO_REUSEADDR
套接字选项。static void
setSocketFactory(SocketImplFactory fac)
设置应用程序的服务器套接字实现工厂。
void
setSoTimeout(int timeout)
启用/禁用
SO_TIMEOUT
带有指定超时,以毫秒为单位。String
toString()
将该套接字的实现地址和实现端口返回为
String
。
-
4.2.2 为多个客户提供服务
package Section4;
import java.io.*;
import java.net.*;
import java.util.*;
/**
* 使用多线程
*/
public class test5 {
public static void main(String[] args) throws IOException{
// TODO Auto-generated method stub
try(ServerSocket s=new ServerSocket(8189)){
int i=1;
while(true) {
Socket incoming = s.accept();
System.out.println("Spawing:"+i);
Runnable r= new ThreadedEchoHandler(incoming);
Thread t= new Thread(r);
t.start();
i++;
}
}
}
}
class ThreadedEchoHandler implements Runnable{
private Socket incoming;
public ThreadedEchoHandler(Socket incoming) {
this.incoming=incoming;
}
@Override
public void run() {
try(InputStream inStream=incoming.getInputStream();
OutputStream outStream=incoming.getOutputStream()){
Scanner in =new Scanner(inStream,"UTF-8");
PrintWriter out=new PrintWriter(new OutputStreamWriter(outStream,"UTF-8"),true);
out.println("Hello");
//客户输入
boolean done=false;
while(!done&&in.hasNextLine()) {
String line = in.nextLine();
out.println("Echo: "+line);
if(line.trim().equals("BYE")) done = true;
}
}catch( IOException e) {
e.printStackTrace();
}
}
}
4.2.3 半关闭
半关闭提供了这样一种能力:套接字连接的一端可以终止其输出,同时仍旧可以接收来自另一端的数据。
package Section4;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class test6 {
public static void main(String[] args) throws IOException{
try(ServerSocket s = new ServerSocket(8189)){
//等待客户连接。直到有人通过网络发送了正确的连接请求,并以此连接到了端口上。该方法返回一个已经建立的Socket对象
try(Socket incoming = s.accept()){
InputStream inStream = incoming.getInputStream();
OutputStream outStream = incoming.getOutputStream();
//本章中,通过套接字发送文本,所以将流转换成扫描器和写入?
try(Scanner in = new Scanner(inStream,"UTF-8")){
PrintWriter out= new PrintWriter(new OutputStreamWriter(outStream,"UTF-8"),true);
out.println("Hello,Enter BYE to Exit");
out.println("YiLing Song is a hundan");
//关闭输出流
incoming.shutdownOutput();
//仍有输入流
while(in.hasNextLine()) {
//...
}
}
}
}
}
}
4.3 可中断套接字
package Section4;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.net.*;
import java.io.*;
import java.nio.channels.*;
import javax.swing.*;
/**
* This program shows how to interrupt a socket channel.
* @author Cay Horstmann
* @version 1.04 2016-04-27
*/
public class InterruptibleSocketTest
{
public static void main(String[] args)
{
EventQueue.invokeLater(() ->
{
JFrame frame = new InterruptibleSocketFrame();
frame.setTitle("InterruptibleSocketTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});
}
}
class InterruptibleSocketFrame extends JFrame
{
private Scanner in;
private JButton interruptibleButton;
private JButton blockingButton;
private JButton cancelButton;
private JTextArea messages;
private TestServer server;
private Thread connectThread;
public InterruptibleSocketFrame()
{
JPanel northPanel = new JPanel();
add(northPanel, BorderLayout.NORTH);
final int TEXT_ROWS = 20;
final int TEXT_COLUMNS = 60;
messages = new JTextArea(TEXT_ROWS, TEXT_COLUMNS);
add(new JScrollPane(messages));
interruptibleButton = new JButton("Interruptible");
blockingButton = new JButton("Blocking");
northPanel.add(interruptibleButton);
northPanel.add(blockingButton);
interruptibleButton.addActionListener(event ->
{
interruptibleButton.setEnabled(false);
blockingButton.setEnabled(false);
cancelButton.setEnabled(true);
connectThread = new Thread(() ->
{
try
{
connectInterruptibly();
}
catch (IOException e)
{
messages.append("\nInterruptibleSocketTest.connectInterruptibly: " + e);
}
});
connectThread.start();
});
blockingButton.addActionListener(event ->
{
interruptibleButton.setEnabled(false);
blockingButton.setEnabled(false);
cancelButton.setEnabled(true);
connectThread = new Thread(() ->
{
try
{
connectBlocking();
}
catch (IOException e)
{
messages.append("\nInterruptibleSocketTest.connectBlocking: " + e);
}
});
connectThread.start();
});
cancelButton = new JButton("Cancel");
cancelButton.setEnabled(false);
northPanel.add(cancelButton);
cancelButton.addActionListener(event ->
{
connectThread.interrupt();
cancelButton.setEnabled(false);
});
server = new TestServer();
new Thread(server).start();
pack();
}
/**
* Connects to the test server, using interruptible I/O
*/
public void connectInterruptibly() throws IOException
{
messages.append("Interruptible:\n");
try (SocketChannel channel = SocketChannel.open(new InetSocketAddress("localhost", 8189)))
{
in = new Scanner(channel, "UTF-8");
while (!Thread.currentThread().isInterrupted())
{
messages.append("Reading ");
if (in.hasNextLine())
{
String line = in.nextLine();
messages.append(line);
messages.append("\n");
}
}
}
finally
{
EventQueue.invokeLater(() ->
{
messages.append("Channel closed\n");
interruptibleButton.setEnabled(true);
blockingButton.setEnabled(true);
});
}
}
/**
* Connects to the test server, using blocking I/O
*/
public void connectBlocking() throws IOException
{
messages.append("Blocking:\n");
try (Socket sock = new Socket("localhost", 8189))
{
in = new Scanner(sock.getInputStream(), "UTF-8");
while (!Thread.currentThread().isInterrupted())
{
messages.append("Reading ");
if (in.hasNextLine())
{
String line = in.nextLine();
messages.append(line);
messages.append("\n");
}
}
}
finally
{
EventQueue.invokeLater(() ->
{
messages.append("Socket closed\n");
interruptibleButton.setEnabled(true);
blockingButton.setEnabled(true);
});
}
}
/**
* A multithreaded server that listens to port 8189 and sends numbers to the client, simulating
* a hanging server after 10 numbers.
*/
class TestServer implements Runnable
{
public void run()
{
try (ServerSocket s = new ServerSocket(8189))
{
while (true)
{
Socket incoming = s.accept();
Runnable r = new TestServerHandler(incoming);
Thread t = new Thread(r);
t.start();
}
}
catch (IOException e)
{
messages.append("\nTestServer.run: " + e);
}
}
}
/**
* This class handles the client input for one server socket connection.
*/
class TestServerHandler implements Runnable
{
private Socket incoming;
private int counter;
/**
* Constructs a handler.
* @param i the incoming socket
*/
public TestServerHandler(Socket i)
{
incoming = i;
}
public void run()
{
try
{
try
{
OutputStream outStream = incoming.getOutputStream();
PrintWriter out = new PrintWriter(
new OutputStreamWriter(outStream, "UTF-8"),
true /* autoFlush */);
while (counter < 100)
{
counter++;
if (counter <= 10) out.println(counter);
Thread.sleep(100);
}
}
finally
{
incoming.close();
messages.append("Closing server\n");
}
}
catch (Exception e)
{
messages.append("\nTestServerHandler.run: " + e);
}
}
}
}
java.net.InetSocketAddress:
-
-
Modifier and Type Method and Description static InetSocketAddress
createUnresolved(String host, int port)
从主机名和端口号创建未解析的套接字地址。
boolean
equals(Object obj)
将此对象与指定对象进行比较。
InetAddress
getAddress()
获得
InetAddress
。String
getHostName()
获得
hostname
。String
getHostString()
如果没有主机名(使用文字创建),则返回主机名或地址的String形式。
int
getPort()
获取端口号。
int
hashCode()
返回该套接字地址的哈希码。
boolean
isUnresolved()
检查地址是否已解决。
String
toString()
构造此InetSocketAddress的字符串表示形式。
-
java.nio.channels.SocketChannel:
-
-
Modifier and Type Method and Description abstract SocketChannel
bind(SocketAddress local)
将通道的套接字绑定到本地地址。
abstract boolean
connect(SocketAddress remote)
连接此通道的插座。
abstract boolean
finishConnect()
完成连接插座通道的过程。
abstract SocketAddress
getLocalAddress()
返回此通道的套接字所绑定的套接字地址。
abstract SocketAddress
getRemoteAddress()
返回此通道的插座所连接的远程地址。
abstract boolean
isConnected()
告知本频道的网络插座是否连接。
abstract boolean
isConnectionPending()
告知此频道是否正在进行连接操作。
static SocketChannel
open()
打开套接字通道。
static SocketChannel
open(SocketAddress remote)
打开套接字通道并将其连接到远程地址。
abstract int
read(ByteBuffer dst)
从该通道读取到给定缓冲区的字节序列。
long
read(ByteBuffer[] dsts)
从该通道读取到给定缓冲区的字节序列。
abstract long
read(ByteBuffer[] dsts, int offset, int length)
从该通道读取字节序列到给定缓冲区的子序列中。
abstract <T> SocketChannel
setOption(SocketOption<T> name, T value)
设置套接字选项的值。
abstract SocketChannel
shutdownInput()
关闭连接进行阅读,不关闭频道。
abstract SocketChannel
shutdownOutput()
关闭连接以进行写入,而不关闭通道。
abstract Socket
socket()
检索与此通道相关联的套接字。
int
validOps()
返回确定此频道支持的操作的操作集。
abstract int
write(ByteBuffer src)
从给定的缓冲区向该通道写入一个字节序列。
long
write(ByteBuffer[] srcs)
从给定的缓冲区向该通道写入一系列字节。
abstract long
write(ByteBuffer[] srcs, int offset, int length)
从给定缓冲区的子序列将一个字节序列写入该通道。
-
4.4 获取Web数
4.4.1 URL和URI
4.4.2 使用URLConnection获取信息
如果想从某个Web资源获取更多的信息,那么应该使用URLConnection类,通过它能够得到比基本的URL更多的控制功能
JAVA提供了6个常用的方法用来访问常用的信息头类型的值,并在需要的时候把他们转换为数字类型
package Section4;
import java.util.*;
import java.nio.*;
import java.nio.charset.StandardCharsets;
import java.net.*;
import java.io.*;
public class test8 {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
String urlName;
urlName="http://horst.com";
URL url=new URL(urlName);
//获得URLConnection对象
URLConnection connection = url.openConnection();
//set方法设置请求属性
/*
* 访问一个有密码保护的Web页,这样做。
String name="a";
String password="b";
String input =name+":"+password;
Base64.Encoder encoder = Base64.getEncoder();
String encoding =encoder.encodeToString(input.getBytes(StandardCharsets.UTF_8));
connection.setRequestProperty("Authorization", "Basic"+encoding);
*/
//连接远程资源
connection.connect();
//查询头信息,还有其它的函数
Map<String,List<String>> headers = connection.getHeaderFields();
for(Map.Entry<String, List<String>> entry:headers.entrySet()) {
String key=entry.getKey();
for(String value:entry.getValue()) {
System.out.println(key+": "+value);
}
}
//没有哪种方法可以返回字段的数量,必须反复调用下列函数知道返回null为止
String value=connection.getHeaderField(3); //n从1开始,第三个值,没有返回null
String key=connection.getHeaderFieldKey(3); //n从一开始,第三个值,没有返回null
System.out.println("()()"+value+" "+key);
//查询各标准字段
System.out.println("----------");
System.out.println("getContentType: " + connection.getContentType());
System.out.println("getContentLength: " + connection.getContentLength());
System.out.println("getContentEncoding: " + connection.getContentEncoding());
System.out.println("getDate: " + connection.getDate());
System.out.println("getExpiration: " + connection.getExpiration());
System.out.println("getLastModifed: " + connection.getLastModified());
System.out.println("----------");
//访问资源数据
String encoding = connection.getContentEncoding();
if(encoding==null) encoding="UTF-8";
try(Scanner in = new Scanner(connection.getInputStream(),encoding)){
for(int n=1;in.hasNextLine()&&n<=10;n++) {
System.out.println(in.nextLine());
}
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
java.net.URL:
-
-
Modifier and Type Method and Description boolean
equals(Object obj)
将此URL与其他对象进行比较。
String
getAuthority()
获取此的授权部分
URL
。Object
getContent()
获取此URL的内容。
Object
getContent(类[] classes)
获取此URL的内容。
int
getDefaultPort()
获取与此
URL
的协议的默认端口号。String
getFile()
获取此
URL
的文件名。String
getHost()
获取此
URL
的主机名(如适用)。String
getPath()
获取此
URL
的路径部分。int
getPort()
获取此
URL
的端口号。String
getProtocol()
获取此
URL
的协议名称。String
getQuery()
获取此
URL
的查询部分。String
getRef()
获取此的锚定(也称为“参考”)
URL
。String
getUserInfo()
获取该
URL
的userInfo部分。int
hashCode()
创建适合哈希表索引的整数。
URLConnection
openConnection()
返回一个
URLConnection
实例,表示与URL引用的远程对象的URL
。URLConnection
openConnection(Proxy proxy)
与
openConnection()
相同,但连接将通过指定的代理进行; 不支持代理的协议处理程序将忽略代理参数并进行正常连接。InputStream
openStream()
打开与此
URL
,并返回一个InputStream
,以便从该连接读取。boolean
sameFile(URL other)
比较两个URL,不包括片段组件。
static void
setURLStreamHandlerFactory(URLStreamHandlerFactory fac)
设置应用程序的
URLStreamHandlerFactory
。String
toExternalForm()
构造这个
URL
的字符串URL
。String
toString()
构造此
URL
的字符串表示URL
。URI
toURI()
-
java.net.URLConnection:
-
-
Modifier and Type Method and Description void
addRequestProperty(String key, String value)
添加由键值对指定的一般请求属性。
abstract void
connect()
打开与此URL引用的资源的通信链接,如果此类连接尚未建立。
boolean
getAllowUserInteraction()
返回此对象的
allowUserInteraction
字段的值。int
getConnectTimeout()
返回连接超时的设置。
Object
getContent()
检索此URL连接的内容。
Object
getContent(类[] classes)
检索此URL连接的内容。
String
getContentEncoding()
返回
content-encoding
标题字段的值。int
getContentLength()
返回
content-length
标题字段的值。long
getContentLengthLong()
返回
content-length
标头字段的值为long。String
getContentType()
返回
content-type
标题字段的值。long
getDate()
返回
date
标题字段的值。static boolean
getDefaultAllowUserInteraction()
返回
allowUserInteraction
字段的默认值。static String
getDefaultRequestProperty(String key)
已弃用在获得适当的URLConnection实例之后,应该使用实例特定的getRequestProperty方法。
boolean
getDefaultUseCaches()
返回默认值为
URLConnection
的useCaches
标志。boolean
getDoInput()
返回此
URLConnection
的doInput
标志的值。boolean
getDoOutput()
返回此
URLConnection
的doOutput
标志的值。long
getExpiration()
返回
expires
标题字段的值。static FileNameMap
getFileNameMap()
从数据文件加载文件名映射(模拟)。
String
getHeaderField(int n)
返回的值
n
th头字段。String
getHeaderField(String name)
返回命名头字段的值。
long
getHeaderFieldDate(String name, long Default)
返回以日期解析的命名字段的值。
int
getHeaderFieldInt(String name, int Default)
返回被解析为命名字段的值。
String
getHeaderFieldKey(int n)
返回的关键
n
th头字段。long
getHeaderFieldLong(String name, long Default)
返回被解析为命名字段的值。
Map<String,List<String>>
getHeaderFields()
返回不可修改的标题字段的映射。
long
getIfModifiedSince()
返回此对象的
ifModifiedSince
字段的值。InputStream
getInputStream()
返回从此打开的连接读取的输入流。
long
getLastModified()
返回
last-modified
标题字段的值。OutputStream
getOutputStream()
返回写入此连接的输出流。
Permission
getPermission()
返回一个权限对象,该对象表示创建此对象所表示的连接所需的权限。
int
getReadTimeout()
返回读取超时的设置。
Map<String,List<String>>
getRequestProperties()
返回此连接的一般请求属性的不可修改映射。
String
getRequestProperty(String key)
返回此连接的命名的常规请求属性的值。
URL
getURL()
返回此
URLConnection
的URL
字段的值。boolean
getUseCaches()
返回此
URLConnection
的useCaches
字段的值。static String
guessContentTypeFromName(String fname)
根据URL的指定“文件”组件,尝试确定对象的内容类型。
static String
guessContentTypeFromStream(InputStream is)
根据输入流开头的字符,尝试确定输入流的类型。
void
setAllowUserInteraction(boolean allowuserinteraction)
设置这个
URLConnection
的allowUserInteraction
字段的值。void
setConnectTimeout(int timeout)
设置打开与此URLConnection引用的资源的通信链接时使用的指定超时值(以毫秒为单位)。
static void
setContentHandlerFactory(ContentHandlerFactory fac)
设置应用
ContentHandlerFactory
的ContentHandlerFactory。static void
setDefaultAllowUserInteraction(boolean defaultallowuserinteraction)
将所有将来的
URLConnection
对象的allowUserInteraction
字段的默认值设置为指定的值。static void
setDefaultRequestProperty(String key, String value)
已弃用在获得适当的URLConnection实例之后,应该使用实例特定的setRequestProperty方法。 调用此方法将不起作用。
void
setDefaultUseCaches(boolean defaultusecaches)
将
useCaches
字段的默认值设置为指定值。void
setDoInput(boolean doinput)
设置的值
doInput
领域本URLConnection
指定值。void
setDoOutput(boolean dooutput)
设置的值
doOutput
领域本URLConnection
指定值。static void
setFileNameMap(FileNameMap map)
设置FileNameMap。
void
setIfModifiedSince(long ifmodifiedsince)
设置的值
ifModifiedSince
这个领域URLConnection
到指定值。void
setReadTimeout(int timeout)
将读取超时设置为指定的超时时间,以毫秒为单位。
void
setRequestProperty(String key, String value)
设置一般请求属性。
void
setUseCaches(boolean usecaches)
设置的值
useCaches
这个领域URLConnection
到指定值。String
toString()
返回
String
此URL连接的表示。
-
4.4.3 提交表单数据
package post;
import java.io.*;
import java.net.*;
import java.nio.file.*;
import java.util.*;
/**
* This program demonstrates how to use the URLConnection class for a POST request.
* @version 1.40 2016-04-24
* @author Cay Horstmann
*/
public class PostTest
{
public static void main(String[] args) throws IOException
{
String propsFilename = args.length > 0 ? args[0] : "post/post.properties";
Properties props = new Properties();
try (InputStream in = Files.newInputStream(Paths.get(propsFilename)))
{
props.load(in);
}
String urlString = props.remove("url").toString();
Object userAgent = props.remove("User-Agent");
Object redirects = props.remove("redirects");
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
String result = doPost(new URL(urlString), props,
userAgent == null ? null : userAgent.toString(),
redirects == null ? -1 : Integer.parseInt(redirects.toString()));
System.out.println(result);
}
/**
* Do an HTTP POST.
* @param url the URL to post to
* @param nameValuePairs the query parameters
* @param userAgent the user agent to use, or null for the default user agent
* @param redirects the number of redirects to follow manually, or -1 for automatic redirects
* @return the data returned from the server
*/
public static String doPost(URL url, Map<Object, Object> nameValuePairs, String userAgent, int redirects)
throws IOException
{
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
if (userAgent != null)
connection.setRequestProperty("User-Agent", userAgent);
if (redirects >= 0)
connection.setInstanceFollowRedirects(false);
connection.setDoOutput(true);
try (PrintWriter out = new PrintWriter(connection.getOutputStream()))
{
boolean first = true;
for (Map.Entry<Object, Object> pair : nameValuePairs.entrySet())
{
if (first) first = false;
else out.print('&');
String name = pair.getKey().toString();
String value = pair.getValue().toString();
out.print(name);
out.print('=');
out.print(URLEncoder.encode(value, "UTF-8"));
}
}
String encoding = connection.getContentEncoding();
if (encoding == null) encoding = "UTF-8";
if (redirects > 0)
{
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_MOVED_PERM
|| responseCode == HttpURLConnection.HTTP_MOVED_TEMP
|| responseCode == HttpURLConnection.HTTP_SEE_OTHER)
{
String location = connection.getHeaderField("Location");
if (location != null)
{
URL base = connection.getURL();
connection.disconnect();
return doPost(new URL(base, location), nameValuePairs, userAgent, redirects - 1);
}
}
}
else if (redirects == 0)
{
throw new IOException("Too many redirects");
}
StringBuilder response = new StringBuilder();
try (Scanner in = new Scanner(connection.getInputStream(), encoding))
{
while (in.hasNextLine())
{
response.append(in.nextLine());
response.append("\n");
}
}
catch (IOException e)
{
InputStream err = connection.getErrorStream();
if (err == null) throw e;
try (Scanner in = new Scanner(err))
{
response.append(in.nextLine());
response.append("\n");
}
}
return response.toString();
}
}
4.5 发送Mail
一旦连接到服务器,就可以发送一个邮件报头(采用SMTP格式,该格式很容易生成)。紧随其后的是邮件信息
package Section4;
import java.io.IOException;
import java.net.*;
import java.io.*;
public class test7 {
public static void main(String []args) throws UnknownHostException, IOException{
Socket s = new Socket("mail.qq.com",25);
PrintWriter out= new PrintWriter(s.getOutputStream());
String message = "HELO sending host\r\n"
+ "MAIL FROM: 1984852655@qq.com\r\n"
+ "RCPT TO: 2872718690@qq.com\r\n"
+ "DATA\r\n"
+ "Subject: Hello World\r\n"
+ "\r\n"
+"Hello May.do you get this?Please call me later.\r\n"
+ ".\r\n"
+ "QUIT\r\n";
out.print(message);
}
}
许多服务器都内置了检查功能,并且只接收来自授信用户的请求。所以,上面代码会
Exception in thread "main" java.net.ConnectException: Connection timed out: connect
使用下方代码可以顺利发送邮件:
package Section4;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;
/**
* Servlet implementation class SendEmail
*/
public class MailTest {
private static final long serialVersionUID = 1L;
public static void main(String[] args){
// TODO Auto-generated method stub
Properties props = new Properties();
// 表示SMTP发送邮件,必须进行身份验证
props.put("mail.smtp.auth", "true");
//此处填写SMTP服务器
props.put("mail.smtp.host", "smtp.qq.com");
//端口号,QQ邮箱给出了两个端口,但是另一个我一直使用不了,所以就给出这一个587
props.put("mail.smtp.port", "25");
// 此处填写你的账号
props.put("mail.user","1984852655@qq.com");
// 此处的密码就是前面说的16位STMP口令
props.put("mail.password","segpcfwwzsuugjjc");
// 构建授权信息,用于进行SMTP进行身份验证
Authenticator authenticator = new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
// 用户名、密码
String userName = props.getProperty("mail.user");
String password = props.getProperty("mail.password");
return new PasswordAuthentication(userName, password);
}
};
// 使用环境属性和授权信息,创建邮件会话
Session mailSession = Session.getInstance(props, authenticator);
// 创建邮件消息
MimeMessage message = new MimeMessage(mailSession);
// 设置发件人
InternetAddress form;
try {
form = new InternetAddress(
props.getProperty("mail.user"));
message.setFrom(form);
// 设置收件人的邮箱
InternetAddress to = new InternetAddress("2872718690@qq.com");
message.setRecipient(Message.RecipientType.TO, to);
// 设置邮件标题
message.setSubject("测试邮件");
// 设置邮件的内容体
message.setContent("这是一封测试邮件", "text/html;charset=UTF-8");
// 最后当然就是发送邮件啦
Transport.send(message);
} catch (AddressException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}