第一种:post多个文件
客户端的使用方法:
需要注意的点:
- 这里是为了方便使用才进行整合到DeliveryService里面,使用的时候引用该服务类即可。
- sendToCenter方法作为入口,传入文件数组File[ ]和服务端的地址,但是真正传输过程是在其调用的sendHttpPostRequest的方法。
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;
import java.io.*;
import java.net.*;
/**
* 传输服务
*/
@Component
public class DeliveryService {
/**
* 将文件上传到服务端
* @param files 文件集合
*/
public String sendToCenter(File[] files,String url){
String response = "";
try {
//中心服务器地址
String serverUrl = url + "getFileByClient";
//发送到中心服务器,并且获取响应结果
response = sendHttpPostRequest(serverUrl, files);
System.out.println("响应结果的内容为:"+response);
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
/**
* 通过post方式传送到中心服务器
* @param serverUrl 服务器地址
* @param files 文件集合
* @return
* @throws Exception
*/
public String sendHttpPostRequest(String serverUrl, File[] files) throws Exception {
String BOUNDARY = "----------" + System.currentTimeMillis();
// 向服务器发送post请求
URL url = null;
try {
url = new URL(serverUrl);
} catch (MalformedURLException e) {
e.printStackTrace();
return e.getMessage();
}
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
e.printStackTrace();
return e.getMessage();
}
// 发送POST请求头信息
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
try {
connection.setRequestMethod("POST");
} catch (ProtocolException e) {
e.printStackTrace();
return e.getMessage();
}
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Charset", "UTF-8");
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
StringBuilder message = new StringBuilder();//存放请求信息
// 链接服务器获得输出流
try (OutputStream out = new DataOutputStream(connection.getOutputStream())) {
// 循环读取上传文件读取个文件
for (int i = 0; i < files.length; i++) {
message.delete(0, message.length());
message.append("--");
message.append(BOUNDARY);
message.append("\r\n");
message.append("Content-Disposition: form-data;name=\"files\";filename=\"" + files[i].getName() + "\"\r\n");
message.append("Content-Type:application/octet-stream\r\n\r\n");
byte[] head = message.toString().getBytes("utf-8");
// 输出文件表头
out.write(head);
// 文件正文部分
// 把文件以流文件的方式 推入到url中
try (DataInputStream in = new DataInputStream(new FileInputStream(files[i]))) {
int bytes = 0;
byte[] bufferOut = new byte[1024];
while ((bytes = in.read(bufferOut)) != -1) {
out.write(bufferOut, 0, bytes);
}
} catch (IOException e) {
e.printStackTrace();
}
// 写入两个文件之间得分隔符,如果没有两个文件内容会被写在一个文件中
out.write("\r\n".getBytes("utf-8"));
}
// 结尾部分
byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定义最后数据分隔线
out.write(foot);
out.flush();
System.out.println("--------------------------------------");
System.out.println("out的内容:"+out);
} catch (IOException e1) {
e1.printStackTrace();
return e1.getMessage();
}
// 4. 从服务器获得回答的内容
String strLine = "";
String strResponse = "";
try (InputStream responseIO = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(responseIO))) {
while ((strLine = reader.readLine()) != null) {
strResponse += strLine + "\n";
}
} catch (IOException e) {
e.printStackTrace();
return e.getMessage();
}
return strResponse;
}
}
客户端的post逻辑是有了,那么服务端怎么去接收呢?
服务端的controller端接收的代码:
@PostMapping("/getFileByClient")
public String getFileByClient(MultipartFile[] files){
String response = "";
try {
ArrayList<File> fileArrayList = new ArrayList<>();
//获取到前置机发送过来文件
for (MultipartFile mufile : files) {
File file = UseUtils.multipartFileToFile(mufile);
fileArrayList.add(file);
}
//......逻辑代码
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
由上述代码可以知道,是用了 MultipartFile[ ]
的格式去接收传过来的文件,然后将每个MultipartFile取出转成File,存入集合中就可以操作文件了。
上面中MultipartFile转成File的方法我是封装了的,这里给出具体逻辑,如下:
public static File multipartFileToFile(MultipartFile file) throws Exception {
File toFile = null;
if (file.equals("") || file.getSize() <= 0) {
file = null;
} else {
InputStream ins = null;
ins = file.getInputStream();
toFile = new File(file.getOriginalFilename());
inputStreamToFile(ins, toFile);
ins.close();
}
return toFile;
}
但是,是不是感觉这种自写的post请求有点太麻烦,是不是觉得是集成好的工具就更简单了,这里就给出我使用到的一种,就是使用hutool集成好的工具包。
只需要引入hutool的依赖:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
然后在需要使用的post请求的逻辑中使用hutool的HttpUtil
工具类:
HashMap<String, Object> parm = new HashMap<>();
File[] listFile = dir.listFiles();
parm.put("files",listFile);
response = HttpUtil.post(url+"getFileByClient",parm);
上述代码需要注意的点:
- dir是一个目录,里面存放了需要上传的文件
- parm的键要用files才能识别出来(我也不确定是不是这样理解)
服务端的接收代码不用改就可以接收到传过来的文件,这样使用工具类就会简单一点了。
第二种:参数以json的格式post到服务器
这种方式是把参数以json的格式进行传输,如:
JSONObject jsonObject = new JSONObject();
jsonObject.put("code","007");
然后再以 jsonObject.toString()
的形式传入data参数中。
/**
* 携带code去请求服务端
* @param serverUrl 服务端地址
* @param data 发送的code
* @return
*/
public String sendCodeToCenter(String serverUrl, String data) throws Exception{
String encoding = "utf-8";
String body = "";
//创建httpclient对象
CloseableHttpClient client = HttpClients.createDefault();
//创建post方式请求对象
HttpPost httpPost = new HttpPost(serverUrl);
//装填参数
StringEntity s = new StringEntity(data.toString(), "utf-8");
s.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,"application/json"));
//设置参数到请求对象中
httpPost.setEntity(s);
//设置header信息
httpPost.setHeader("Content-type", "application/json");
httpPost.setHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
//执行请求操作,并拿到结果(同步阻塞)
CloseableHttpResponse response = client.execute(httpPost);
//获取结果实体
HttpEntity entity = response.getEntity();
if (entity != null) {
//按指定编码转换结果实体为String类型
body = EntityUtils.toString(entity, encoding);
}
EntityUtils.consume(entity);
//释放链接
response.close();
return body;
}
这种方式上传的参数,服务端的controller怎么接收呢?
这里使用到的方法就是:
/**
* 获取客户端post过来的code
* @param data code数据
* @return 处理响应
*/
@PostMapping("/getCodeByClient")
public String getCodeByClient(@RequestBody String data){
JSONObject jsonObject = JSONObject.parseObject(data);
Object getCode = jsonObject.get("code");
String response = "";
//......逻辑代码
return response;
}
可以注意到,是使用@RequestBody
来接收的,接收到之后,再将字符串转成JSONObject 格式,再根据key取出value。
问题又来了,如果使用hutool工具包,客户端的逻辑怎么写?
这里对需要传输的参数进行处理:
JSONObject parm = new JSONObject();
parm.put("code",localCode);
HttpUtil.post(centerUrl + "getCodeByClient", parm.toString());
第三种:将key:value的值post到服务端
- 这种方式的效果和第二种的效果是一样的,只是用到的类不一样而已。
- 其服务端接收的方式也和第二种的一致。
- 客户端用hutool工具包的方式也和第二种的一致。
import org.springframework.stereotype.Component;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
@Component
public class SendResultService {
/**
* 发送结果到前置机
*/
public void sendResultToQianZhi(){
//定义post的路径与参数
String strURL = "";
CenterResult centerResult = new CenterResult();
String params = centerResult.toString();
//post请求,返回响应结果
String response = post(strURL, params);
System.out.println("响应结果为:"+response);
}
/**
* post接收信息的方法
* @param strURL
* @param params
* @return
*/
public String post(String strURL, String params) {
System.out.println(strURL);
System.out.println(params);
BufferedReader reader = null;
try {
URL url = new URL(strURL);// 创建连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setInstanceFollowRedirects(true);
connection.setRequestMethod("POST"); // 设置请求方式
connection.setRequestProperty("Accept", "application/json"); // 设置接收数据的格式
connection.setRequestProperty("Content-Type", "application/json"); // 设置发送数据的格式
connection.connect();
//一定要用BufferedReader 来接收响应, 使用字节来接收响应的方法是接收不到内容的
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8"); // utf-8编码
out.append(params);
out.flush();
out.close();
// 读取响应
reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
String line;
String res = "";
while ((line = reader.readLine()) != null) {
res += line;
}
reader.close();
return res;
} catch (IOException e) {
e.printStackTrace();
}
return "error"; // 自定义错误信息
}
}
这篇内容记录的内容可能比较零散,不够全面,希望大伙能看得懂吧😰😰😰