前端-后端交互

前端-后端交互(文件从前端上传阿里云OSS)

前端fetch 发送 HTTP 请求:

ES8中提供的新的异步API操作 ,fetch,await async:

​ 在ES8 (ECMAScript 2017) 中,引入了 asyncawait 关键字,这是JavaScript中处理异步操作的一种新方法。这两个关键字旨在简化使用承诺(promises)执行异步操作时的语法。它们帮助开发者以一种更接近同步编程的方式来编写异步代码,从而提高代码的可读性和维护性。

async

async 函数是一种特殊类型的函数,用于定义异步函数,它始终返回一个 Promise 对象。async 函数内部可以使用 await 表达式,这有助于暂停函数的执行,直到等待的 Promise 解决

await

await 关键字用于等待 Promise 解决,并暂停 async 函数的执行,直到 Promise 完成(resolved)。使用 await 可以以一种更线性、更同步的方式编写异步代码,从而避免回调地狱。

前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>基于fetch的上传图片、文件到OSS</title>
    <script>
        function $(id) {
            return document.getElementById(id);
        }
        function reg() {
            let file =$("file").files; //同名的file元素有多个
            //具体流程 第一步
            const formData=new FormData(); // 表示以表单形式构建参数
            // formData.append( "file", file);
            for(let i = 0; i < file.length; i++) {
                formData.append("file"+i, file[i]); // 将文件对象添加到 formData 中
            }
            // 第四步 向后端传数据  , 提交数据到后端
            const postData = async (url, data) => {
                try {
                    const response = await fetch(url, {
                        method: 'POST',
                        //参数 : 因为有图片,文件,所以不能以json格式传数据
                        body: data
                    });
                    // 前后端关键地方  前后端分隔的地方  暂停  等后端处理完前端传的数据  接收来自后端的数据  返回出去
                    const result = await response.json(); //将响应体解析为 JSON 格式
                    return result; //此result是一个包含了jsonmodel的promise对象
                } catch (error) {
                    console.error('Error sending POST request:', error);
                }
            };
            //第二步   设置要调的Servlet 并传一个op判断调用的方法
            const apiUrl = 'FileToOSSText.action?op=regFile';
            //第三步   传递参数
            const pro = postData( apiUrl , formData ); //pro就是执行后的promise对象
            //第五步   接收后端数据  进行判断
            pro.then(jsonobj => {
                if (jsonobj.code == 1) {
                    $("resultdiv").innerHTML = "<b>文件上传成功</b> <br />链接地址:"+jsonobj.obj;
                    $('myImg').src=jsonobj.obj ;
                } else {
                    $("resultdiv").innerHTML = "<b>文件上传失败</b> 原因:" + jsonobj.error;
                }
            });
        }
    </script>
</head>
<body>
    选择需要上传的文件:<input type="file" name="file" id="file" multiple> <br />
    <input type="button"  id="btn" value="上传" onclick="reg()"/>
    <div id="resultdiv"></div>
    <h2>如果是图片则显示在下面:</h2>
    <img src="" id="myImg" width="100px"height="100px">
</body>
</html>

后端Servlet 接收(使用容器 Apache Tomcat)

Java Servlet

Java Servlet 是 Java EE 规范中的一部分,用于处理 Web 请求和响应。你可以编写自己的 Servlet 类来处理来自前端的 HTTP 请求,然后部署到 Servlet 容器(如 Apache Tomcat 或者 Jetty)中运行。

1 接收前端发来的请求,调用doGet()方法,激活regFile()函数

import com.google.gson.Gson;
import com.yc.Servlet.JsonModel;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;

public abstract class BaseServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String op = req.getParameter("op"); //取值 op=regFile
        JsonModel jm = new JsonModel(); //用来保存要运行后的信息  并  返回到前端
        try {
            if (op == null || "".equals(op)) {
                // out.println( "{code:0,error:'没有op参数'}"  );
                jm.setCode(0);
                jm.setError("op参数不能为空..");
                writeJson(jm,resp);
                return;
            }
            ///        反 射
            Method[] methods  = this.getClass().getDeclaredMethods();//取子类中的方法
            for (Method m:methods){
                if (  m.getName().equals(  op  )  ) {  // 判断有没有 regFile方法
                    m.invoke(this, req,  resp);//激活对应函数  regFile
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            jm.setCode(0);
            jm.setError(  e.getMessage()  );
            writeJson(jm,resp);
        }
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");  // 响应流的编码
        resp.setContentType("text/html;charset=utf-8");

        super.service(req, resp);//判断调用doGet()还是doPost()方法
    }

	//***** 最后要执行的函数   返回信息到前端
    //*** 后端传数据到前端  关键地方   ***    以json格式传数据到前端
    protected void writeJson(  JsonModel jm , HttpServletResponse resp) throws IOException {
        resp.setContentType("text/json;charset=utf-8");
        PrintWriter out = resp.getWriter();
        Gson g = new Gson();
        out.println(  g.toJson(  jm  )); ///后端 把 运行情况 以json类型传出到前端
        out.flush();
        out.close();
    }
}

2 对文件进行处理,并传文件信息到上传工具

import com.yc.Servlet.JsonModel;
import com.yc.utils.BaseServlet;
import com.yc.utils.UploadToOSS;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;

@WebServlet("/FileToOSSText.action")
@MultipartConfig(fileSizeThreshold = 1024*1024 , maxFileSize = 1024*1024*5 , maxRequestSize = 1024*1024*5*5)
public class FileToOSSText extends BaseServlet {

    public void regFile(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
        JsonModel jm = new JsonModel();
        Collection<Part> parts = req.getParts(); // 获取所有部分
        try {
            for (Part part : parts) {
                if (part.getContentType() != null) { // 检查部分是否为文件
                    String fileName = part.getSubmittedFileName(); // 获取文件名
                    InputStream fileContent = part.getInputStream(); // 获取文件内容的输入流
                    String url = UploadToOSS.uploadFileOSS( fileName ,  fileContent );//调用上传到OSS的函数
                    if ( "0".equals(url) ){  //上传失败
                        jm.setCode(0);
                        jm.setError("上传失败。。。");
                        super.writeJson( jm , resp );
                        return;
                    }else {     //上传成功
                        jm.setObj(url);
                        jm.setCode(1);
                    }
                }
            }
        } catch (Exception ex) {
            throw new ServletException(ex);
        } finally {
            super.writeJson(jm,resp);
            System.out.println("OSS close Success");
            UploadToOSS.close(); // 最终,无论上传成功还是失败,都关闭OSS客户端实例以释放资源。
        }
    }
}

3 上传文件到阿里云OSS,并返回URL(访问域名)

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import com.aliyuncs.exceptions.ClientException;
import java.io.InputStream;

public class UploadToOSS {

	//OSS客户端实例
    static  OSS ossClient = null;
    
    public static String uploadFileOSS(String fileKey, InputStream inputStream) throws ClientException {
        // 阿里云OSS服务的Endpoint。  服务的访问域名,指定了阿里云OSS服务的网络节点
        String endpoint = "http://oss-cn-beijing.aliyuncs.com";
        // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 你的阿里云OSS存储桶名称。填写Bucket名称,
        String bucketName = "xin-qiu";
        // OSS中的文件键(Key),即上传后的文件名。
//        String fileKey = "qqq.jpg"; // 保存到OSS的文件名
        // 本地系统中的文件路径,用于找到你想上传的文件。
//        String filePath = "C:/Users/DELL/OneDrive/桌面/图片/二次元/qqq.jpg"; // 本地文件路径

        // 使用OSSClientBuilder构建一个OSS客户端实例。
        ossClient = new OSSClientBuilder().build(endpoint,credentialsProvider);

        try {
            // 创建一个文件输入流,用于读取本地文件。
//            FileInputStream inputStream = new FileInputStream(filePath);
            // 调用OSS客户端的putObject方法上传文件。传入存储桶名、文件键和文件输入流。
            ossClient.putObject(bucketName, fileKey, inputStream);
            System.out.println("上传成功");
            //返回出去并保存到数据库 : https://xin-qiu.oss-cn-beijing.aliyuncs.com/cx.png
            return "https:/xin-qiu.oss-cn-beijing.aliyuncs.com/"+fileKey;//上传成功 把 访问域名返回出去
        } catch (Exception e) {
            System.out.println("文件未找到:" + e.getMessage());
            return "0";  //失败返回 0
        }
    }

    public static void close() {
        // 最终,无论上传成功还是失败,都关闭OSS客户端实例以释放资源。
        ossClient.shutdown();
    }
}

4 最后调用BaseServlet类中的 writeJson() 函数把结果以json格式传到前端

	//***** 最后要执行的函数   返回信息到前端
    //*** 后端传数据到前端  关键地方   ***    以json格式传数据到前端
    protected void writeJson(  JsonModel jm , HttpServletResponse resp) throws IOException {
        resp.setContentType("text/json;charset=utf-8");
        PrintWriter out = resp.getWriter();
        Gson g = new Gson();
        out.println(  g.toJson(  jm  )); ///后端 把 运行情况 以json类型传出到前端
        out.flush();
        out.close();
    }

保存运行情况类

import lombok.Data;
import java.io.Serializable;

@Data
public class JsonModel implements Serializable {
    private Integer code;  //响应码  :  0:表示失败  1:表示成功
    private Object obj;
    private String error;
}

需要的依赖

	<dependency>
      <groupId>org.apache.tomcat.embed</groupId>
      <artifactId>tomcat-embed-core</artifactId>
      <version>9.0.80</version>
    </dependency>

    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.30</version>
    </dependency>

    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.9.0</version>
    </dependency>

    <dependency>
      <groupId>com.aliyun.oss</groupId>
      <artifactId>aliyun-sdk-oss</artifactId>
      <version>3.1.0</version>
    </dependency>

没上传文件前的前端界面

在这里插入图片描述

上传后的前端界面

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值