最近两个项目之间的需要做数据同步,要求是A项目的数据以及图片文件要同步到B项目,首先两个项目都是独立的采集录入信息的项目,数据库数据同步不说了,还有一些图片等文件也得需要同步, 首先想到的是B项目调用A项目的图片路径,因为两个项目的图片文件路径有很多种生成情况,两项目都在运行中,这种图片路径方法就排除了。 后面就想到了两种解决方法:
1 socket 方法 就是在B项目添加侦听 B项目启动时候start, 在A项目中用Client 。
2 在A项目中通过HttpURLConnection模拟post表单提交到B项目对应方法。(个人感觉这种比较好)
HttpURLConnection:
package test.httpUp;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
public class HttpPostUtil {
URL url;
HttpURLConnection conn;
String boundary = "--------http";
Map<String, String> textParams = new HashMap<String, String>();
Map<String, File> fileparams = new HashMap<String, File>();
DataOutputStream ds;
public HttpPostUtil(String url) throws Exception {
this.url = new URL(url);
}
//重新设置要请求的服务器地址,即上传文件的地址。
public void setUrl(String url) throws Exception {
this.url = new URL(url);
}
//增加一个普通字符串数据到form表单数据中
public void addTextParameter(String name, String value) {
textParams.put(name, value);
}
//增加一个文件到form表单数据中
public void addFileParameter(String name, File value) {
fileparams.put(name, value);
}
// 清空所有已添加的form表单数据
public void clearAllParameters() {
textParams.clear();
fileparams.clear();
}
// 发送数据到服务器,返回一个字节包含服务器的返回结果的数组
public byte[] send() throws Exception {
initConnection();
try {
conn.connect();
} catch (SocketTimeoutException e) {
// something
throw new RuntimeException();
}
ds = new DataOutputStream(conn.getOutputStream());
writeFileParams();
writeStringParams();
paramsEnd();
InputStream in = conn.getInputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream();
int b;
while ((b = in.read()) != -1) {
out.write(b);
}
conn.disconnect();
return out.toByteArray();
}
//文件上传的connection的一些必须设置
private void initConnection() throws Exception {
conn = (HttpURLConnection) this.url.openConnection();
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setConnectTimeout(10000); //连接超时为10秒
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type",
"multipart/form-data; boundary=" + boundary);
}
//普通字符串数据
private void writeStringParams() throws Exception {
Set<String> keySet = textParams.keySet();
for (Iterator<String> it = keySet.iterator(); it.hasNext();) {
String name = it.next();
String value = textParams.get(name);
ds.writeBytes("--" + boundary + "\r\n");
ds.writeBytes("Content-Disposition: form-data; name=\"" + name
+ "\"\r\n");
ds.writeBytes("\r\n");
ds.writeBytes(encode(value) + "\r\n");
}
}
//文件数据
private void writeFileParams() throws Exception {
Set<String> keySet = fileparams.keySet();
for (Iterator<String> it = keySet.iterator(); it.hasNext();) {
String name = it.next();
File value = fileparams.get(name);
ds.writeBytes("--" + boundary + "\r\n");
ds.writeBytes("Content-Disposition: form-data; name=\"" + name
+ "\"; filename=\"" + encode(value.getName()) + "\"\r\n");
ds.writeBytes("Content-Type: " + getContentType(value) + "\r\n");
ds.writeBytes("\r\n");
ds.write(getBytes(value));
ds.writeBytes("\r\n");
}
}
//获取文件的上传类型,图片格式为image/png,image/jpg等。非图片为application/octet-stream
private String getContentType(File f) throws Exception {
// return "application/octet-stream"; // 此行不再细分是否为图片,全部作为application/octet-stream 类型
ImageInputStream imagein = ImageIO.createImageInputStream(f);
if (imagein == null) {
return "application/octet-stream";
}
Iterator<ImageReader> it = ImageIO.getImageReaders(imagein);
if (!it.hasNext()) {
imagein.close();
return "application/octet-stream";
}
imagein.close();
return "image/" + it.next().getFormatName().toLowerCase();//将FormatName返回的值转换成小写,默认为大写
}
//把文件转换成字节数组
private byte[] getBytes(File f) throws Exception {
FileInputStream in = new FileInputStream(f);
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] b = new byte[1024];
int n;
while ((n = in.read(b)) != -1) {
out.write(b, 0, n);
}
in.close();
return out.toByteArray();
}
//添加结尾数据
private void paramsEnd() throws Exception {
ds.writeBytes("--" + boundary + "--" + "\r\n");
ds.writeBytes("\r\n");
}
// 对包含中文的字符串进行转码,此为UTF-8。服务器那边要进行一次解码
private String encode(String value) throws Exception{
return URLEncoder.encode(value, "UTF-8");
}
public static void main(String[] args) throws Exception {
HttpPostUtil u = new HttpPostUtil("http://xxxxxx.action");
u.addTextParameter("path", "qs/");
u.addTextParameter("fileName", "111.jpg");
u.addFileParameter("picFile", new File(
"D://272.jpg"));
u.addTextParameter("text", "utf-8");
byte[] b = u.send();
String result = new String(b);
System.out.println(result);
}
}
=====================
socket client
package test.socket;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.URL;
/**
* 文件发送客户端主程序
* @author admin_Hzw
*
*/
public class BxClient {
/**
* 程序main方法
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
int length = 0;
double sumL = 0 ;
byte[] sendBytes = null;
Socket socket = null;
DataOutputStream dos = null;
FileInputStream fis = null;
boolean bool = false;
try {
File file = new File("d:/272.jpg"); //要传输的文件路径
long l = file.length();
socket = new Socket();
socket.connect(new InetSocketAddress("192.168.1.110", 8877));
dos = new DataOutputStream(socket.getOutputStream());
fis = new FileInputStream(file);
sendBytes = new byte[1024];
while ((length = fis.read(sendBytes, 0, sendBytes.length)) > 0) {
sumL += length;
System.out.println("已传输:"+((sumL/l)*100)+"%");
dos.write(sendBytes, 0, length);
dos.flush();
}
//虽然数据类型不同,但JAVA会自动转换成相同数据类型后在做比较
if(sumL==l){
bool = true;
}
}catch (Exception e) {
System.out.println("客户端文件传输异常");
bool = false;
e.printStackTrace();
} finally{
if (dos != null)
dos.close();
if (fis != null)
fis.close();
if (socket != null)
socket.close();
}
System.out.println(bool?"成功":"失败");
}
}
socket server
web.xml
<listener>
<listener-class>XXX.web.listener.SocketServiceLoader</listener-class>
</listener>
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class SocketServiceLoader implements ServletContextListener { //socket server 线程
private SocketThread socketThread;
@Override
public void contextDestroyed(ServletContextEvent arg0) {
if(null!=socketThread && !socketThread.isInterrupted())
{
socketThread.closeSocketServer();
socketThread.interrupt();
}
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
// TODO Auto-generated method stub
if(null==socketThread)
{
//新建线程类
socketThread=new SocketThread(null);
//启动线程
socketThread.start();
}
} }
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketThread extends Thread{
private ServerSocket serverSocket = null;
public SocketThread(ServerSocket serverScoket){
try {
if(null == serverSocket){
this.serverSocket = new ServerSocket(8877);
System.out.println("socket start");
}
} catch (Exception e) {
System.out.println("SocketThread创建socket服务出错");
e.printStackTrace();
}
}
public void run(){
while(!this.isInterrupted()){
try {
Socket socket = serverSocket.accept();
if(null != socket && !socket.isClosed()){
//处理接受的数据
new SocketOperate(socket).start();
}
socket.setSoTimeout(30000);
}catch (Exception e) {
e.printStackTrace();
}
}
}
public void closeSocketServer(){
try {
if(null!=serverSocket && !serverSocket.isClosed())
{
serverSocket.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Random;
public class SocketOperate extends Thread{
private Socket socket;
public SocketOperate(Socket socket) {
this.socket=socket;
}
@SuppressWarnings("unused")
public void run()
{
try{
System.out.println("开始监听...");
/*
* 如果没有访问它会自动等待
*/
System.out.println("有链接");
receiveFile(socket);
} catch (Exception e) {
System.out.println("服务器异常");
e.printStackTrace();
}
}
/*public void run() {
}*/
/**
* 接收文件方法
* @param socket
* @throws IOException
*/
public static void receiveFile(Socket socket) throws IOException {
byte[] inputByte = null;
int length = 0;
DataInputStream dis = null;
FileOutputStream fos = null;
String filePath = "D:/temp/"+new Random().nextInt(10000)+".jpg";
try {
try {
dis = new DataInputStream(socket.getInputStream());
File f = new File("D:/temp");
if(!f.exists()){
f.mkdir();
}
/*
* 文件存储位置
*/
fos = new FileOutputStream(new File(filePath));
inputByte = new byte[1024];
System.out.println("开始接收数据...");
while ((length = dis.read(inputByte, 0, inputByte.length)) > 0) {
fos.write(inputByte, 0, length);
fos.flush();
}
System.out.println("完成接收:"+filePath);
} finally {
if (fos != null)
fos.close();
if (dis != null)
dis.close();
if (socket != null)
socket.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}