java 连接远程服务器 URLconnection

网络中的URL(Uniform Resource Locator)是统一资源定位符的简称。它表示Internet上某一资源的地址。通过URL我们可以访问Internet上的各种网络资源,比如最常见的WWW,FTP站点。 URL可以被认为是指向互联网资源的“指针”,通过URL可以获得互联网资源相关信息,包括获得URL的InputStream对象获取资源的信息,以及一个到URL所引用远程对象的连接URLConnection。 URLConnection对象可以向所代表的URL发送请求和读取URL的资源。通常,创建一个和URL的连接,需要如下几个步骤:

  1. 创建URL对象,并通过调用openConnection方法获得URLConnection对象;
  2. 设置URLConnection参数和普通请求属性;
  3. 向远程资源发送请求;
  4. 远程资源变为可用,程序可以访问远程资源的头字段和通过输入流来读取远程资源返回的信息。

这里需要重点讨论一下第三步:如果只是发送GET方式请求,使用connect方法建立和远程资源的连接即可;如果是需要发送POST方式的请求,则需要获取URLConnection对象所对应的输出流来发送请求。这里需要注意的是,由于GET方法的参数传递方式是将参数显式追加在地址后面,那么在构造URL对象时的参数就应当是包含了参数的完整URL地址,而在获得了URLConnection对象之后,就直接调用connect方法即可发送请求。而POST方法传递参数时仅仅需要页面URL,而参数通过需要通过输出流来传递。

package com.wa.axis2.test;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

import org.junit.Test;

public class Upload {
    @Test
	public void upload(){
		try {
			URL url=new URL("http://localhost:8090/audit/UploadFileHttpServlet?name=hello");
			HttpURLConnection urlConnection=(HttpURLConnection) url.openConnection();

			urlConnection.setDoInput(true);
			urlConnection.setDoOutput(true);
			urlConnection.setUseCaches(false);
			urlConnection.setRequestProperty("Content-Type", "application/octet-stream");
			urlConnection.setRequestProperty("ReturnFileUploadPath", "D://test//a.txt");

			File file=new File("E:\\aa.txt");
			int len=0;
			byte[] by=new byte[1024*1024];
			BufferedInputStream bi=new BufferedInputStream(new FileInputStream(file));
			while((len=bi.read(by))!=-1){
				urlConnection.getOutputStream().write(by, 0, len);
			}

			// 获得响应状态
			int responseCode = urlConnection.getResponseCode();
			if (HttpURLConnection.HTTP_OK == responseCode) {
				// 当正确响应时处理数据
				System.out.println("");
				System.out.println("Http Response OK...");
				// 处理响应流,必须与服务器响应流输出的编码一致
				StringBuffer responseBuffer = new StringBuffer();
				String readLine;

				BufferedReader responseReader = new BufferedReader(new InputStreamReader(
						urlConnection.getInputStream(),
						"utf-8"));
				while ((readLine = responseReader.readLine()) != null) {
					responseBuffer.append(readLine).append("n");
				}

				System.out.println("Http Response:" + responseBuffer);
				responseReader.close();
			}
			bi.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

服务器servlet代码如下:

protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		    String name = request.getParameter("name");
	        String path=request.getHeader("ReturnFileUploadPath");
	        System.out.println(path);
	        File file=new File(path);
	        if(!file.exists()){
	        	file.getParentFile().mkdirs();
	        }
	        //读取发送来的文件并且保存到本地
	        BufferedOutputStream bo=new BufferedOutputStream(new FileOutputStream(file));
	        int len=0;
	        byte[] by=new byte[1024*1024];
	        while((len=request.getInputStream().read(by))!=-1){
	        	bo.write(by, 0, len);
	        }
	        bo.flush();
	        bo.close();
	        response.setContentType("text/plain; charset=UTF-8");
	        response.setCharacterEncoding("UTF-8");
	        response.getWriter().write("It is ok!");
	}

注意事项;

总结:a:) HttpURLConnection的connect()函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。

无论是post还是get,http请求实际上直到HttpURLConnection的getInputStream()这个函数里面才正式发送出去。

b:) 在用POST方式发送URL请求时,URL请求参数的设定顺序是重中之重, 对connection对象的一切配置(那一堆set函数) 都必须要在connect()函数执行之前完成。而对outputStream的写操作,又必须要在inputStream的读操作之前。 这些顺序实际上是由http请求的格式决定的。

如果inputStream读操作在outputStream的写操作之前,会抛出例外:

java.net.ProtocolException: Cannot write output after reading input.......

c:) http请求实际上由两部分组成,

一个是http头,所有关于此次http请求的配置都在http头里面定义,所以在服务端需要使用getHeader来获取参数,request.getHeader("ReturnFileUploadPath");

一个是正文content。

connect()函数会根据HttpURLConnection对象的配置值生成http头部信息,因此在调用connect函数之前, 就必须把所有的配置准备好。

d:) 在http头后面紧跟着的是http请求的正文,正文的内容是通过outputStream流写入的,

实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络,

而是存在于内存缓冲区中,待outputStream流关闭时,根据输入的内容生成http正文。

至此,http请求的东西已经全部准备就绪。在getInputStream()函数调用的时候,就会把准备好的http请求 正式发送到服务器了,然后返回一个输入流,用于读取服务器对于此次http请求的返回信息。由于http 请求在getInputStream的时候已经发送出去了(包括http头和正文),因此在getInputStream()函数  之后对connection对象进行设置(对http头的信息进行修改)或者写入outputStream(对正文进行修改) 都是没有意义的了,执行这些操作会导致异常的发生。

时间: 2024-09-28 03:22:21

java 连接远程服务器 URLconnection的相关文章

java连接远程服务器

我用的是smb协议 共享方式连接远程 Windows服务器  也可以用ftp 但要保证服务器是ftp的 连接Linux服务器可以用ssh 协议 新建一个res.properites连接 IP=10.61.28.56 SMB_MINGCHENG=smb://jichuzhongxin:[email protected] //服务器登录名 密码 IP WENJIAN_NAME=/res.properties //代码 public class UploadFile{ // 读取服务器文件夹到本地 p

zendStudio连接远程服务器报错java.net.SocketException

zendStudio在连接远程服务器的时候突然报如下错误 消息: Operation failed due to network I/O error 'java.net.SocketException: Software caused connection abort: socket write error' 从昨晚,一直查询到现在.在链接日志中,突然查询到如下错误. 215 UNIX emulated by FileZilla 百度如下答案: 如果在使用UNIX by FileZilla' 时

Java中通过jsch来连接远程服务器执行linux命令

有时候你可能需要通过代码来控制执行linux命令实现某些功能. 针对这类问题可以使用JSCH来实现,具体代码如下: public class CogradientImgFileManager{ private static final Logger log = LoggerFactory.getLogger(CogradientImgFileManager.class); private static ChannelExec channelExec; private static Session

记一次java连接远程mysql数据库

用java连接远程数据库,写一个小java gui程序,写一张小表 student(number,name,sex),可以写入数据,删除数据,查询数据 主要代码: 1 public class TestSqlOnFrame { 2 public static void main(String[] args) { 3 frame frameOne=new frame(); 4 frameOne.main(); 5 } 6 } 7 8 class frame extends Frame{ 9 //新

java连接Linux服务器问题

问题: 使用java连接Linux服务器上的redis失败 代码: package com.redis.study.test; import org.junit.Test; import redis.clients.jedis.Jedis; public class RedisTest { @Test public void test() { Jedis jedis = new Jedis("192.168.80.128", 6379); System.out.println(jedi

mac 连接远程服务器、上传文件

1.连接远程服务器: ssh 命令 +用户名@服务器域名 ssh [email protected] 2.上传文件到远程服务器:scp 命令 +本地文件路径 + 用户名@服务器域名:服务器上存放的文件路径 MAC20151009AdeMac-mini:~ admin$ scp ~/documents/wx_sample.php [email protected]:/srv/www/li753-107.members.linode.com/public_html/wx/

pl/sql连接远程服务器

配置系统变量 NLS_LANG:SIMPLIFIED CHINESE_CHINA.ZHS16GBK TNS_ADMIN:D:\PLSQL Developer\instantclient_11_2\NETWORK\ADMIN tnsnames.ora 文件 [email protected] = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = IP)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATE

Mac下ssh连接远程服务器时自动断开问题

在mac下使用securecrt通过ssh连接远程服务器时,总会一段时间没有动作后,ssh被自动断开.在windows下用xmanager貌似没有遇到过这个问题. 在网上找了解决方法如下: 客户端配置: Global.ini文件中将D:"Disconnect After Resume Timeout"=00000000改为D:"Disconnect After Resume Timeout"=FFFFFFFF securecrt界面上配置:send string \

VNC配置连接远程服务器桌面-linux\windows

一.VNC配置连接远程服务器桌面 1.服务器安装VNC-server # yum -y install vnc-server 2.配置VNC连接登陆密码 # vncpasswd 回车 3.配置VNC-server # vi /etc/sysconfig/vncservers 4.取消以下两行的注释 VNCSERVERS="2:root" VNCSERVERARGS[2]="-geometry 1024x768" 保存退出 5.启动VNC-server # /etc/