WebService、Http请求、Socket请求
WebService
定义
一种web程序访问方式,常见协议:SOAP(简单对象访问协议),其实就是Http+XML。利用对象进行数据交互。
请求方法
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* @program:FoundationStudy
* @Author: zhuyang
* @Date: 2021/09/07/20:20
* @Description: WebService服务请求
*/
@Slf4j
public class WebServiceUtils {
public static String setSoapParam(String xml) throws Exception {
StringBuilder parm = new StringBuilder(200);
//包装壳需要根据不同的服务,进行不同的修改 xmlns:web="http://WebService.HisService">
parm.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:web=\"http://WebService.HisService\">\">\r\n")
.append("<soapenv:Header/>\r\n")
.append("<soapenv:Body>\r\n")
.append("<web:getService>\r\n")
.append("<web:inValue>")
.append("<![CDATA[")
.append(xml)
.append("]]>")
.append("</web:inValue>\r\n")
.append("</web:getService>\r\n")
.append(" </soapenv:Body>\r\n")
.append("</soapenv:Envelope>");
//System.out.println(parm.toString());
return parm.toString();
}
/**
* description
* param [soapHeader 参数, url 地址, host ?]
* return java.lang.String
* author zhuyang
* createTime 2021/9/7 23:13
**/
public static String sendDataToWebService(String soapHeader,String url,String host) throws Exception {
soapHeader = setSoapParam(soapHeader);
String contentType = "text/xml;charset=UTF-8";
String SOAPAction = "urn:getService";
URL u = new URL(url);
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setConnectTimeout(60000);
conn.setReadTimeout(60000);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setDefaultUseCaches(false);
/**
*
* 设置Host头部来让nginx识别,可以为IP,也可以为域名,也可以不设置,不一定要和url的ip相同
* 若nginx无法识别,添加下列代码,告诉程序,允许能使用这些限制的头部即可
* System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
*
*
**/
conn.setRequestProperty("Host", host);
conn.setRequestProperty("Content-Type", contentType);
conn.setRequestProperty("Content-Length", String.valueOf(soapHeader.length()));
conn.setRequestProperty("SOAPAction", "");
conn.setRequestMethod("POST");
//定义输出流
OutputStream output = conn.getOutputStream();
if (null != soapHeader) {
byte[] b = soapHeader.toString().getBytes("utf-8");
//发送soap请求报文
output.write(b, 0, b.length);
}
output.flush();
output.close();
//定义输入流,获取soap响应报文
InputStream input = conn.getInputStream();
//需设置编码格式,否则会乱码
String s = IOUtils.toString(input, "UTF-8");
input.close();
System.out.println("输出的xml=" + s);
Document document = DocumentHelper.parseText(s);
Element root = document.getRootElement();
return root.getStringValue();
}
参考
- https://segmentfault.com/a/1190000013806509
- http://www.biliyu.com/article/986.html
- http://blog.csdn.net/u010323023/article/details/52926051
- http://blog.csdn.net/dreamfly88/article/details/52350370
Http请求
定义
利用TCP/IP协议和json数据格式进行数据传输,现在也开始流行RestFul风格;是应用层协议,主要解决如何包装数据。
1)在HTTP 1.0中,客户端的每次请求都要求建立一次单独的连接,在处理完本次请求后,就自动释放连接。
2)在HTTP 1.1中则可以在一次连接中处理多个请求,并且多个请求可以重叠进行,不需要等待一个请求结束后再发送下一个请求。
由于HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是一种“短连接”,要保持客户端程序的在线状态,需要不断地向服务器发起连接请求。通常的做法是即时不需要获得任何数据,客户端也保持每隔一段固定的时间向服务器发送一次“保持连接”的请求,服务器在收到该请求后对客户端进行回复,表明知道客户端“在线”。若服务器长时间无法收到客户端的请求,则认为客户端“下线”,若客户端长时间无法收到服务器的回复,则认为网络已经断开。
请求方法
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public static String sendByPost(String urlString, Object params) {
Map<String, List<String>> responseMap = new HashMap<String, List<String>>();
String content = null; // 正文内容
BufferedReader bfr = null;
DataOutputStream out = null;
try {
URL url = new URL(urlString);
/** -- 创建URL连接 -- */
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//设置请求方式
conn.setRequestMethod("POST");
//设置获取连接时间
conn.setConnectTimeout(10000);
//设置阅读时间
conn.setReadTimeout(10000);
/** -- 设置通用的请求属性 -- */
//conn.setRequestProperty("appId", "18151689001");
/**
* httpUrlConnection.setDoOutput(true);以后就可以使用conn.getOutputStream().write()
* httpUrlConnection.setDoInput(true);以后就可以使用conn.getInputStream().read();
* get请求用不到conn.getOutputStream(),因为参数直接追加在地址后面,因此默认是false。
* post请求(比如:文件上传)需要往服务区传输大量的数据,这些数据是放在http的body里面的,因此需要在建立连接以后,往服务端写数据。
* 因为总是使用conn.getInputStream()获取服务端的响应,因此默认值是true。
*/
conn.setDoOutput(true);
conn.setDoInput(true);
//设置请求头
conn.setRequestProperty("Accept-Charset", "UTF-8");
//conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Type", "application/json");
conn.connect();
OutputStream writer = conn.getOutputStream();
// 写入请求的字符串
writer.write((params.toString()).getBytes("UTF-8"));
writer.flush();
/** -- 获取所有响应头字段 -- */
responseMap = conn.getHeaderFields();
/** -- 读取响应内容 -- */
bfr = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
String s = null;
StringBuffer sbf = new StringBuffer();
while ((s = bfr.readLine()) != null) {
sbf.append(s);
}
content = sbf.toString();
} catch (Exception ex) {
System.out.println("发送请求错误 -- 错误信息:" + ex.getMessage());
} finally {
try {
if (bfr != null) {
bfr.close();
}
} catch (Exception ex) {
System.out.println("关闭流错误 -- 错误信息:" + ex.getMessage());
}
}
return content;
}
Socket请求
定义
Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。
socket连接就是所谓的长连接,理论上客户端和服务器端一旦建立起连接将不会主动断掉;但是由于各种环境因素可能会是连接断开,比如说:服务器端或客户端主机down了,网络故障,或者两者之间长时间没有数据传输,网络防火墙可能会断开该连接以释放网络资源。所以当一个socket连接中没有数据的传输,那么为了维持连接需要发送心跳消息~具体心跳消息格式是开发者自己定义的。
服务器端
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import static java.util.concurrent.Executors.*;
/**
* @program:FoundationStudy
* @Author: zhuyang
* @Date: 2021/09/03/15:42
* @Description:
*/
public class SocketServer {
@Test
public void socketServer() throws IOException, InterruptedException {
ExecutorService newCacheThreadPool = newCachedThreadPool();
//创建Socket服务,监听10000端口
ServerSocket server = new ServerSocket(51503);
System.out.println("服务启动");
while (true){
//获取一个套接字(阻塞)
final Socket socket = server.accept();
System.out.println("来了一个客户端");
newCacheThreadPool.execute(new Runnable() {
@Override
public void run() {
handler(socket);
}
});
}
}
private static void handler(Socket socket) {
byte[] bytes = new byte[1024];
try {
InputStream inputStream = socket.getInputStream();
String message="";
while (true){
//读取数据(阻塞)
int read = inputStream.read(bytes);
if(read != -1){
message+=new String(bytes,0,read);
}else {
break;
}
}
System.out.println("客户端发送消息:"+message);
OutputStream out = socket.getOutputStream();
// 6. 回写数据
// Thread.sleep(1000*100);
out.write("我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你我很好,谢谢你hahahahahahhaok 完美".getBytes());
// 7.关闭资源.
out.close();
} catch (IOException e) {
e.printStackTrace();
}finally {
System.out.println("socket关闭");
try {
if (socket != null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端
import org.junit.jupiter.api.Test;
import java.io.*;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* @program:FoundationStudy
* @Author: zhuyang
* @Date: 2021/09/03/10:11
* @Description:
*/
public class SocketClient {
//默认超时时间一分钟以上 2分钟以内
public static String socket(String ip, Integer port, String message) throws IOException {
String info = "";
BufferedReader bufferedReader = null;
InputStream inputStream = null;
PrintWriter printWriter = null;
OutputStream outputStream = null;
Socket socket = null;
long t1=0;
try {
t1=System.currentTimeMillis();
socket = new Socket();
/**
* 设置建立链接超时时间
* java.net.SocketTimeoutException: connect timed out 建立链接超时
**/
socket.connect(new InetSocketAddress(ip,port),10000);
/**
* 设置读超时时间
* java.net.SocketTimeoutException: Read timed out 设置读超时时间
**/
socket.setSoTimeout(3*1000);
// Socket写超时是基于TCP协议栈的超时重传机制,一般不需要设置write的超时时间,也没有提供这种方法。
//根据输入输出流和服务端连接
outputStream = socket.getOutputStream();//获取一个输出流,向服务端发送信息
printWriter = new PrintWriter(outputStream);//将输出流包装成打印流
printWriter.write(message);
printWriter.flush();
socket.shutdownOutput();//关闭输出流
inputStream = socket.getInputStream();
//获取一个输入流,接收服务端的信息
byte[] content2 = getContent2(inputStream);
info = new String(content2);
//关闭相对应的资源
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
System.out.println("connect...."+(System.currentTimeMillis()-t1));
e.printStackTrace();
} finally {
if (bufferedReader != null) {
bufferedReader.close();
}
;
if (inputStream != null) {
inputStream.close();
}
;
if (printWriter != null) {
printWriter.close();
}
;
if (outputStream != null) {
outputStream.close();
}
;
if (socket != null) {
socket.close();
}
;
}
return info;
}
//第二种获取文件内容方式,先把所有内容获取为一个byte数组
public static byte[] getContent2(InputStream inputStream) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
byte[] temp = new byte[1024];
int size = 0;
while ((size = inputStream.read(temp)) != -1) {
out.write(temp, 0, size);
}
inputStream.close();
byte[] bytes = out.toByteArray();
return bytes;
}
@Test
public void socketTest() throws IOException {
String server = socket("127.0.0.1", 51503, "服务端你好吗");
System.out.println("服务端返回:" + server.substring(26,server.length()-16));
}
}
Gitee地址
WebService、Http请求、Socket请求的更多相关文章
- Java发送socket请求的工具
package com.tech.jin.util; import java.io.ByteArrayOutputStream; import java.io.IOException; import ...
- 协程demo,1异步爬网页 2异步socket请求
一.异步爬网页 ''' 协程并发爬网页 ''' from urllib import request import gevent,time from gevent import monkey # 让g ...
- 向继电器发送socket请求(python+java)
近日,有一需求,向连接在内网的继电器发送socket请求,加以控制.原本并不复杂,只是io流/socket转换的问题,实操中却出现python代码没问题,java代码执行无响应的问题,问题很好定位:没 ...
- Python Socket请求网站获取数据
Python Socket请求网站获取数据 ---阻塞 I/O ->收快递,快递如果不到,就干不了其他的活 ---非阻塞I/0 ->收快递,不断的去问,有没有送到,有没有送到,. ...
- WebService如何封装XML请求 以及解析接口返回的XML
原 WebService如何封装XML请求 以及解析接口返回的XML 置顶 2019年08月16日 15:00:47 童子泛舟 阅读数 28 标签: XML解析WebService第三方API 更多 ...
- HTTP协议简介详解 HTTP协议发展 原理 请求方法 响应状态码 请求头 请求首部 java模拟浏览器客户端服务端
协议简介 协议,自然语言里面就是契约,也是双方或者多方经过协商达成的一致意见; 契约也即类似于合同,自然有甲方123...,乙方123...,哪些能做,哪些不能做; 通信协议,也即是双方通过网络通信必 ...
- ajax请求,请求头是provisional are shown。请求未发送出去
问题: ajax请求,请求没成功.ajax请求没有发送出去. 查看network,看到请求头处:Provisional headers are shown. 原因: 搜索了一下,网上说了几个原因. 1 ...
- Java Apcahe的HTTPClient工具Http请求当请求超时重发
java Apcahe的HTTPClient工具Http请求当请求超时时底层会默认进行重发,默认重发次数为3次,在某些情况下为了防止重复的请求,需要将自动重发覆盖. 设置HTTP参数,设置不进行自动重 ...
- [面试没答上的问题1]http请求,请求头和响应头都有什么信息?
最近在找工作,面试官问了一些问题自己并没有回答上,这里做一个小结. http请求,请求头和响应头都有什么信息? 页面和服务器交互最常见的方式就是ajax,ajax简单来说是浏览器发送请求到服务端,然后 ...
随机推荐
- 第三十四个知识点:描述攻击离散对数问题的baby-step/Giant-step方法
第三十四个知识点:描述攻击离散对数问题的baby-step/Giant-step方法 Baby-step/Giant-step是Dnaiel Shanks为解决DLP问题开发的算法.DLP问题已经是许 ...
- 「双串最长公共子串」SP1811 LCS - Longest Common Substring
知识点: SAM,SA,单调栈,Hash 原题面 Luogu 来自 poj 的双倍经验 简述 给定两字符串 \(S_1, S_2\),求它们的最长公共子串长度. \(|S_1|,|S_2|\le 2. ...
- Centos 切换中文输入法
切换输入法看起来是一个非常简单的操作,但是对于初学者来说,也并非那么简单,开始会发现按Ctrl+space无法切换中文输入法,原因是系统没有安装中文输入法,运行以下命令可以安装中文输入法: yum i ...
- Adversarial Detection methods
目录 Kernel Density (KD) Local Intrinsic Dimensionality (LID) Gaussian Discriminant Analysis (GDA) Gau ...
- 编写Java程序,观察类启动时静态代码块和main()的执行顺序
返回本章节 返回作业目录 需求说明: 观察类启动时静态代码块和main()的执行顺序 在Book类中定义静态代码块. 在Book中分别定义一个普通实例方法和静态方法. 在Book类的静态代码块中调用静 ...
- Dapper的封装、二次封装、官方扩展包封装,以及ADO.NET原生封装
前几天偶然看到了dapper,由于以前没有用过,只用过ef core,稍微看了一下,然后写了一些简单的可复用的封装. Dapper的用法比较接近ADO.NET所以性能也是比较快.所以我们先来看看使用A ...
- 2 - 基于ELK的ElasticSearch 7.8.x技术整理 - java操作篇 - 更新完毕
3.java操作ES篇 3.1.摸索java链接ES的流程 自行创建一个maven项目 3.1.1.依赖管理 点击查看代码 <properties> <ES-version>7 ...
- python 安装包时提示“unsupport command install”
为什么提示找不到? 电脑安装了LoadRunnder,LoadRunner也有pip.exe,导致找不到python的exe 解决方法: 切换到python pip的路径进行安装,进到这个路径下,进行 ...
- VC 2010 Express 学生版(中文版)
Microsoft Visual C++ 2010 Express 学生版 下载传送门(提取码:r7sm) 如何安装 拿到压缩文件后,解压到桌面(别怕,安装完后这个文件夹是可以删除的). 在 &quo ...
- 用户注册调优 及Connection对象
调优的方法: (1)减少Connection对象的销毁与创建 我们可以在服务器启动时 预先创建好二十个Connection对象 因为每次Coonection对象的创建与销毁会浪费大量的时间 我们需要 ...