在开发过程中用的是http请求,但是响应流一直为空,获取到的响应流{"n_a_s":1,"atts":[]},最终修改用okhttp方法。http请求方法也放在文章最后,大家如果有类似的问题欢迎一起讨论。
/**
* OA附件生成接口
* @param urlstr 上传地址
* @param filename 路径
* @param token
* @return
* @throws BusinessException
* @throws IOException
*/
public static String filePost(String urlstr, String filename, String token) throws BusinessException, IOException {
try {
OkHttpClient client = new OkHttpClient().newBuilder().build();
MediaType mediaType = MediaType.parse("text/plain");
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("file",filename,
RequestBody.create(MediaType.parse("application/octet-stream"),
new File(filename)))
.build();
Request request = new Request.Builder()
.url("http://192.168.1.15:8090/seeyon/rest/attachment?token="+token)
.method("POST", body)
.addHeader("Cookie", "JSESSIONID=7144DE4003B79E88839BF28F5E89A171")
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful())
throw new IOException("Unexpected code " + response);
return response.body().string();
} catch (IOException e) {
throw new BusinessException(e.getMessage(), e);
}
}
public static String sendFiles(String urlstr, String filename,String token) throws BusinessException {
DataOutputStream dos = null;
OutputStream os = null;
//生成一个文件,把文件转换成流对象FileBody
File file = new File(filename);
JSONObject json = new JSONObject();
String BOUNDARY = "----WebKitFormBoundary7MA4YWxkTrZu0gW";
//前缀
String PREFIX = "--";
//换行符
String ROW = "\r\n";
//产生一个边界
// String BOUNDARY = UUID.randomUUID().toString().replaceAll("-" , "");
try {
URL url = new URL(urlstr.toString());
//打开和url之间的连接
HttpURLConnection hc = (HttpURLConnection) url.openConnection();
//请求头
//设置超时时间
hc.setConnectTimeout(10000);
//允许输入流
hc.setDoInput(true);
//允许输出流
hc.setDoOutput(true);
//不允许使用缓存
hc.setUseCaches(false);
//请求方式
hc.setRequestMethod("POST");
//设置通用的请求属性
hc.setRequestProperty("accept", "*/*");
//设置编码 utf-8
hc.setRequestProperty("Charset", "utf-8");
//设置为长连接
hc.setRequestProperty("Connection", "Keep-Alive");
//设置浏览器代理
hc.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36");
hc.setRequestProperty("token", token);
//边界标识
// String boundary = Long.toHexString(System.currentTimeMillis());
//这里设置请求方式以及boundary的内容,即上面生成的随机字符串
// hc.setRequestProperty("Content-Type", CONTENT_TYPE+"; boundary=----" + boundary);
hc.setRequestProperty("Content-Type","multipart/form-data; boundary=" + BOUNDARY);
hc.connect();
StringBuilder contentBody1 = new StringBuilder();
DataOutputStream out =new DataOutputStream(hc.getOutputStream());
os = hc.getOutputStream();
dos = new DataOutputStream(os);
String result = "";
if (file != null) {
//当文件不为空,把文件包装并且上传
//这里定义输出流,用于之后向服务器发起请求
//第一部分参数:excel文件
// contentBody1.append("Content-Type:").append("multipart/form-data; boundary=" + BOUNDARY).append(ROW);
contentBody1.append(ROW).append(BOUNDARY).append(ROW);
//拼接文件名称
contentBody1.append("Content-Disposition: form-data; name=\"file\"; filename=\"").append(file.getName())
.append("\"")
.append(ROW)
//设置内容类型为流及编码为UTF-8
.append("Content-Type: application/octet-stream; charset=UTF-8");
//Todo 这两个换行很重要 标识文件信息的结束 后面的信息为文件流
contentBody1.append(ROW).append(ROW);
out.write(contentBody1.toString().getBytes(StandardCharsets.UTF_8));
//写入文件流
InputStreamReader reader=new InputStreamReader(new FileInputStream(file),"UTF-8");
//读入缓冲区
char[] buffer = new char[1024];
//读入结果
StringBuffer sb = new StringBuffer();
//每次读入缓冲区的长度
int len;
//从读入流中读取文件内容并形成结果
while ((len = reader.read(buffer)) != -1) {
sb.append(buffer, 0, len);
}
byte[] data = sb.toString().getBytes();
// 向文件写入内容
out.write(data);
out.write(ROW.getBytes(StandardCharsets.UTF_8));
//写入边界结束符
out.write((BOUNDARY+PREFIX).getBytes(StandardCharsets.UTF_8));
out.close();
out.flush();//可以理解为发送请求
//从服务器获得回答的内容
/**
* 获取响应码 200=成功
* 当响应成功,获取响应的流
*/
int res = hc.getResponseCode();
//获取后台返回的数据
if (res == 200) {
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(hc.getInputStream()));
String line;
StringBuffer sb_result = new StringBuffer();
while ((line = bufferedReader.readLine()) != null) {
sb_result.append(line);
}
return sb_result.toString();
// out.close();
}else {
BufferedReader bReader = new BufferedReader(new InputStreamReader(hc.getErrorStream(), "UTF-8"));
int ch;
while ((ch = bReader.read()) != -1) {
result += String.valueOf((char) ch);
}
throw new BusinessException(result, res + "");
} }
} catch (Exception e) {
Logger.error("发送 POST 请求出现异常!" + e);
throw new BusinessException("发送 POST 请求出现异常:" + e.getMessage(), e);
} finally {
if (dos != null) {
try {
dos.close();
} catch (Exception e2) {
Logger.error(e2.getMessage(), e2);
}
}
if (os != null) {
try {
os.close();
} catch (Exception e2) {
Logger.error(e2.getMessage(), e2);
}
}
if(!"".equals(json)&&json!=null) {
JSONObject parseObject = JSONObject.parseObject(json.toString());
Object object = parseObject.get("fileUrl");
if(!"".equals(object)&&object!=null) {
return object.toString();
}
// log.writesendlog(url1+";;type:"+type+";;;数据:"+param, entityName+"error","");
}
}
return FAILURE;
}
PS:okhttp方法需要okhttp3和okio两个jar包,需要可以私信。
今天代码打到测试环境发现上传附件还是获取不到fileurl这个值,在postman测试时发送正常,我将postman中的代码取出(如下),怀疑是Cookie引发的问题,仔细查看Cookie获取的是JSESSIONID,这个id是从哪里获取到的呢?
OkHttpClient client = new OkHttpClient().newBuilder().build();
MediaType mediaType = MediaType.parse("text/plain");
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("file","/C:/Users/86177/Desktop/发起OA流程表单接口.doc",
RequestBody.create(MediaType.parse("application/octet-stream"),
new File("/C:/Users/86177/Desktop/发起OA流程表单接口.doc")))
.build();
Request request = new Request.Builder()
.url("https://127.0.0.1:80/seeyon/rest/attachment?token=391ed45d-798a-4a08-b0cd-6631ac2173b6")
.method("POST", body)
.addHeader("Cookie", "JSESSIONID=FC05529B631B89C2F1B9F21DDC845A50; route=d9b669d27408c3f4e55a50b632da8fb2")
.build();
Response response = client.newCall(request).execute();
让我们先看一下用postman获取到的附件上传的截图,图中可以看出此时可以附件已经发送成功,Cookie的值是187EC412AF0F028ACFA24BDB59FEF602,我询问了OA的老师,老师说token要获取登录名,建议我看看有没有获取到,我才想起来之前发送HTTP请求是我并没有绑定登录名,我用postman再次查看之前获取token的信息。
此时可以看到绑定登录者的token返回时会带回sessionid,这个值就是我们想要的,请求的url地址应该是http://IP:端口/seeyon/rest/token/用户名/密码?loginName=登录名
在HTTP请求获取token返回时还遇到了中文乱码问题,一并指出,在下文得到输入流时进行utf-8转码,最后从result结果中获取到发送成功的id,不需要sessionid,因为绑定了用户名的id可以在发送附件时自动存储在cookie。以上就是我在开发中遇到的问题,希望对你有所帮助。
/**
* 获取token
* @return
*/
public static String getToken2() {
String result = "";
String id = "";
try{
String oAURL = SysInitQuery.getParaString("GLOBLE00000000000000", "OAURL");
String oAusername = SysInitQuery.getParaString("GLOBLE00000000000000", "OAuser");
String oAPassword = SysInitQuery.getParaString("GLOBLE00000000000000", "OApassword");
StringBuilder lasturl = new StringBuilder(oAURL+"/seeyon/rest/token/"+oAusername+"/"+oAPassword+"?loginName=tianxiang");
URL url = new URL(lasturl.toString());
//打开和url之间的连接
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
//请求头
urlConn.setRequestProperty("Content-Type", "application/json");
urlConn.setRequestProperty("Accept", "application/json;charset=UTF-8");
urlConn.setDoOutput(true);
urlConn.setDoInput(true);
urlConn.setRequestMethod("GET");//GET和POST必须全大写
urlConn.connect();
int code = urlConn.getResponseCode();//获得响应码
if(code == 200) {//响应成功,获得响应的数据
// InputStream is = urlConn.getInputStream();//得到数据流(输入流)
InputStreamReader is = new InputStreamReader(urlConn.getInputStream(),"UTF-8");
BufferedReader bufferedReader = new BufferedReader(is);
StringBuffer stringBuffer = new StringBuffer();
String line = null;
while ((line = bufferedReader.readLine()) != null) {
stringBuffer.append(line);
}
result = stringBuffer.toString();
if(!"".equals(result)&&result!=null){
JSONObject parseObject = JSONObject.parseObject(result);
Object object = parseObject.get("id");
if(object != null && !"".equals(object)) {
urlConn.disconnect(); //断开连接
return object.toString();
}
}
}
urlConn.disconnect(); //断开连接
}catch (Exception e) {
e.printStackTrace();
}
return null;
}