这两天给手机写了几个服务(接口形式),其他数据还好,图片实在没处理过,这里记录下使用base64编码遇到的坑。。。。
1、图片转base64编码:
public static String getImageStr(String imgUrl) {//将图片文件转化为字节数组字符串,并对其进行Base64编码处理
String imgFile = imgUrl;// 待处理的图片
InputStream in = null;
byte[] data = null;
// 读取图片字节数组
try {
in = new FileInputStream(imgFile);
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
// 对字节数组Base64编码
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);// 返回Base64编码过的字节数组字符串
}
2、base64编码转图片:
public static boolean GenerateImage(String imgStr,String newPath) { // 对字节数组字符串进行Base64解码并生成图片
if (imgStr == null) // 图像数据为空
return false;
BASE64Decoder decoder = new BASE64Decoder();
try {
// Base64解码
byte[] b = decoder.decodeBuffer(imgStr);
for (int i = 0; i < b.length; ++i) {
if (b[i] < 0) {// 调整异常数据
b[i] += 256;
}
}
// 生成jpeg图片
OutputStream out = new FileOutputStream(newPath);
out.write(b);
out.flush();
out.close();
return true;
} catch (Exception e) {
return false;
}
}
3、上面两个方法正常使用是没问题的,但是手机上传图片到服务器需要通过参数的形式传到接口,操作起来就比较费劲了,我这里的思路比较笨:手机把base64编码传到接口,接口转成图片后存到图片服务器,数据库保存地址,下面看代码:
@RequestMapping("/inkinfo/saveOrUpdate")
@ResponseBody
public Object saveOrUpdateInkinfo(HttpServletRequest request,HttpServletResponse response){
AppMessage appMsg = new AppMessage();
String data;
try {
//编码修正(框架存在问题:web.xml中增加字符集的监听设置未起作用)
data = new String(request.getParameter("data").getBytes("iso-8859-1"),"utf-8");
JSONObject map = (JSONObject) JsonUtils.toObejctByJson(data, JSONObject.class);
//储存签名图片
SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd HHmmss");
String d = String.valueOf(map.get("LINK_INFO"));
//设置服务器图片保存地址
String path = "D:/GSDJ_WebFile/"+map.get("USER_ID")+"/"+sdf.format(new Date())+"/"+map.get("CASE_ID")+".jpg";
//创建目录
File f = new File("D:/GSDJ_WebFile/"+map.get("USER_ID")+"/"+sdf.format(new Date()));
f.mkdirs();
//参数修补
d = d.replace(" ", "+");
//本地生成
StringUtil.GenerateImage(d, path);
map.put("LINK_INFO",path);
//业务数据保存
licAppService.saveOrUpdateInkinfo(map);
//保存流程
String OPT_CODE = map.get("OPT_CODE")==null?"": map.get("OPT_CODE").toString();//处理代码
if(!StringUtil.isNullOrEmpty(OPT_CODE)&&(OPT_CODE.equals("1")||OPT_CODE.equals("242")))
{
this.saveOrUpdateLicProcess(appMsg, map);
}
appMsg.setData(map);
return appMsg;
} catch (Exception e1) {
// TODO Auto-generated catch block
appMsg.setCode("E001");
appMsg.setMessage("服务器异常");
e1.printStackTrace();
return appMsg;
}
}参数修补是因为编码通过request传到后台以后编码种的+全部变成了空格,所以全部替换了(没找到别的问题之前先这样用了)如下图(左边是正常编码,右边是通过参数传到后台以后的):
图片还有一个合理的处理方法:图片传入时base64编码转成二进制数据,后台也不存图片,二进制可以直接存到数据库中,我主要问题卡在接口如何处理二进制数据上了,等研究出来再来补充这部分。
另外 java post调用接口代码:
public static String httpURLConnectionPOST (String POST_URL,String param) {
try {
URL url = new URL(POST_URL);
// 将url 以 open方法返回的urlConnection 连接强转为HttpURLConnection连接 (标识一个url所引用的远程对象连接)
HttpURLConnection connection = (HttpURLConnection) url.openConnection();// 此时cnnection只是为一个连接对象,待连接中
// 设置连接输出流为true,默认false (post 请求是以流的方式隐式的传递参数)
connection.setDoOutput(true);
// 设置连接输入流为true
connection.setDoInput(true);
// 设置请求方式为post
connection.setRequestMethod("POST");
// post请求缓存设为false
connection.setUseCaches(false);
// 设置该HttpURLConnection实例是否自动执行重定向
connection.setInstanceFollowRedirects(true);
// 设置请求头里面的各个属性 (以下为设置内容的类型,设置为经过urlEncoded编码过的from参数)
// application/x-javascript text/xml->xml数据 application/x-javascript->json对象 application/x-www-form-urlencoded->表单数据
// ;charset=utf-8 必须要,不然妙兜那边会出现乱码【★★★★★】
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
byte[] mydata = param.toString().getBytes("UTF-8");
// 设置请求体的类型
connection.setRequestProperty("Content-Lenth",
String.valueOf(mydata.length));
// 建立连接 (请求未开始,直到connection.getInputStream()方法调用时才发起,以上各个参数设置需在此方法之前进行)
connection.connect();
// 创建输入输出流,用于往连接里面输出携带的参数,(输出内容为?后面的内容)
DataOutputStream dataout = new DataOutputStream(connection.getOutputStream());
// 将参数输出到连接
if(!StringUtil.isNullOrEmpty(param)) {
dataout.write(mydata);
}
// 输出完成后刷新并关闭流
dataout.flush();
dataout.close(); // 重要且易忽略步骤 (关闭流,切记!)
// 连接发起请求,处理服务器响应 (从连接获取到输入流并包装为bufferedReader)
BufferedReader bf = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
String line;
StringBuilder sb = new StringBuilder(); // 用来存储响应数据
// 循环读取流,若不到结尾处
while ((line = bf.readLine()) != null) {
// sb.append(bf.readLine());
sb.append(line).append(System.getProperty("line.separator"));
}
bf.close(); // 重要且易忽略步骤 (关闭流,切记!)
connection.disconnect(); // 销毁连接
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}

1648

被折叠的 条评论
为什么被折叠?



