Java 实现SharePoint文件操作-站点下文件获取、文件上传

本文介绍了如何在SharePoint中通过OAuth授权获取文件,包括使用FormDigestValue进行安全验证,以及如何使用RESTfulAPI上传文件,涉及yml配置、HTTP请求和文件操作技术。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

业务需求介绍:
用户会在SharePoint具体站点创建分类文件,开发人员需要在不同文件夹下获取文件并实现上传。
前置条件:具体的站点需要有权限的用户名密码授权访问。

一、SharePoint介绍

精心规划和执行的信息体系结构是智能和高性能 Intranet、中心或网站的先决条件。
规划有效信息体系结构最重要的第一步是了解用户,并帮助他们找到以对他们最有意义的方式完成任务所需的内容。

信息体系结构还有助于提高用户采用率、满意度和工作效率,同时降低 IT 成本,减少信息过载,并最大程度地降低合规性和安全风险。

官网介绍:https://learn.microsoft.com/zh-cn/sharepoint/information-architecture-modern-experience

二、获取文件数据

1. yml配置

sharepoint:
  auth:
    username: 授权了的用户账号
    password: 用户账号密码
    siteUrl: 服务器URL
    domain: 域地址

2. 配置类兼工具类

定义授权 getAuthenticatedResponse 方法,根据具体情况获取FormDigestValue

@ConfigurationProperties(prefix = "sharepoint.auth")
@Getter
@Setter
@Configuration
public class SharePointUtils {

    private String username;
    private String password;
    private String siteUrl;
    private String domain;

	// 授权
	public String getAuthenticatedResponse(final String urlStr, final String domain, final String userName, final String password) throws IOException {
        StringBuffer response = new StringBuffer();
        Authenticator.setDefault(new Authenticator() {
            @Override
            public PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(domain + "\\" + userName, password.toCharArray());
            }
        });
        URL urlRequest = new URL(urlStr + "/_api/contextinfo");
        //获取contextinfo
        HttpURLConnection contextInfoRequest = (HttpURLConnection) urlRequest.openConnection();
        contextInfoRequest.setRequestProperty("Content-Type", "application/json;odata=verbose");
        contextInfoRequest.setRequestProperty("Accept", "application/json;odata=verbose");
        contextInfoRequest.setRequestProperty("Connection", "Keep-Alive");
        contextInfoRequest.setDoOutput(true);
        contextInfoRequest.setDoInput(true);
        contextInfoRequest.setRequestMethod("POST");
        contextInfoRequest.connect();

        OutputStream out = contextInfoRequest.getOutputStream();
        out.flush();
        InputStream in = contextInfoRequest.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        String str = "";
        while ((str = br.readLine()) != null) {
            response.append(str);
        }

        String returnValue = new String(response);

        Map jobj = JSONUtil.toBean(returnValue, Map.class);
        //获取第一层
        Map A1 = (Map) jobj.get("d");
        //System.err.println("A1:"+A1);
        //获取第二层
        Map A2 = (Map) A1.get("GetContextWebInformation");
        //System.err.println("A2:"+A2);
        //获取第三层
        Object A3 = A2.get("FormDigestValue");
        System.err.println("A3:" + A3.toString());
        out.close();
        in.close();
        return A3.toString();
    }
}

这里对其做出介绍:

为什么需要这个FormDigestValue?
在SharePoint中进行数据修改时,必须包含FormDigest控件来为安全验证创建digest。它主要基于当前的用户、站点和时间在页面中添加一个安全标示(security token),一旦页面post back回到SharePoint Server上,这个安全标示会被验证。
这个安全标示一旦创建出来,它只在一个可设置的时间段是有效的。由于安全问题,Microsoft SharePoint Foundation不允许从一个Web application往回Post数据来修改存储在数据库中的数据,除非在发送这个Post请求时在页面中包含了安全验证。
大白话:类似于token,这个就是鉴权的
这里的大致长这个样子:A3:
0x569F150668434DF0D75463ED8421570D2256F14632892CD77D878ECE89E37BF46A9A685627EF432B734750EE9CB62C8A45CEBF96BF589EF59F7C4A……,24 Oct 2023 02:29:03 -0000

3. 获取具体文件下数据
该业务场景为获取具体流程对应活动下的模板数据,所以文件夹只有两层,具体情况做相应调整。

public List<SharePointResultDTO> getTemplateData(String process, String activity) {
    HttpURLConnection connection = null;
    try {
        String apiUrl;
        if (StringUtils.isNotEmpty(process) && StringUtils.isNotEmpty(activity)) {
            apiUrl = siteUrl + "/_api/web/GetFolderByServerRelativeUrl('[相应的站点地址,如果有中文需要进行统一编码,否则会报错]" + URLEncoder.encode(process, "UTF-8") + "/" + URLEncoder.encode(activity, "UTF-8") + "')/files";
        } else {
            apiUrl = siteUrl + "/_api/web/GetFolderByServerRelativeUrl('[相应的站点地址,如果有中文需要进行统一编码,否则会报错]')/files";
        }
        URL url = new URL(apiUrl);
        CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestProperty("Content-Type", "application/json;odata=verbose");//请求头中设置ContentType对应值
        connection.setRequestProperty("Accept", "application/json;odata=verbose");//请求头中设置Accept对应值
        connection.setRequestProperty("X-RequestDigest", getAuthenticatedResponse(siteUrl, domain, username, password));
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setRequestMethod("GET");
        Authenticator.setDefault(new Authenticator() {
            @Override
            public PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(domain + "\\" + username, password.toCharArray());
            }
        });
        connection.connect();
        BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        String inputLine;
        StringBuilder response = new StringBuilder();
        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();
        if (StringUtils.isNotEmpty(response)) {
            ArrayList<SharePointResultDTO> sharePointResultDTOS = new ArrayList<>();
            //对获取到的数据进行相应的解析 …………
            return sharePointResultDTOS;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

若出现数据为空或者出现 "Unable to excute HTTP request: Permission denied: connect"等错误,可能是网络原因,浏览器尝试通过对应账号密码访问到对应的目录文件下然后再尝试。

4. 结果展示
在这里插入图片描述

三、上传文件

1. 获取文件字节流

    /**
     * 获取本地文件,将文件转为byte[]
     */
    public static byte[] getBytes(String filePath) throws IOException {

        File file = new File(filePath);
        FileInputStream fis = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
        try {
            fis = new FileInputStream(file);
            //创建个字节数组,给定长度为1000
            byte[] byteArr = new byte[1000];
            int n;
            //进行循环读取文件内容,当read返回值为-1的时候,表示文件读取完毕,就可以显示文件内容
            //读取到的字节全部放入到指定的字节数组byteArr 返回每次填充给bytes数组的长度
            while ((n = fis.read(byteArr)) != -1) {
                //将指定的字节数组写入文件
                bos.write(byteArr, 0, n);
            }
            return bos.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                fis.close();
            }
            bos.close();
        }
        return null;
    }

    //获取链接地址文件的byte数据
    public byte[] getUrlFileData(String fileUrl) throws Exception {
        // 文件做相应处理,获取可以下载到的文件链接,有中文需要进行编码处理
        // ……
        URL url = new URL(fileUrl);
        CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestProperty("Content-Type", "application/json;odata=verbose");//请求头中设置ContentType对应值
        connection.setRequestProperty("Accept", "application/json;odata=verbose");//请求头中设置Accept对应值
        connection.setRequestProperty("X-RequestDigest", getAuthenticatedResponse(siteUrl, domain, username, password));
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setRequestMethod("GET");
        Authenticator.setDefault(new Authenticator() {
            @Override
            public PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(domain + "\\" + username, password.toCharArray());
            }
        });
        connection.connect();
        InputStream cin = connection.getInputStream();
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[4096];
        int len = 0;
        while ((len = cin.read(buffer)) != -1) {
            outStream.write(buffer, 0, len);
        }
        byte[] fileData = outStream.toByteArray();
        cin.close();
        outStream.close();
        return fileData;
    }

2. 上传文件

public SharePointResultDTO postFileByRestful(byte[] buffer, String fileName) {
        HttpURLConnection connection = null;
        BufferedReader reader = null;
        InputStream is = null;
        OutputStream out = null;
        try {
            StringBuffer sbf = new StringBuffer();
            String strRead = null;
            String allurl = siteUrl + "/_api/web/GetFolderByServerRelativeUrl('[相应的站点地址,如果有中文需要进行统一编码,否则会报错]')/files/add(url='" + URLEncoder.encode(fileName, "UTF-8") + "',overwrite=true)";
            URL url = new URL(allurl);
            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestProperty("Content-Type", "application/json;odata=verbose");//请求头中设置ContentType对应值
            connection.setRequestProperty("Accept", "application/json;odata=verbose");//请求头中设置Accept对应值
            connection.setRequestProperty("Content-Length", String.valueOf(buffer.length));//请求中携带参数的长度
            connection.setRequestProperty("X-RequestDigest", getAuthenticatedResponse(siteUrl, domain, username, password));
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setRequestMethod("POST");
            Authenticator.setDefault(new Authenticator() {
                @Override
                public PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(domain + "\\" + username, password.toCharArray());
                }
            });
            connection.connect();
            out = connection.getOutputStream();
            out.write(buffer, 0, buffer.length);
            out.flush();

            connection.setInstanceFollowRedirects(false);
            is = connection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
            while ((strRead = reader.readLine()) != null) {
                sbf.append(strRead);
            }
            reader.close();
            is.close();
            out.close();
            connection.disconnect();
            // 将获取数据进行json解析,封装自己需要返回的数据 …………
            return sharePointResultDTO;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

3. 结果展示
在这里插入图片描述

写在最后:今天是1024,祝大家和自己程序员节日快乐,一起进步一起变好!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值