Axios+SSM上传和获取图片

Axios+SSM上传和获取图片,第1张

Axios+SSM上传和获取图片 图片上传FormDataFornData添加键值对数据Blob数据类型form表单的enctype属性form表单Ajax+FormData文件上传基于Servlet的后端解析 Axios+Element UI引入el-upload组件el-upload事件处理与Axios文件上传SSM后端接口编写Mapper接口与XML文件Service接口与实现子类Controller层与结果响应 图片获取基于Servlet的图片请求Servlet代码编写前端代码编写 基于Axios的图片请求SSM后端代码编写Controller层接口与byte[]类型结果响应Axios前端请求与数据解析

图片上传

    前端工程中,文件上传 *** 作需要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 = 'hey!'; // 新文件的正文
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表单

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


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事件处理与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


基于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)
        })

    至此,图片上传和获取就基本完成了。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/990574.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)