1.HTTP协议简介
HTTP(HyperText Transfer Protocal)协议是万维网(W3C)制定的一种应用层协议,主要用来定义浏览器与服务器之间的通信方式和通信的数据格式。
1.1通信方式
1.2通信的数据格式
1.2.1请求的数据格式
1.2.2响应的数据格式
需要注意的是在实际开发中
我们只需要学会使用request和response处理实体内容即可。
2.访问网络资源
2.1 什么叫访问网络资源
通过建立网络连接获取相应的数据信息就叫做访问网络资源。在实际开发中,一个项目中的某些数据需要访问其他项目才能得到时,我们就必须在当前项目中编写代码与其他项目建立连接从而获得我们需要的资源或者数据。
2.2 java如何实现
2.2.1 通过java自带的实现类URLConnection
//发送get请求,当参数中有中文且报400错误时,记得对中文参数先要进行URLEncode("param","utf=8")操作
public static String sendGet(String url, String param) {
String result = "";
BufferedReader in = null;
//get方式参数必须拼在路径后面,区别于下面的post传参方式
try {
//处理url与param
if(!param.equals("")){
if(url.indexOf("?") == -1){
url += "?" + param;
}else{
if(url.endsWith("&")){
url += param;
}else{
url += "&" + param;
}
}
}
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性,必须写在connect()方法之前
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接,post方式可不写
connection.connect();
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
//get方式参数必须拼在路径后面,区别于下面的post传参方式
try {
//处理url与param
if(!param.equals("")){
if(url.indexOf("?") == -1){
url += "?" + param;
}else{
if(url.endsWith("&")){
url += param;
}else{
url += "&" + param;
}
}
}
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性,必须写在connect()方法之前
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接,post方式可不写
connection.connect();
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
//发送post请求
public static String sendPost(String url, String param) {
OutputStreamWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
conn.setRequestProperty("Accept-Charset", "utf-8");
conn.setRequestProperty("contentType", "utf-8");
// 发送POST请求必须设置如下一行
conn.setDoOutput(true);
//默认为true,可不写
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new OutputStreamWriter(conn.getOutputStream(), "utf-8");
// 发送请求参数
out.write(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
conn.getInputStream(), "utf-8"));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 使用finally块来关闭输出流、输入流
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return result;
// 发送POST请求必须设置如下一行
conn.setDoOutput(true);
//默认为true,可不写
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new OutputStreamWriter(conn.getOutputStream(), "utf-8");
// 发送请求参数
out.write(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
conn.getInputStream(), "utf-8"));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 使用finally块来关闭输出流、输入流
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return result;
2.2.2 通过HttpClient
<!-- maven依赖 -->
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
//post请求
public class HouseTest {
private static Logger logger = LoggerFactory.getLogger(HouseTest.class);
// 服务器地址
private String host = "http://localhost:8084/erpshopapp";
// 虚拟客户端对象
private HttpClient httpClient = new HttpClient();
// 参数集合
private List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
// 请求方式
private PostMethod post;
private GetMethod get;
@Before
public void init() {
// 模拟登入
String url = host + "/user/login";
post = new PostMethod(url);
// 传参
nameValuePairs.add(new NameValuePair("loginname", "5"));
nameValuePairs.add(new NameValuePair("password", "123456"));
nameValuePairs.add(new NameValuePair("ipgp", "AC"));
try {
if (nameValuePairs.size() > 0) {
NameValuePair[] arrs = new NameValuePair[nameValuePairs.size()];
// 将集合中的元素存入数组
for (int i = 0; i < nameValuePairs.size(); i++) {
arrs[i] = nameValuePairs.get(i);
}
// 将参数拼接到请求路径中,参数必须存进一个数组NameValuePair[]中
post.setRequestBody(arrs);
}
// 执行请求
httpClient.executeMethod(post);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
// 该方法用来测试获得租赁房源列表
@Test
public void test1() {
String url = host + "/house/rentHouse/getRentHouseList";
// 发送post请求
post = new PostMethod(url);
// 传参
nameValuePairs.add(new NameValuePair("src_type", "-1"));
try {
if (nameValuePairs.size() > 0) {
NameValuePair[] arrs = new NameValuePair[nameValuePairs.size()];
// 将集合中的元素存入数组
for (int i = 0; i < nameValuePairs.size(); i++) {
arrs[i] = nameValuePairs.get(i);
}
// 将参数拼接到请求路径中,参数必须存进一个数组NameValuePair[]中
post.setRequestBody(arrs);
}
// 执行请求
httpClient.executeMethod(post);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@After
public void destroy() {
int status = post.getStatusCode();
if (status == 200) {
// 如果请求发送成功,将返回值结果打印
try {
String result = post.getResponseBodyAsString();
logger.debug("服务器返回数据:" + result);
} catch (IOException e) {
e.printStackTrace();
} finally {
post.releaseConnection();// 关闭连接
}
}
}
}
// 传参
nameValuePairs.add(new NameValuePair("src_type", "-1"));
try {
if (nameValuePairs.size() > 0) {
NameValuePair[] arrs = new NameValuePair[nameValuePairs.size()];
// 将集合中的元素存入数组
for (int i = 0; i < nameValuePairs.size(); i++) {
arrs[i] = nameValuePairs.get(i);
}
// 将参数拼接到请求路径中,参数必须存进一个数组NameValuePair[]中
post.setRequestBody(arrs);
}
// 执行请求
httpClient.executeMethod(post);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@After
public void destroy() {
int status = post.getStatusCode();
if (status == 200) {
// 如果请求发送成功,将返回值结果打印
try {
String result = post.getResponseBodyAsString();
logger.debug("服务器返回数据:" + result);
} catch (IOException e) {
e.printStackTrace();
} finally {
post.releaseConnection();// 关闭连接
}
}
}
}
//发送get请求
public void testGetMethod() {
String url = host + "/house/rentHouse/getRentHouseList";
// 发送get请求,参数拼接在后面
get = new GetMethod(url + "?src_type=-1");
try {
// 执行请求
httpClient.executeMethod(get);
System.out.println("打印结果:"+get.getResponseBodyAsString());
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
get.releaseConnection();//关闭连接
}
}
// 发送get请求,参数拼接在后面
get = new GetMethod(url + "?src_type=-1");
try {
// 执行请求
httpClient.executeMethod(get);
System.out.println("打印结果:"+get.getResponseBodyAsString());
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
get.releaseConnection();//关闭连接
}
}
2.2.3 HttpPost和HttpGet
<!-- maven依赖 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
测试代码以及这种方式与上面这种方式的区别日后有空再加以补充(由于控制层使用了@ResponseBody注解,使用HttpPost发现无法得到返回值,具体原因还没搞清楚)
3.URLConnection和HttpClient的区别
HttpURLConnection是java的标准类,什么都没封装。HTTPClient是个开源框架,封装了访问http的请求头,参数,内容体,响应等等。简单来说,HTTPClient就是一个增强版的HttpURLConnection,HttpURLConnection可以做的事情HTTPClient全部可以做;HttpURLConnection没有提供的有些功能,HTTPClient也提供了,但它只是关注于如何发送请求、接收响应,以及管理HTTP连接。
4.解决中文乱码的问题
post.addRequestHeader("Content-type","application/x-www-form-urlencoded; charset=UTF-8");
参考:https://blog.csdn.net/zhaky/article/details/51064932
在性能方面,URLConnection比HttpClient更快一些,测试代码省略。