IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Axios+SSM上传和获取图片 -> 正文阅读

[移动开发]Axios+SSM上传和获取图片

图片上传

????前端工程中,文件上传操作需要FormData对象的支持;而后端解析则是需要MultipartFile类的支持。

FormData

????FormData对象用以将数据编译成键值对,主要用于发送表单数据,但是也可用来发送带键数据(keyed data),而独立于表单使用。而如果enctype属性设置为multipart/form-data,就可以通过form表单的submit()方法来上传数据了。

FornData添加键值对数据

????FormData提供了append()方法,可以用来添加将要上传的数据,这些数据可以是普通文本数据,也可以是二进制流数据(例如:Blob类型)。

ar formData = new FormData();

formData.append("username", "Groucho");
formData.append("accountnum", 123456); //数字123456会被立即转换成字符串 "123456"

// HTML 文件类型input,由用户选择
formData.append("userfile", fileInputElement.files[0]);

// JavaScript file-like 对象
var content = '<a id="a"><b id="b">hey!</b></a>'; // 新文件的正文
var blob = new Blob([content], { type: "text/xml"});
//添加Blob对象
formData.append("webmasterfile", blob);

var request = new XMLHttpRequest();
request.open("POST", "http://foo.com/submitform.php");
request.send(formData);

Blob数据类型

????Blob对象表示一个不可变、原始数据的类文件对象,而且Blob是File文件类型的“父级接口”,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。
????Blob类型的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作。

form表单的enctype属性

????利用form表单可以提交用户基本信息,此时:enctype采用默认值:application/x-www-form-urlencoded。
????当form表单包含type=file的input文件上传控件时,enctype的值就必须要指定为multipart/form-data了,虽然原则上来讲,它仍然具有表单提交基本字符串数据的功能。
????在使用FormData上传文件时,需要在表单中添加一个文件类型input。例如:

<form enctype="multipart/form-data" method="post" name="fileinfo">
  <label>Your email address:</label>
  <input type="email" autocomplete="on" autofocus name="userid" placeholder="email" required size="32" maxlength="64" /><br />
  <label>Custom file label:</label>
  <input type="text" name="filelabel" size="12" maxlength="32" /><br />
  <label>File to stash:</label>
  
  <input type="file" name="file" required />
  
  <input type="submit" value="Stash the file!" />
</form>
<div></div>

form表单

????如下HTML代码片段,enctype属性被指定为multipart/form-data,可用于上传文件。

<form enctype="multipart/form-data" id="student_award_form">
                        <div class="form-row">
                            <div class="form-group col-md-6">
                                <label for="awardlunit">颁奖单位</label>
                                <input type="text" class="form-control" id="awardlunit"
                                       name="unit" placeholder="例如:单位A,单位B" disabled>
                                <small id="emailHelp" class="form-text text-muted"> 若有多个单位名称-请以
                                    <span class="text-primary">逗号 ','</span> 分隔</small>
                            </div>
                            <div class="form-group col-md-6">
                                <label for="evidence">实证文件</label>
                                <input type="file" class="form-control" id="evidence"
                                       accept="application/pdf" name="evidence" placeholder="" disabled>
                                <small id="emailHelp"
                                       class="form-text text-muted">若有多个文件,请合并后上传-<span
                                        class="text-primary">[文件类型:*.pdf]</span></small>
                            </div>
                        </div>
                        <div class="row">
                            <div class="col">
                                <button type="button"
                                        class="btn btn-success btn-lg btn-block" id="btn_student_award_uploadlater"
                                        οnclick="uploadLater('student_award')">稍后上报
                                </button>
                                <small
                                        id="emailHelp" class="form-text text-muted"><span
                                        class="text-info">选择稍后上报,将为您记录本次填写的上报信息,之后仍可继续上报</span></small>
                            </div>
                            <div class="col">
                                <button type="button"
                                        class="btn btn-success btn-lg btn-block" id="btn_student_award_upload" οnclick="uploadRightNow('student_award')">立即上报
                                </button>
                                <small
                                        id="emailHelp"
                                        class="form-text text-muted">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                                    <input
                                        class="form-check-input" type="checkbox" id="gridCheck_student_award">上报前请确认:
                                    <span
                                        class="text-danger">当前账户与实际上报人一致,否则会导致信息错乱!</span>
                                </small>
                            </div>
                        </div>

                    </form>

Ajax+FormData文件上传

   /**
     * 上传文件与参数信息
     * @param url 请求链接
     * @param idSelector id选择器
     * @param paramsValue 参数值信息
     * */
    function uploadFile(url,idSelector,paramsValue) {
        //照片-img-id=basic_userPhoto
        var filePath=$(idSelector)[0].value;//获取文件路径
        var fileObj=$(idSelector)[0].files[0];//获取文件对象
        if (filePath){
            //获取文件后缀名
            var postfix=filePath.substring(filePath.lastIndexOf(".")+1)
            if(postfix&&fileObj&&(postfix=="pdf")){
                //使用FileReader解析
                var pdfFile = $(idSelector)[0].files[0];
                //提交文件路径到服务器端程序
                var formData = new FormData();
                console.log(paramsValue);
                formData.append("evidencfile",fileObj);
                formData.append("params",JSON.stringify(paramsValue));
                $.ajax({
                    url: url,
                    method: "POST",
                    async: true,
                    data: formData,
                    processData:false,
                    contentType:false,
                    dataType: "json",
                    success: function (result, status, xhr) {
                        // console.log("响应信息")
                        console.log(result)
                        if(result){
                            alert(result.message)
                            //禁用稍后上传菜单
                            $("#btn_student_award_uploadlater").attr("disabled",true);
                            $("#btn_student_award_upload").attr("disabled",true);
                            $("#btn_teacTest_award_uploadlater").attr("disabled",true);
                            $("#btn_teacTest_award_upload").attr("disabled",true);
                        }

                    }
                })
            }else{
                alert("仅支持pdf文件类型!")
            }
        }
    }

基于Servlet的后端解析

????基于Servlet的传统开发模式,可以引入第三方jar包,来支持文件上传之后的解析功能开发。
在这里插入图片描述
????上传文件解析代码截取如下,

/**
     * 上传用户头像信息
     * @param request
     * @return
     */
    private Result uploadUserPhoto(HttpServletRequest request) {
        //获取session对象
        HttpSession session = request.getSession();
        //获取当前登录用户
        User user = (User) session.getAttribute("login_user");
        Result result = null;
        //判断是否为文件上传请求
        boolean multipartContent = ServletFileUpload.isMultipartContent(request);
        System.out.println("isMultipartContent=" + multipartContent);
        if (multipartContent) {
            //创建文件上传处理对象
            ServletFileUpload upload = new ServletFileUpload();
            try {
                //转换request请求
                FileItemIterator itemIterator = upload.getItemIterator(request);
                if (itemIterator.hasNext()) {
                    //获取文件项目
                    FileItemStream next = itemIterator.next();
                    //获取请求字段名称
                    String fieldName = next.getFieldName();
                    //获取流对象
                    InputStream inputStream = next.openStream();
                    System.out.println("inputStream=" + inputStream);
                    System.out.println("next.isFormField()=" + next.isFormField());
                    //解析流对象
                    long rows = userDetailService.uploadPhoto(user.getUsername(), inputStream);
                    System.out.println("rows=" + rows);
                    if (rows > 0) {
                        result = Result.ok("设置成功!");
                    } else {
                        result = Result.error("设置失败!");
                    }
                }else {
                    result = Result.error("设置失败!");
                }
            } catch (FileUploadException | IOException e) {
                e.printStackTrace();
                result = Result.error("设置失败!");
            }
        } else {
            result = Result.error("设置失败!");
        }
        return result;
    }

Axios+Element UI

????通过Element UI提供的el-upload组件,结合Axios实现文件上传。通常需要:

引入el-upload组件

 <el-upload
                class="avatar-uploader"
                action="https://jsonplaceholder.typicode.com/posts/"
                multiple
                :show-file-list="false"
                :on-preview="handlePictureCardPreview"
                :on-success="handleAvatarSuccess"
                :before-upload="beforeAvatarUpload"
              >
                <img
                  v-if="imageUrl"
                  :src="imageUrl"
                  style="width: 200px; height: 250px"
                  class="avatar"
                />
                <i v-else class="el-icon-plus avatar-uploader-icon"></i>
              </el-upload>

el-upload事件处理与Axios文件上传

handleAvatarSuccess(res, file, fileList) {
      this.imageUrl = URL.createObjectURL(file.raw)
      //获取文件对象
      let imgFile = file.raw
      console.log(imgFile)
      if (imgFile) {
        //将文件转换为formdata
        let formData = new FormData()
        let email = localStorage.getItem('email')
        formData.append('photo', imgFile) //将文件放入formdata对象
        formData.append('email', email)//放入文本键值对
        console.log(formData)
        //开始上传文件
        this.$axios({
          url: 'http://localhost:8010/stasys_v3/userDetail/POST/update/photo',
          method: 'POST',
          data: formData,
        })
          .then((res) => {
            console.log(res)
            if (res.data && res.data == 1) {
              //头像更新成功
              this.$message({
                message: '照片更新成功!',
                type: 'success',
              })
            }
          })
          .catch((err) => {
            console.log(err)
            //更新失败
            this.$message.error('照片更新失败!')
          })
      } else {
        //更新失败
        this.$message.error('照片更新失败!')
      }
    },
    handlePictureCardPreview(file) {
      // console.log(file)
    },
    //预处理
    beforeAvatarUpload(file) {
      const isJPG = file.type === 'image/jpeg'
      const isLt2M = file.size / 1024 / 1024 < 2
      if (!isJPG) {
        this.$message.error('上传头像图片只能是 JPG 格式!')
      }
      if (!isLt2M) {
        this.$message.error('上传头像图片大小不能超过 2MB!')
      }
      //上传头像至服务器
      let fd = new FormData()
      let email = localStorage.getItem('email')
      fd.append('photo', file) //添加图片
      fd.append('email', email) //邮箱参数
      return isJPG && isLt2M
    },

SSM后端接口编写

????SSM框架整合操作就不写了。下面是Mapper、Service、Controller层的代码。其中要被操作的字段是以Blob类型存储在数据库中的。
在这里插入图片描述

Mapper接口与XML文件

  <update id="updatePhoto" >
        UPDATE tb_user_detail SET photo = #{photo}
        WHERE userid = #{email}
    </update>
  /**
     * 更新头像
     * @param email
     * @param photo
     * @return
     */
    public abstract Integer updatePhoto(@Param(value = "email")String email,
                                        @Param(value = "photo")byte[] photo);

Service接口与实现子类

	//service接口中抽象方法定义
   public interface UserDetailService {
		   /**
		     * 更新头像
		     * @param email
		     * @param photo
		     * @return
		     */
		    public abstract Integer updatePhoto(String email,byte[] photo);
    }
  public interface UserDetailServiceImpl implements  UserDetailService {
		//properties
	    @Autowired
	    private UserDetailMapper mapper;
		//methods
		  @Override
		    public Integer updatePhoto(String email, byte[] photo) {
		        return mapper.updatePhoto(email,photo);
		    }

Controller层与结果响应

@Controller(value = "userDetailController")
@RequestMapping(value = "/userDetail")
public class UserDetailController {
    //properties
    @Autowired
    @Qualifier(value = "userDetailServiceImpl")
    private UserDetailService userDetailService;
	
	//methods
	@RequestMapping(value = "/POST/update/photo")
    @ResponseBody
    public Integer updateUserPhoto(@RequestParam("photo")MultipartFile photo,
                                  @RequestParam("email")String email){
        byte[] bytes = null;
        InputStream inputStream = null;
        //接收文件
        try {
            //转换为二进制byte数组
            inputStream = photo.getInputStream();
            //获取二进制流文件的字节数
            int available = inputStream.available();
            bytes= new byte[available];
            //读取二进制字节到byte[]数组
            int read = inputStream.read(bytes);
            inputStream.close();
            //更新UserDetail信息
            //判断用户是否存在
            if (userDetailService.selectOne(email)==null){
            	//不存在则先增加用户记录
                UserDetail userDetail=new UserDetail();
                userDetail.setUserid(email);
                userDetailService.insertOne(userDetail);
            }
            //更新头像信息
            Integer rows= userDetailService.updatePhoto(email, bytes);
            return rows;
        } catch (IOException e) {
            e.printStackTrace();
            return 0;
        }
    }

}

图片获取

????SSM+Vue+Axios+Element UI开发时,文件下载操作:可以将从数据库中读取Blob字段值,编写Mapper接口与XML配置文件,将其自动转换为byte[]字节数组,将其直接返回给前端;最终在前端利用Axios进行解析。

基于Servlet的图片请求

????传统Servlet开发模式中,可以将从数据库中读取到的byte[]数组,转换为InputStream输入流,通过二进制输入流,配合HttpServletResponse对象的OutputStream对象,将其写出。然后在前端修改img的src属性为后端接口名称,即可实现图片的回显操作。

Servlet代码编写

????部分代码截取如下,

  /*
    * 获取用户图像
    * */
    private void responseUserPhoto(HttpServletRequest req,HttpServletResponse resp) throws IOException {
        //获取当前登录用户
        HttpSession session = req.getSession();
        User user = (User) session.getAttribute("login_user");
        InputStream inputStream = userDetailService.downloadPhoto(user.getUsername());
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");
        //判断是否获取成功
        if (inputStream==null){
            PrintWriter writer = resp.getWriter();
            writer.write(JSON.toJSONString(Result.error("获取头像失败!")));
            writer.flush();
            writer.close();
            return;
        }
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("image/jpeg;charset=UTF-8");
        OutputStream outputStream = resp.getOutputStream();
        byte[] buff=new byte[1024];
        int len = -1;
        //输出图像
        while ((len=inputStream.read(buff))!=-1){
            outputStream.write(buff,0,len);
        }
        //关闭流对象
        outputStream.flush();
        outputStream.close();
        if (inputStream!=null)
            inputStream.close();
    }

前端代码编写

????部分代码截取如下,

假设后端接口为:http://localhost:8010/stasys_v2/get/userphoto.do

<img
       class="rounded-circle mb-3 mt-4" src="http://localhost:8010/stasys_v2/get/userphoto.do"
        width="160" height="160"
        id="basic_userPhoto">

基于Axios的图片请求

SSM后端代码编写

????Mapper接口与XML中SQL语句编写、Service与子类实现没什么特殊的,只给出Controller接口。

Controller层接口与byte[]类型结果响应

@Controller(value = "userDetailController")
@RequestMapping(value = "/userDetail")
public class UserDetailController {
	@RequestMapping("/GET/userdetailphoto")
    @ResponseBody
    public byte[] getPhoto(@RequestParam(value = "email") String email) {
        UserDetail userDetail = userDetailService.selectJoin(email);
        byte[] photo = userDetail.getPhoto();
        return photo;
    }
}

Axios前端请求与数据解析

	//获取用户照片
      axios({
        url: 'http://localhost:8010/stasys_v3/userDetail/GET/userdetailphoto',
        method: 'GET',
        params: { email: "参数值" },
        responseType: 'arraybuffer',
      })
        .then((response) => {
          //解析响应对象
          console.log(response)
          this.imageUrl =
            'data:image/png;base64,' +
            btoa(
              new Uint8Array(response.data).reduce(
                (data, byte) => data + String.fromCharCode(byte),
                ''
              )
            )
        })
        .catch((error) => {
          console.log(error)
        })

????至此,图片上传和获取就基本完成了。
在这里插入图片描述

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-03-15 22:41:49  更:2022-03-15 22:42:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 17:56:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码