java实现网络交互 get、post方法

终于把要上的课都上完了,强度太大了,累的连博客都懒得写了,很久都没写过了。。。不过现在得开始逐步总结了!

由于近期主要在学网络交互这一块,那么这里就从最基础的java实现get、post请求说起吧:

首先我们得了解http get和post的请求方式,
1、get方式下,URL地址后的附加信息;
浏览器在URL地址后以“?”形式带上数据,多个数据之间以&分隔如:http://localhost:8080/MyApp/myServlet?name1=value1&age=value2

请求示例:
GET /myApp/1.html?name=tom&age=21 HTTP/1.1
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
Host: localhost:8080
Connection: Keep-Alive

2、post方式下,HTTP请求消息中的实体内容部分;
<form>表单method属性设置为“post”,提交表单时生成的HTTP请求方式:Content-Type: application/x-www-form-urlencoded
POST方式传递参数的形式:作为请求消息的实体内容部分进行传送

请求示例:
POST /myApp/1.html HTTP/1.1
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
Host: localhost:8080
Connection: Keep-Alive

name=tom&age=21

下来用java代码实现:


1、我们先用最底层的Socket来实现:
get方法:
Socket socket = new Socket("localhost",8080);		
	StringBuffer sb = new StringBuffer();
	sb.append("POST /Servlett?name=tom&age=21 HTTP/1.1\r\n");//请求地址和参数
	sb.append("Connection: close\r\n");//连接状态
	sb.append("Host: localhost:8080\r\n");//网络地址,端口
	sb.append("\r\n");
	socket.getOutputStream().write(sb.toString().getBytes());//发送到服务器

post方法:

StringBuffer sb = new StringBuffer();
	sb.append("POST /Servlett HTTP/1.1\r\n");
	sb.append("Connection: close\r\n");
	sb.append("Host: localhost:8080\r\n");
	sb.append("Content-Type: application/x-www-form-urlencoded\r\n");//参数内容
	sb.append("\r\n");
			
	sb.append("name=tom&age=21");
			
	socket.getOutputStream().write(sb.toString().getBytes());

要接受服务器端发过来的信息,直接用InputStream获取就行,再进行处理,ye可以用下面要说到的的 formatIsToString()方法将结果处理为String类型

其实到这里应该很清楚get方式和post方式的不同之处了,因为get方法将参数(用户数据)放在url中,在浏览器中很容易得到,极不安全;而post方法将参数置于内容之中,在请求过程中不会被发现,是安全的。所以在web项目中一般关于用户信息的提交方式都是post。


2、其实 在java中有个类:HttpURLConnection 它已经把这些东西封装好了,我们可以用它来实现
首先我们需要一个将InputStream对象转为String对象的方法(简单写一种)
public static String formatIsToString(InputStream is)throws Exception{
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			byte[] buf = new byte[1024];
			int len = -1;
			try {
				while( (len=is.read(buf)) != -1){
					baos.write(buf, 0, len);
				}
				baos.flush();
				baos.close();
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return new String(baos.toByteArray(),"utf-8");
		}

get方法实现:
public static String get(String apiUrl) throws Exception {
		String str= null;
		URL url = new URL(apiUrl);
		
		HttpURLConnection con = (HttpURLConnection) url.openConnection();
		con.setReadTimeout(5000);//将读超时设置为指定的超时,以毫秒为单位。用一个非零值指定在建立到资源的连接后从 Input 流读入时的超时时间。如果在数据可读取之前超时期满,则会引发一个 java.net.SocketTimeoutException。
		con.setDoInput(true);//指示应用程序要从 URL 连接读取数据。
		con.setRequestMethod("GET");//设置请求方式
		if(con.getResponseCode() == 200){//当请求成功时,接收数据(状态码“200”为成功连接的意思“ok”)
			InputStream is = con.getInputStream();
			str = formatIsToString(is);
		}
		return str;
	}


post方法实现:

将请求的参数内容放在一个Map中,在发送之前需要解析它(在这用的是下面的getContent()方法)

public static String post(String apiUrl,
			HashMap<String, String> params) throws Exception {
		String str = null;
		URL url = new URL(apiUrl);//根据参数创建URL对象
		HttpURLConnection con = (HttpURLConnection) url.openConnection();//得到HttpURLConnection对象
		con.setRequestMethod("POST");
		con.setReadTimeout(5000);
		con.setDoInput(true);
		con.setDoOutput(true);//指示应用程序要将数据写入 URL 连接。
		String content = getContent(params);//解析参数(请求的内容)
		con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");//设置内容
		con.setRequestProperty("Content-Length", content.length()+"");//设置内容长度
		OutputStream os = con.getOutputStream();
		os.write(content.getBytes("utf-8"));//发送参数内容
		os.flush();
		os.close();
		if(con.getResponseCode() == 200){
			str = formatIsToString(con.getInputStream());
		}
		return str;
	}

将map里的参数进行解析
private static String getContent(HashMap<String, String> params) throws UnsupportedEncodingException {
		String content = null;
		Set<Entry<String,String>> set = params.entrySet();//Map.entrySet 方法返回映射的 collection 视图,其中的元素属于此类
		StringBuilder sb = new StringBuilder();
		for(Entry<String,String> i: set){//将参数解析为"name=tom&age=21"的模式
			sb.append(i.getKey()).append("=")
			.append(URLEncoder.encode(i.getValue(), "utf-8"))
			.append("&");
		}
		if(sb.length() > 1){
			content = sb.substring(0, sb.length()-1);
		}
		return content;
	}
用Entry的好处是不用知道key的值可以通过getKey()和getValue()方法得到map中的所有值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值