Web服务器与客户端三种http交互方式
近期在对接项目时用到http方式与第三方交互数据,由于中间沟通不足导致走了不少弯路,至此特意花了点时间总结服务端与客户端数据交互的方式,本地搭建两个项目一个作为服务端,一个作为客户端。post可以有两种方式:一种与get一样,将请求参数拼接在url后面,这种服务端就以request.getParameter获取内容;另一种以流的方式写入到http链接中,服务端再从流中读取数据,在HttpURlConnection中分别用到了GET、POST请求方式,HttpClient以及commons-httpClient均以POST请求为例。
服务端代码:
package com.lutongnet.server; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* Servlet implementation class Server_ccy
*/
@WebServlet("/Server_ccy")
public class Server_ccy extends HttpServlet {
private static final long serialVersionUID = 1L; /**
* @see HttpServlet#HttpServlet()
*/
public Server_ccy() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
System.out.println("server-------doGet..start.");
String name = request.getParameter("name");
String password = request.getParameter("password");
System.out.println("server-------params:"+name+":"+password);
System.out.println("server-------doGet..end.");
PrintWriter out = response.getWriter();
out.print("{\"姓名\":\"陈昌圆\"}");
out.flush();
out.close();
//response.getWriter().append("server_get_info:").append("Served at: ").append(request.getContextPath());
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//doGet(request, response);
response.setContentType("application/json;charset=utf-8");
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
System.out.println("server-------doPost..start.");
System.out.println("ContentType---->"+response.getContentType());
System.out.println("queryString---->"+request.getQueryString());
String name = request.getParameter("name");
System.out.println("name---->"+name);
//String password = request.getParameter("password");
//System.out.println("server-------params:"+name+":"+password);
StringBuffer sb = new StringBuffer("");
String str;
BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
if((str = br.readLine()) != null){
sb.append(str);
}
System.out.println("从客户端获取的参数:"+sb); System.out.println("server-------doPost..end.");
PrintWriter out = response.getWriter();
out.print("{\"姓名\":\"陈昌圆\"}");
out.flush();
out.close();
} }
客户端代码:
1.HttpURLConnection:主要详细分析GET与POST两种请求方式,我们项目中的api就是用的这种
package com.lutongnet.HttpURLConnection; import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date; public class HttpURLConnectionTest { public static void main(String[] args) {
String url = "http://localhost:7373/ccy_server/ccy";
//String params = "name=ccy&password=123";
String params = "{\"name\":\"陈昌圆\",\"password\":\"123\"}";
try {
String result = httpGetOrPost("POST", url, params);
System.out.println("client---result:"+result);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
public static String httpGetOrPost(String type, String url, String params) throws Exception{
//get请求通过url传参(post可以通过url传参也可以将参数写在http正文传参)
if("GET".equals(type)){
if(url.contains("?")){
url += "&" + params;
}else{
url += "?" + params;
}
}
System.out.println("请求地址:" + url);
System.out.println("请求参数:" + params);
URL u = new URL(url);
/*
* 查看URL API 发现 openConnection方法返回为URLConnection
* HttpURLConnection为URLConnection的子类,有其更多的实现方法,
* 通常将其转型为HttpURLConnection
* */
HttpURLConnection httpConn = (HttpURLConnection) u.openConnection();
//设置请求方式 默认是GET
httpConn.setRequestMethod(type);
//写 默认均为false,GET不需要向HttpURLConnection进行写操作
if("POST".equals(type)){
httpConn.setDoOutput(true);
}
httpConn.setDoInput(true);//读 默认均为true,HttpURLConnection主要是用来获取服务器端数据 肯定要能读
httpConn.setAllowUserInteraction(true);//设置是否允许用户交互 默认为false
httpConn.setUseCaches(false);//设置是否缓存
httpConn.setConnectTimeout(5000);//设置连接超时时间 单位毫秒 ms
httpConn.setReadTimeout(5000);//设置访问超时时间
//setRequestProperty主要设置http请求头里面的相关属性
httpConn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31");
httpConn.setRequestProperty("accept", "*/*");
httpConn.setRequestProperty("Content-Type", "application/json");
//开启连接
httpConn.connect();
//post方式在建立连接后把头文件内容从连接的输出流中写入
if("POST".equals(type)){
//在调用getInputStream()方法中会检查连接是否已经建立,如果没有建立,则会调用connect()
OutputStreamWriter out = new OutputStreamWriter(httpConn.getOutputStream(), "utf-8");
out.write(params);//将数据写入缓冲流
out.flush();//将缓冲区数据发送到接收方
out.close();
}
System.out.println("httpcode:"+httpConn.getResponseCode());
//读取响应,现在开始可以读取服务器反馈的数据
BufferedReader br = new BufferedReader(new InputStreamReader(httpConn.getInputStream(), "utf-8"));
StringBuffer sb = new StringBuffer("");
String str;
while((str = br.readLine()) != null){
sb.append(str);
}
System.out.println(new Date()+"---响应:"+sb);
br.close();
httpConn.disconnect();
return sb.toString();
} }
get请求运行结果
客户端:
服务端:
post请求运行结果
客户端:
服务端:
2.DefaultHttpClient:需要导入三个包,httpclient-4.1.jar,httpcode-4.1.jar,commons-logging-1.1.1.jar,doPost方法是直接可以请求https,doPost2为的http方式,日后若有需要对接第三方接口需要https协议可以参考doPost方法
package com.lutongnet.HttpClient; import java.security.cert.CertificateException;
public class HttpClientDemo { public static void main(String[] args) {
HttpClientDemo hct = new HttpClientDemo();
String url = "http://localhost:7373/ccy_server/ccy";
Map<String, String> map = new HashMap<String, String>();
map.put("name", "ccy");
map.put("password", "123");
String charset = "utf-8";
String result = hct.doPost(url, map, charset);
System.out.println("1.获取服务器端数据为:"+result);
String params = "{\"name\":\"陈昌圆\",\"password\":\"123\"}";
String result2 = hct.doPost2(url, params);
System.out.println("2.获取服务器端数据为:"+result2);
}
public String doPost2(String url, String content) {
System.out.println("请求地址:" + url);
System.out.println("请求参数:" + content);
String charsetName = "utf-8";
DefaultHttpClient httpclient = null;
HttpPost post = null;
try {
httpclient = new DefaultHttpClient();
post = new HttpPost(url);
post.setHeader("Content-Type", "application/json;charset=" + charsetName);
post.setEntity(new StringEntity(content, charsetName));
HttpResponse response = httpclient.execute(post);
HttpEntity entity = response.getEntity();
String rsp = EntityUtils.toString(entity, charsetName);
System.out.println("返回参数: "+rsp);
return rsp;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
httpclient.getConnectionManager().shutdown();
} catch (Exception ignore) {}
} }
public String doPost(String url,Map<String,String> map,String charset){
HttpClient httpClient = null;
HttpPost httpPost = null;
String result = null;
try{
httpClient = new SSLClient();
httpPost = new HttpPost(url);
//设置参数
List<NameValuePair> list = new ArrayList<NameValuePair>();
Iterator iterator = map.entrySet().iterator();
while(iterator.hasNext()){
Entry<String,String> elem = (Entry<String, String>) iterator.next();
list.add(new BasicNameValuePair(elem.getKey(),elem.getValue()));
}
if(list.size() > 0){
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list,charset);
httpPost.setEntity(entity);
}
HttpResponse response = httpClient.execute(httpPost);
if(response != null){
HttpEntity resEntity = response.getEntity();
if(resEntity != null){
result = EntityUtils.toString(resEntity,charset);
}
}
}catch(Exception ex){
ex.printStackTrace();
}
return result;
}
class SSLClient extends DefaultHttpClient{
public SSLClient() throws Exception{
super();
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
ctx.init(null, new TrustManager[]{tm}, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = this.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("https", 443, (SchemeSocketFactory) ssf));
}
}
}
post请求运行结果
客户端:
服务端:
3.commons-httpclient:需要导入两个包,commons-httpclient-3.0.jar,commons-codec-1.7.jar,这种方式是最简洁的,前后不到10行代码就解决了,不过需要注意的是设置正文编码,5种方式都可行,这种将参数拼接在http正文中,在服务端可以利用request.getParameter()方法获取参数,也可以用request.getInputStream()流的方式获取参数(这种方式如果参数中有中文的话,暂时没有找到解决乱码的方法)
package com.lutongnet.commonHttpclient; import java.util.ArrayList;
import java.util.List; import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams; public class CommonHttpClient {
public static void main(String[] args) {
String url = "http://localhost:7373/ccy_server/ccy";
List<String> params = new ArrayList<String>();
params.add("陳昌圓");
params.add("123");
CommonHttpClient chc = new CommonHttpClient();
String result = chc.getPostMethod(url, params);
System.out.println("commonHttpClient---->从服务端获取的数据:" + result);
}
private String getPostMethod(String url, List<String> params) {
String result = null;
HttpClient httpClient = new HttpClient();
PostMethod postMethod = new PostMethod(url);
//httpClient.getParams().setContentCharset("utf-8");
//httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "utf-8");
//postMethod.addRequestHeader("Content-type","application/x-www-form-urlencoded; charset=UTF-8");
//postMethod.addRequestHeader("Content-Type", PostMethod.FORM_URL_ENCODED_CONTENT_TYPE
// + "; charset=utf-8");
postMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET,
"utf-8");
postMethod.addParameter("name", params.get(0));
postMethod.addParameter("password", params.get(1));
try {
httpClient.executeMethod(postMethod);
result = postMethod.getResponseBodyAsString();
System.out.println("result:" + result);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/*class ccyPostMethod extends PostMethod {
public ccyPostMethod(String url) {
super(url);
} @Override
public String getRequestCharSet() {
return "utf-8";
}
}*/ }
post请求运行结果
客户端:
服务端:
Web服务器与客户端三种http交互方式的更多相关文章
- python web编程-CGI帮助web服务器处理客户端编程
这几篇博客均来自python核心编程 如果你有任何疑问,欢迎联系我或者仔细查看这本书的地20章 另外推荐下这本书,希望对学习python的同学有所帮助 概念预热 eb客户端通过url请求web服务器里 ...
- Tomcat、Apache、IIS这三种Web服务器来讲述3种搭建JSP运行环境的方法
一.相关软件介绍 1. J2SDK:Java2的软件开发工具,是Java应用程序的基础.JSP是基于Java技术的,所以配置JSP环境之前必须要安装J2SDK. 2. Apache服务器:Apache ...
- Java Web开发Tomcat中三种部署项目的方法
第一种方法:在tomcat中的conf目录中,在server.xml中的,<host/>节点中添加: <Context path="/hello" docBase ...
- WebService学习整理(一)——客户端三种调用方式整理
1 WebService基础 1.1 作用 1, WebService是两个系统的远程调用,使两个系统进行数据交互,如应用: 天气预报服务.银行ATM取款.使用邮箱账号登录各网站等. 2, ...
- nginx反向代理后端web服务器记录客户端ip地址
nginx在做反向代理的时候,后端的nginx web服务器log中记录的地址都是反向代理服务器的地址,无法查看客户端访问的真实ip. 在反向代理服务器的nginx.conf配置文件中进行配置. lo ...
- [Web 前端] 006 css 三种页面引入的方法
1. 外链式 用法 step 1: 在 html 文档的 head 头部分写入下方这句话 <link rel="stylesheet" href="./xxx.cs ...
- 如何搭建一个WEB服务器项目(三)—— 实现安卓端联网登录
安卓端调用服务器登录函数进行验证登录 观前提示:本系列文章有关服务器以及后端程序这些概念,我写的全是自己的理解,并不一定正确,希望不要误人子弟.欢迎各位大佬来评论区提出问题或者是指出错误,分享宝贵经验 ...
- python一个简单的web服务器和客户端
服务器: 当客户联系时创建一个连接套接字 从这个连接接收HTTP请求(*) 解释该请求所请求的特定文件 从服务器的文件系统获取该文件 并发送文件内容 ...
- redis数据库服务器开启的三种方式
redis的启动方式1.直接启动 进入redis根目录,执行命令: #加上‘&’号使redis以后台程序方式运行 1 ./redis-server & 2.通过指定配置文件启动 ...
随机推荐
- VS2008 安装WINCE插件报错 ToolsMsmCA(Error)解决方案___VS2008
在win7系统,VS2008环境下安装EFMS9280_SDK.msi文件出现报错 ToolsMsmCA(Error):IHxFilters filter registration failure: ...
- WPF实战案例-MVVM模式下在Xaml中弹出窗体
相信很多学习和开发wpf项目的同学都了解过mvvm模式,同样,在mvvm模式下会有一个不可忽视的问题,就是怎么在xaml中弹出窗体,而不破坏MVVM本身的结构. 关于弹出窗体的方式还是很多的,本文先讲 ...
- dbcp和druid(数据库连接池)
前言: 对于一个简单的数据库应用,由于对于数据库的访问不是很频繁.这时可以简单地在需要访问数据库时,就新创建一个连接,用完后就关闭它,这样做也不会带来什么明显的性能上的开销.但是对于一个复杂的数据库应 ...
- MySql字段类型说明
bigint 从 -^ (-) 到 ^- () 的整型数据(所有数字).存储大小为 个字节. P.S. bigint已经有长度了,在mysql建表中的length,只是用于显示的位数 int 从 -^ ...
- MariaDB 使用正则匹配查询(7)
MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可MariaDB的目的是完全兼容MySQL,包括API和命令行,MySQL由于现在闭源了,而能轻松成为MySQ ...
- 防止sql注入的小函数 以及一些小验证
function test_input($data) { $data = trim($data); $data = stripslashes($data); $data = htmlspecialch ...
- 网易免费企业邮箱Foxmail设置方法
网易免费企业邮箱Foxmail7.0设置方法 第一步:启动 Foxmail 邮件客户端,点击工具->账号管理,弹出如下页面. 点击新建,如下: 填写自己企业邮箱账号,然后下一步,邮箱类型选择PO ...
- InfluxDB概念和基本操作
InfluxDB基本概念 数据格式 在 InfluxDB 中,我们可以粗略的将要存入的一条数据看作一个虚拟的 key 和其对应的 value(field value).格式如下: cpu_usage, ...
- springbootf访问静态文件资源
springboot目录结构: 网友说在springboot的配置文件中加 现在访问static目录下的jquery文件 用jquery在页面做一个弹窗 启动服务看页面效果 页面没有出现弹窗 ,连jq ...
- odoo开发笔记-tree列表视图拖拽排序
odoo列表tree视图 拖拽排序 实现效果: 实现方式: 模型中定义字段: class CusYourModel(models.Model): """ 你的模型 &qu ...