在业务发展中,根据不同的业务需求,建立了不同的系统;系统间是相互独立的,为了避免信息孤岛,各系统通过对外提供接口进行交互;在众多的业务系统群中,通过点对点的接口交互存在很多弊端,系统间的接口交互混乱,不方便管理等等;采用SOA架构,ESB服务,又有点牛刀杀鸡;故设计了接口请求中转的组件;该组件接受各业务系统的报文请求,根据请求的交易码,去调用对应的组件处理;交易码和处理组件都配置在数据库中;
组件的主方法:
public class InterfaceServers {
private int port = 9999;
private ServerSocket serverSocket;
private ExecutorService executorService;// 线程池
private final int POOL_SIZE = 10;// 单个CPU线程池大小
protected Log log = LogFactory.getLog(this.getClass());
public static void main(String[] args) throws Exception {
try {
new InterfaceServers().serverStart();
} catch (IOException e) {
e.printStackTrace();
}
}
public InterfaceServers() throws IOException {
this.serverSocket = new ServerSocket(port);
//使用Java线程池管理线程,每个CPU分10个线程
this.executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * POOL_SIZE);
log.info("BGO服务启动...");
String thisHostIp = "";
try {
thisHostIp = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
}
log.info("\n监听IP:" + thisHostIp + " 端口:" + port);
}
public void serverStart() throws Exception {
//服务端收报就是在一个死循环里面,socket.accept()
while (true) {
//服务端收报就是在一个死循环里面,socket.accept()
Socket socket = serverSocket.accept();
//executorService.execute(new PrcThread(socket));//接受到报文
switchInterface(socket);
}
}
public void switchInterface(Socket socket) throws Exception{
ByteArrayOutputStream headOutputStream = new ByteArrayOutputStream();
OutputStream socketOutStream = socket.getOutputStream();
InputStream socketInStream = socket.getInputStream();
//接受报文
byte[] reciveContentByteArray = readFromHttp(socketInStream, headOutputStream);
String reciveStr = new String(reciveContentByteArray,"utf-8");
log.info("请求报文:"+reciveStr);
//根据报文中的交易码去数据库中找到对应的实现类,通过java反射机制将实例化对象,并将请求交给该实例去处理
SoapHead head = SoapParser.getHead(reciveContentByteArray);
BgoTradeCodeDao bgoTradeCodeDao = new BgoTradeCodeDao();
bgoTradeCodeDao.setTransactionManager(DB.getTransactionManager());
InterfaceCodeBean interfaceCodeBean = bgoTradeCodeDao.getInterfaceCodeBean(head.getTradeCode());
if(interfaceCodeBean!=null){
//实例化具体的处理组件,将请求交由该组件去处理
InterfaceConsumer newInstance = (InterfaceConsumer)Class.forName(interfaceCodeBean.getImplClass()).newInstance();
newInstance.process(interfaceCodeBean, socketOutStream, reciveStr.getBytes("utf-8"));
}else{
recive(socketOutStream,head,"交易码不存在");
}
if (socketOutStream != null){
socketOutStream.close();
}
if (socketInStream != null){
socketInStream.close();
}
if (socket != null){
socket.close();
}
}
protected static String readLine(InputStream in) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
int c;
int i = 0;
byte[] rn = { '\r', '\n' };
c = in.read();
while (c > -1) {
if ((byte) c == rn[i]) {
i++;
if (i > 1)
break;
} else {
if (i > 0)
out.write(rn[0]);
i = 0;
out.write(c);
}
c = in.read();
}
return new String(out.toByteArray());
}
/**
* 读取HTTP协议的报文
* @param in
* @param headOutputStream
* @return
* @throws Exception
*/
public static byte[] readFromHttp(InputStream in, OutputStream headOutputStream) throws Exception {
ByteArrayOutputStream bodyOutputStream = new ByteArrayOutputStream();
byte buf[] = new byte[1024];
int len = 0;
String headStr = readLine(in);
Properties headers = new Properties();
writetofile(headOutputStream, headStr);
readHeads(in, headers, headOutputStream);
int contentLength = getContentLen(headers);
int readLen = contentLength > 1024 ? 1024 : contentLength;
while (contentLength > 0 && (len = in.read(buf, 0, readLen)) > 0) {
contentLength -= len;
bodyOutputStream.write(buf, 0, len);
headOutputStream.write(buf, 0, len);
readLen = contentLength > 1024 ? 1024 : contentLength;
}
return bodyOutputStream.toByteArray();
}
private static void writetofile(OutputStream out, String content) throws Exception {
if (out == null)
return;
out.write((content + "\r\n").getBytes());
}
protected static void readHeads(InputStream in, Properties headers, OutputStream out) throws Exception {
String line = readLine(in);
writetofile(out, line);
while (line.trim().length() > 0) {
int p = line.indexOf(':');
headers.put(line.substring(0, p).trim(), line.substring(p + 1).trim());
line = readLine(in);
writetofile(out, line);
}
}
protected static int getContentLen(Properties headers) {
int contentLength = 0;
String line = (String) headers.get("Content-Length");
if (line != null) {
try {
contentLength = Integer.parseInt(line);
} catch (NumberFormatException ex) {
contentLength = 0;
}
}
return contentLength;
}
/**
* 发送异常响应报文
*
* @param socketOutStream
* @param soapHead
* @throws Exception
*/
protected void recive(OutputStream socketOutStream,SoapHead soapHead,String errorInfo) throws Exception{
SoapConstructor constructor=new SoapConstructor();
//创建报文
soapHead.setCommCode(SoapHead.COMMCODE_ONLINE_RPN_ONLINE);
String create = constructor.create(soapHead, soapHead.getTradeCode()+"-"+errorInfo);
byte responseContent[] = create.getBytes("utf-8");
log.info("响应报文:"+new String(responseContent).toString());
//****发响应报文!!!!!!************************
socketOutStream.write("HTTP/1.0 200 OK\r\n".getBytes());// 返回应答消息,并结束应答
socketOutStream.write(("Content-Length: " + responseContent.length + "\r\n").getBytes());
socketOutStream.write("\r\n".getBytes()); // 根据 HTTP 协议, 空行将结束头信息
socketOutStream.write(responseContent);
socketOutStream.flush();
}
}