之前写过一篇有关使用 Retrofit 上传图片文件的代码, 不过如果使用 OkHttp 该如何做呢. 相信对于这两者之间有些了解的同学都知道其实 Retrofit 的内部网络请求实现就是 OkHttp, 包裹了一层之后只是为了方便开发者写接口并且和 RxJava 结合使用而已, 所以代码的差别不是很大.
这里没有很好的封装, 只是一个 demo, 大家实际使用的时候给 okHttp 封装一层会更好. 我自己开发的语言是 Kotlin, 不过为了方便起见, 我会把 Java 版本的代码也粘贴上去, 至于后台的代码其实和上篇文章介绍的一样, 不过因为其中名称有所变动所以我还是会都给出. 如果有什么问题欢迎指出和提问
- // 上传背景图片的方法
- fun uploadBgImg(userid: String, imgPath: String, listener: UploadListener) {
- var file: File? = null
- try {
- file = File(imgPath)
- } catch (e: URISyntaxException) {
- e.printStackTrace()
- }
- val mOkHttpClent = OkHttpClient()
- val requestBody = MultipartBody.Builder()
- .setType(MultipartBody.FORM)
- .addFormDataPart("userid", userid) // 上传参数
- .addFormDataPart(
- "bgImg", file?.name,
- RequestBody.create(MediaType.parse("multipart/form-data"), file!!)
- ) // 上传文件
- .build()
- val request = Request.Builder()
- .url(ConstantConfig.JACKSON_BASE_URL + "phoneUser/uploadBgImg")
- .post(requestBody)
- .build()
- val call = mOkHttpClent.newCall(request)
- call.enqueue(object : Callback {
- override fun onFailure(call: Call, e: IOException) {
- LogUtils.e("yyy" + e.message)
- listener.uploadFailed(e.message.toString())
- }
- override fun onResponse(call: Call, response: Response) {
- if (response.isSuccessful) {
- listener.uploadSuccess()
- } else {
- listener.uploadSuccess()
- LogUtils.e("tttttt" + response.code() + response.message())
- }
- }
- })
- }
接口文件
- interface UploadListener {
- fun uploadSuccess()
- fun uploadFailed(msg: String)
- }
实际调用位置
- // 上传背景图片
- private fun uploadBgImg(path: String) {
- UploadUtils.uploadBgImg(App.getLoginUser()?.userid!!, path, object : UploadUtils.UploadListener {
- override fun uploadSuccess() {
- runOnUiThread {
- userBgImage.setImageBitmap(BitmapFactory.decodeFile(path))
- }
- LogUtils.e("ModifyUserInfo 成功")
- }
- override fun uploadFailed(msg: String) {
- LogUtils.e("ModifyUserInfo" + msg)
- }
- })
- }
这里需要注意的就是 okHttp 默认返回的线程是子线程而不是主线程. 所以我们如果需要进行一些操作的话还是需要有 runOnUiThread 方法切换到主线程中才可以. 大家有空闲的话可以封装一下, 具体使用可以通过 Handle, 毕竟是 Android 中的异步处理大师.
后台代码, 注意这里参数名称和上次那篇不一样, 所以如果使用的话不要对应出错
- /**
- * 用户背景图片上传
- */
- @RequestMapping(value = "/uploadBgImg", method = RequestMethod.POST)
- @ResponseBody
- public Map<String, Object> uploadBgImg(@RequestParam("userid") String userid, @RequestBody MultipartFile bgImg) {
- // 在 spring 家族中上传头像都是使用 MultipartFile 类. 多个文件则是数组类型
- System.out.println("进入背景图片上传接口");
- System.out.println("文件名:" + bgImg.getOriginalFilename() + "\n" + "userid:" + String.valueOf(userid));
- Map<String, Object> map = new HashMap<>();
- if (!bgImg.isEmpty()) {
- String originalFileName = bgImg.getOriginalFilename();
- String mimeType = request.getServletContext().getMimeType(originalFileName);
- System.out.println("mimeType:" + mimeType);
- // 是否图片文件
- if (mimeType != null && mimeType.startsWith("image/")) {
- try {
- String suffix = originalFileName.split("\\.")[1]; // 扩展名
- // 上传到项目根目录的 upload 文件夹
- String avatarPath = request.getSession().getServletContext().getRealPath("/upload") +
- // File.separator + user.getUsername() +
- File.separator + "avatar" +
- File.separator + System.currentTimeMillis() + "." + suffix;
- String savePath = avatarPath.substring(avatarPath.indexOf("\\upload"));
- String finPath = savePath.replaceAll("\\\\", "/");
- System.out.println("savePath:" + savePath);
- System.out.println("finPath:" + finPath);
- /**
- * 上传到具体的硬盘路径, 此时需要配置 tomcat 虚拟路径
- */
- // String avatarPath = "I:" + File.separator + "ProjectsFolder" + File.separator + "IdeaProject"
- // + File.separator + "MovieProject" + File.separator + "src" + File.separator + "main"
- // + File.separator + "webapp" + File.separator + "upload" + File.separator + user.getUsername()
- // + File.separator + "avatar" + File.separator + System.currentTimeMillis() + "." + suffix;
- System.out.println("tomcatPath:" + avatarPath);
- File saveFile = new File(avatarPath);
- if (!saveFile.getParentFile().exists()) {
- saveFile.getParentFile().mkdirs();
- saveFile.createNewFile();
- }
- bgImg.transferTo(saveFile); // 将文件上传到指定的服务器的位置
- int rows = userService.updateUserAvatar(userid, finPath.substring(1)); // 存储在数据库中的路径就从 upload 开始就可以了,
- // 这里的 sub 是为了去除第一个 '/'
- if (rows> 0) {
- System.out.println("上传背景图片成功");
- // // 上传文件成功之后查询 user, 之后把最新的 user 返回
- PhoneUser user = userService.getUserInfo(userid);
- if (user != null) {
- map.put("data", user);
- map = CommonUtils.operationSucceed(map);
- } else {
- map = CommonUtils.operationFailed(map, "other error", HttpStatus.NOT_FOUND.value());
- }
- } else {
- System.out.println("上传背景图片失败");
- map = CommonUtils.operationFailed(map,
- "change data failed", HttpStatus.BAD_REQUEST.value());
- }
- } catch (IOException e) {
- // 上传过程出错
- System.out.println(e.getMessage());
- map = CommonUtils.operationFailed(map, "upload fail", HttpStatus.INTERNAL_SERVER_ERROR.value());
- e.printStackTrace();
- }
- } else {
- // 不是图片文件返回相关信息
- map = CommonUtils.operationFailed(map, "please upload an image file", HttpStatus.BAD_REQUEST.value());
- }
- // 空文件返回相关
- } else {
- System.out.println("empty file");
- map = CommonUtils.operationFailed(map, "empty file", HttpStatus.BAD_REQUEST.value());
- }
- return map;
- }
到此代码完成, 其中注释也都比较丰富相信大家都能理解. 下面我把 Java 版本的前台代码贴出来供大家参考.
- // 上传背景图片的方法
- public static void uploadBgImg(String userid, String imgPath, final UploadUtils.UploadListener listener) {
- File file = null;
- try {
- file = new File(imgPath);
- } catch (Exception e) {
- e.printStackTrace();
- }
- OkHttpClient mOkHttpClent = new OkHttpClient();
- assert file != null;
- MultipartBody requestBody = new MultipartBody.Builder()
- .setType(MultipartBody.FORM)
- .addFormDataPart("userid", userid) // 上传参数
- .addFormDataPart(
- "bgImg", file.getName(),
- RequestBody.create(MediaType.parse("multipart/form-data"), file)
- ) // 上传文件
- .build();
- Request request = new Request.Builder()
- .url(ConstantConfig.JACKSON_BASE_URL + "phoneUser/uploadBgImg")
- .post(requestBody)
- .build();
- Call call = mOkHttpClent.newCall(request);
- call.enqueue(new Callback() {
- @Override
- public void onFailure(@NonNull Call call, @NonNull IOException e) {
- listener.uploadFailed(e.getMessage());
- }
- @Override
- public void onResponse(@NonNull Call call, @NonNull Response response) {
- if (response.isSuccessful())
- listener.uploadSuccess();
- }
- });
- }
相信小伙伴们自己也可以写出来, 不过可惜 AS 只提供了 Java 转 Kotlin 的插件, 没有 Kotlin 转 Java 的插件. 所以只能自己手写啦.
愿我们成为真实的自己, 一起加油
来源: http://www.jianshu.com/p/663447254718