http发送服务请求实例_a514548454的博客-程序员秘密

技术标签: java io  java  io  socket  

------------------客户端发送请求-----------------------

HttpPost req = new HttpPost("/dm");

req.addHeader("Content-Type",  "application/json; charset=UTF-8");
String jsonReq = MsgWrap.wrapRequestMsg("getTest", "0",new JSONObject());//jsonReq为json格式
req.setEntity(new StringEntity(jsonReq, ContentType.APPLICATION_JSON));
HttpHost host = new HttpHost(IP, 20215); //IP为自己的IP,端口为所要发送服务地址的端口

String response = RequestHandler.getInstance().sendRequest(host, req);


/**
* 封装请求消息
* @param req 请求消息
* @param reqSequence 请求消息序列
* @param body 请求消息体
* @return
*/
@SuppressWarnings("unchecked")
public static String wrapRequestMsg(String req, String reqSequence, JSONObject body) {
JSONObject msg = new JSONObject();
JSONObject jHeader = new JSONObject();
jHeader.put("req", req);
jHeader.put("seq", reqSequence);
msg.put("type", "request");
msg.put("header", jHeader);
msg.put("body", body);
return msg.toJSONString();
}


package util;




import java.io.IOException;
import java.net.Socket;


import org.apache.http.HttpException;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.impl.DefaultHttpClientConnection;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.params.SyncBasicHttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpProcessor;
import org.apache.http.protocol.HttpRequestExecutor;
import org.apache.http.protocol.ImmutableHttpProcessor;
import org.apache.http.protocol.RequestConnControl;
import org.apache.http.protocol.RequestContent;
import org.apache.http.protocol.RequestExpectContinue;
import org.apache.http.protocol.RequestTargetHost;
import org.apache.http.protocol.RequestUserAgent;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;


/**
 * 对外发送请求的控制器封装类, 所有对外发送请求都可以调用此类的sendRequest方法
 */
public class RequestHandler {


private Logger logger = Logger.getLogger(RequestHandler.class);
private HttpParams params = null;
private DefaultHttpClientConnection conn = null;
private HttpRequestExecutor httpexecutor = null;
private HttpContext context = new BasicHttpContext(null);
private HttpProcessor httpproc = null;
private Socket socket = null;

private static RequestHandler handler = new RequestHandler();;

public static RequestHandler getInstance() {
return handler;
}

/**
* 初始化服务通道
* @return
*/
private RequestHandler() {

params = new SyncBasicHttpParams();
conn = new DefaultHttpClientConnection();
httpexecutor = new HttpRequestExecutor();
context = new BasicHttpContext(null);
httpproc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
    new RequestContent(),
    new RequestTargetHost(),
    new RequestConnControl(),
    new RequestUserAgent(),
    new RequestExpectContinue()});

        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, "UTF-8");
        HttpProtocolParams.setUserAgent(params, "HttpComponents/1.1");
        HttpProtocolParams.setUseExpectContinue(params, true);
}

/**
* 发送服务请求
* @param request 发送请求(HttpRequest)
* @param host  
* @return
*/
public synchronized String sendRequest(HttpHost host, HttpRequest request) {
String response = null;
HttpResponse resp = null;
try {
conn = new DefaultHttpClientConnection();
context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, host);
context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
socket = new Socket(host.getHostName(), host.getPort());
conn.bind(socket, params);
conn.setSocketTimeout(30*1000);

request.setParams(params);
httpexecutor.preProcess(request, httpproc, context);
resp = httpexecutor.execute(request, conn, context);
if (null == resp) {
return null;
}
resp.setParams(params);
httpexecutor.postProcess(resp, httpproc, context);
response = EntityUtils.toString(resp.getEntity());//获取到服务端响应的请求
} catch (IOException e) {
logger.debug("send request IOException:" + e.toString());
} catch (HttpException e) {
logger.debug("send request HttpException:" + e.toString());
} catch (Exception e) {
logger.debug("send request Exception:" + e.toString());
} finally {
close();
}
return response;
}

/**
* 关闭通道
*/
private void close() {
try {
if (conn != null) {
conn.close();
conn = null;
}
if (socket != null) {
socket.close();
socket = null;
}
} catch (IOException e) {
logger.debug("http client connect close exception:" + e.getMessage());

}
}


--------------------服务端--------------------

public static void main(String[] args) {

BasicHandler businessHandler = new InitChannelHandler();
businessHandler.registerHandler(new AddDevicesHandler())
.registerHandler(new GetAllDeviceHandler());

int port = XmlUtil.getDMPort();
server.start(port);
}

/**
* 注册下一个控制器,当自身处理不该请求时,就会调用下一个控制器进行处理
* @param nextHandler
* @return
*/

private BasicHandler nextHandler =null;
public BasicHandler registerHandler(BasicHandler nextHandler) {
this.nextHandler = nextHandler;
return nextHandler;
}

/**
* 启动服务
* @param port 服务监听的端口
*/
public void start(int port) {
listener.setPort(port);//端口号8080
listener.start(); //启动线程,下面run()方法
}

//继承的是thread类

public void run() {
// Create server-side HTTP protocol handler
HttpAsyncService protocolHandler = new HttpAsyncService(
httpProc, new DefaultConnectionReuseStrategy(), reqistry, params) {

@Override
public void connected(final NHttpServerConnection conn) {
super.connected(conn);
logger.debug(conn + ": connection open");
}

@Override
public void closed(final NHttpServerConnection conn) {
logger.debug(conn + ": connection closed");
super.closed(conn);
}

};

// Create HTTP connection factory
connFactory = new DefaultNHttpServerConnectionFactory(params);
// Create server-side I/O event dispatch
IOEventDispatch ioEventDispatch = new DefaultHttpServerIODispatch(protocolHandler, connFactory);
// Create server-side I/O reactor
try {
ioReactor = new DefaultListeningIOReactor();
// Listen of the given port
ioReactor.listen(new InetSocketAddress(port));
ioReactor.execute(ioEventDispatch);
} catch (InterruptedIOException ex) {
logger.error("Interrupted");
} catch (IOException e) {
logger.error("I/O error: " + e.getMessage());
} finally {
try {
if (ioReactor != null) {
ioReactor.shutdown();
}
} catch (IOException e) {
logger.error(e);
}
}
logger.error("Shutdown");
}

//baseHander类

/**
 * 

基本控制器, 所有服务请求都首先经过这里,然后进行分发处理
 *
 */
public abstract class BasicHandler implements HttpAsyncRequestHandler<HttpRequest>{


protected final int REQ_OK = 0;      //正确的请求标识
protected final int REQ_ERROR = 1;   //错误的请求标识
protected BasicHandler nextHandler = null;

@Override
public HttpAsyncRequestConsumer<HttpRequest> processRequest(HttpRequest req,
HttpContext context) throws HttpException, IOException {
return new BasicAsyncRequestConsumer();
}


@Override
public void handle(HttpRequest req, HttpAsyncExchange ex, HttpContext context) 
   throws HttpException, IOException {
HttpResponse response = ex.getResponse();
JSONObject header = null;
JSONObject body = null;
int bad_req = REQ_OK;
String result = "";
String responseMsg = "";
System.out.println("req==" + req.toString());   //调试用,后面会有专门的日志处理
if (req instanceof HttpEntityEnclosingRequest) {
..............处理代码
} else {
handlerRequest(request, header, body, ex, context);//抽象类
}

}

/**
* 不同的请求不同的处理, 需要子类来实现
* @param request  请求消息
* @param msgHeader 请求消息头
* @param msgBody  请求消息体
* @param ex
* @param context
*/
public abstract void handlerRequest(String request, JSONObject msgHeader,
JSONObject msgBody, HttpAsyncExchange ex, HttpContext context);

/**
* 对请求消息处理后响应封装
* @param ex
* @param result 请求消息处理结果
* @param contenType 消息类型
* @param bBadRequest 消息响应状态
*/
protected void submitResponse(HttpAsyncExchange ex, String result, ContentType contenType, int bBadRequest) {
HttpResponse res = ex.getResponse();
if (bBadRequest == REQ_ERROR) {
res.setStatusCode(HttpStatus.SC_BAD_REQUEST);
} else {
res.setStatusCode(HttpStatus.SC_OK);
}
// ByteArrayEntity rets = new ByteArrayEntity(result.getBytes(Charset.forName("utf-8")));
contenType = ContentType.create(contenType.getMimeType(), Charset.forName("utf-8"));
StringEntity ret = new StringEntity(result, contenType);
res.setEntity(ret);
res.setHeader("Context-Type", "UTF-8");
ex.submitResponse(new BasicAsyncResponseProducer(res));//提交response,对客户端的请求惊醒响应
}


//处理具体业务的类


import org.apache.http.entity.ContentType;
import org.apache.http.nio.protocol.HttpAsyncExchange;
import org.apache.http.protocol.HttpContext;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;



/**
 * 获取所有
 *
 */
public class GetAllDeviceHandler extends BasicHandler{


@SuppressWarnings("unchecked")
@Override
public void handlerRequest(String request, JSONObject msgHeader,
JSONObject msgBody, HttpAsyncExchange ex, HttpContext context) {
int bad_req = REQ_OK;
if ( “客户端所需要调用的类(getTest)”.equalsIgnoreCase(request) ) {
....处理业务
submitResponse(ex, result, ContentType.APPLICATION_JSON, bad_req);//上面的一个方法,对客户端的请求进行响应
} else {
if (nextHandler != null){//如果request不是这个hander就寻找下一个handlerRequest(。。)
nextHandler.handlerRequest(request, msgHeader, msgBody, ex, context);
} else {
responseError(msgHeader, ex);
}
}
}


}

这样一个客户端向服务端发送请求的实例就做好了。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/a514548454/article/details/25892817

智能推荐

Centos 6.4 minimal kamailio编译安装_baiyangliu的博客-程序员秘密

安装websocket模块所需库 yum install libunistring libunistring-devel提示:/usr/bin/ld: cannot find -lmysqlclient解决办法:rpm -ivh MySQL-shared-5.6.14-1.linux_glibc2.5.x86_64.rpm提示:chown: invalid user

鲲鹏云计算解决方案“-容器迁移实验_hmad的博客-程序员秘密

鲲鹏云计算解决方案"-容器迁移实验实验简介Docker安装检查内核版本移除旧的版本安装Docker依赖工具。Docker构建基础镜像任务3 Docker根据基础镜像安装Redis验证Redis镜像实验简介通过Docker安装,构建基础镜像,根据基础镜像安装Redis,验证Redis镜像等模块的实验练习和实训,让学员掌握容器的迁移指导。实验目的掌握Docker安装。掌握Docker构建基础镜像。掌握Docker根据基础镜像安装Redis。掌握验证构建的Redis镜像。实验环境华为云鲲鹏虚拟

Spring Boot项目application.yml文件数据库配置密码加密_application.yml配置密码_辰小白的博客-程序员秘密

在Spring boot开发中,需要在application.yml文件里配置数据库的连接信息,或者在启动时传入数据库密码,如果不加密,传明文,数据库就直接暴露了,相当于"裸奔"了,因此需要进行加密处理才行。 使用@SpringBootApplication注解启动的项目,只需增加maven依赖我们对信息加解密是使用这个jar包的:编写加解密测试类:package cn...

配置logback.xml文件来实现日志文件输出(项目本地文件)--以及遇到不能打印问题_打印日志必须要配logback.xml吗_骑车去哪儿的博客-程序员秘密

如何配置logback.xmllogback.xml各标签含义:二级目录三级目录logback.xml各标签含义:整个目录结构:`${glmapper-name}&lt;appender&gt; //xxxx&lt;/appender&gt; &lt;logger&gt; //xxxx&lt;/logger&gt;&lt;root&gt; //xxxx&lt;/root&gt; 》`二级目录三级目录...

SQL获取数据库中表信息:表名、建表时间、总行数、数据大小等_sql怎么查看表的信息_袁袁袁袁满的博客-程序员秘密

目录写法1(推荐)写法2:只获取库中表名、行数建表时间写法3:只查看表名和建表时间写法4:有点小问题,大佬帮忙改一下写法5:查看某个数据库大小写法5:查看某个表写法1(推荐)SQL:USE [test] -- 只需修改这里的库名SELECT a.name table_name, -- 表名 a.crdate crdate, -- 建表时间 b.rows rows, -- 总行数 8*b.reserved/1024 reserved, -- 保留大小

随便推点

pyinstaller打包python脚本和资源_songqiu65的博客-程序员秘密

1.安装pyinstallerpip install pyinstaller2.无图标资源打包:pyinstaller -F pyPath/name.py就可以看到生成了build和dist文件夹,dist文件夹中有你打包的exe,是单个文件(不带-F就是一群散文件)有图标资源打包1:pyi-makespec pyPath/name.py它会生成name.spec,这时打开spec文件可以看到下面代

HTML5期末大作业:美食甜品网站设计——餐饮咖啡(11页)HTML+CSS+JavaScript 使用dreamweaver制作采用DIV+CSS进行布局 HTML5网页设计成品..._网页设计咖啡店html5网页_@码住夏天-web网页设计的博客-程序员秘密

常见网页设计作业题材有 ​​个人、 美食、 公司、 学校、 旅游、 电商、 宠物、 电器、 茶叶、 家居、 酒店、 舞蹈、 动漫、 明星、 服装、 体育、 化妆品、 物流、 环保、 书籍、 婚纱、 游戏、 节日、 戒烟、 电影、 摄影、 文化、 家乡、 鲜花、 礼品、 汽车、 其他​​ 等网页设计题目, ​​A+水平作...

angularJS控制器ng-controller里获取不到input标签里ng-model的值_Lucky_bo的博客-程序员秘密

所遇问题:&lt;div class="list list-inset item item-input"&gt; &lt;i class="icon ion-ios-search placeholder-icon positive" ng-click="queryData(true,1)"&gt;&lt;/i&gt; &lt;input type="text" placeh...

FFmpeg源代码简单分析:avformat_alloc_output_context2()_avformat_alloc_output_context2 源码_雷霄骅的博客-程序员秘密

本文简单分析FFmpeg中常用的一个函数:avformat_alloc_output_context2()。在基于FFmpeg的视音频编码器程序中,该函数通常是第一个调用的函数(除了组件注册函数av_register_all())。avformat_alloc_output_context2()函数可以初始化一个用于输出的AVFormatContext结构体。它的声明位于libavformat\a

ubuntu更换python pip国内源_追天一方的博客-程序员秘密

以清华源为例1.pip安装源可以在命令中临时使用: pip install -i https://pipy.tuna.tsinghua.edu.cn/simple 包名2.长久使用的话,需要使用配置文件: (1).创建pip.conf配置文件 打开终端,执行如下命令。mkdir ~/.pipcd ~/.piptouch pip.conf (2).进入配置文件sudo nano ~/.pip/pip.conf[global]i...

智能计算系统(学习笔记)-第二章神经网络_确定阈值逻辑单元的神经网络的参数wji和θj,如右图所示,以计算布尔变量x1和x2的异_oliveQ的博客-程序员秘密

课程: (中科院)地址第一章人工智能底层的缺失导致智能产业变成空中阁楼为什么有智能计算系统芯片层---&gt;系统层---&gt;算法层---&gt;应用层计算机专业培养计算机整体及子系统的设计者和研究者不但会开车,还会制造汽车计算机系统的研究,算法仅仅是系统的一个环节,算法服务于系统.例如系统(Tensorflow,AlphaGo,TPU(芯片))计算机系统的研究,形成系统思维,拥有更广阔的科研道路.包括集成CPU和智能芯片的异构系统,软件上面向开发者的智能计算编程环境....

推荐文章

热门文章

相关标签