Spring Boot WebDavにファイルを書き込む

Spring Boot

この記事では、JavaのSpring Bootを利用してWebDavにファイルを書き込む方法を書いていきます。
それと一緒に、書き込むフォルダが存在するかや、フォルダが存在しなければ作成する方法も一緒に解説します。

JavaLearning

よく利用する処理を書き出す

WebDavサーバの情報を保持するオブジェクトクラスを作成する

オブジェクトクラスにWebDavのURLや、認証のためのユーザーやパスワードを持たせておきます。

package com.example;

public class WebDavServerObject {
    
    private Integer davId;
    private String davName;
    private String davUrl;
    private String davUserId;
    private String davUserPass;



    public Integer getDavId() {
        return this.davId;
    }

    public void setDavId(Integer davId) {
        this.davId = davId;
    }

    public String getDavName() {
        return this.davName;
    }

    public void setDavName(String davName) {
        this.davName = davName;
    }

    public String getDavUrl() {
        return this.davUrl;
    }

    public void setDavUrl(String davUrl) {
        this.davUrl = davUrl;
    }

    public String getDavUserId() {
        return this.davUserId;
    }

    public void setDavUserId(String davUserId) {
        this.davUserId = davUserId;
    }

    public String getDavUserPass() {
        return this.davUserPass;
    }

    public void setDavUserPass(String davUserPass) {
        this.davUserPass = davUserPass;
    }
}

認証情報を作成する

WebDavを利用する際には、Basic認証が必要になることがよくあります。
その場合認証情報を作成するメソッドは、よく利用するのであらかじめ書き出しておきます。

// 認証情報作成
private static String getAuthorizationString(String username, String password) {
    String userpass = username + ":" + password;
    return Base64.getEncoder().encodeToString(userpass.getBytes());
}

ファイルやフォルダが存在するかを確認する

WebDav内のファイルやフォルダの存在を確認するメソッドもよく利用するのであらかじめ書き出しておきます。

// WebDavフォルダの存在確認
private static boolean checkWebDavFolderExistence(String webdavUrl, String username, String password) {
    try {
        URL url = new URL(webdavUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("HEAD");
        connection.setRequestProperty("Authorization", "Basic "
            + getAuthorizationString(username, password));
        int responseCode = connection.getResponseCode();
        connection.disconnect();
        return responseCode == HttpURLConnection.HTTP_OK;
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    }
}

フォルダが存在しない場合は作成する

WebDav内にフォルダが存在しない場合はフォルダを作成するので、何度も利用するメソッドではありませんが、プログラムが冗長にならないように書き出します。
また、あらかじめ書き出しておくことによって、これから作るプログラムの中で同じような処理が必要になった場合に楽ができます。

// フォルダが存在しない場合は作成する
private boolean createFolderIfNotExists( WebDavServerObject davServer) throws IOException {

    String webdavServerUrl = davServer.getDavUrl() + "/folderPath/";

    URL url = new URL(webdavServerUrl);
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setRequestMethod("PUT");
    connection.setDoOutput(false);
    connection.setRequestProperty("Authorization", "Basic "
        + getAuthorizationString(davServer.getDavUserId(), davServer.getDavUserPass()));
    connection.setRequestProperty("Content-Type", "application/octet-stream");
    connection.setRequestProperty("Content-Length", "0");
    connection.setUseCaches(false);
    connection.setInstanceFollowRedirects(false);

    int responseCode = connection.getResponseCode();
    connection.disconnect();
    if (responseCode == 201 || responseCode == 204) {
        return true;
    } else if (responseCode == 405) {
        // フォルダが既に存在する場合
        return true;
    } else {
        return false;
    }
}

WebDavにファイルを書き込む

あらかじめ作っておいたメソッドを利用しながら、WebDavに書き出すプログラムを書きます。
戻り値はHTTPのレスポンスコードを返却するのがおすすめです。
WebDavの場合、認証情報が正しくないためファイルが書き込めない可能性があります。
その場合はレスポンスコード「403」が返却されるのでわかりやすくなります。

public Integer writeFile4WebDav(MultipartFile file, WebDavServerObject davServer) throws IOException {

    // フォルダの存在を確認
    String webdavServerUrl = davServer.getDavUrl() + "/folderPath/";
    if (!checkWebDavFolderExistence(webdavServerUrl, davServer.getDavUserId(), davServer.getDavUserPass())) {
        // フォルダ作成
        createFolderIfNotExists(davServer);
    }

     // ファイルの存在を確認
    webdavServerUrl = davServer.getDavUrl() + "/folderPath/" + file.getOriginalFilename();
    if (checkWebDavFolderExistence(webdavServerUrl, davServer.getDavUserId(), davServer.getDavUserPass())) {
        throw new IOException("the same file exists.");
    }

    URL url = new URL(webdavServerUrl);
    HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();
    httpUrlConnection.setRequestProperty("Authorization", "Basic "
        + getAuthorizationString(davServer.getDavUserId(), davServer.getDavUserPass()));
    httpUrlConnection.setRequestMethod("PUT");
    httpUrlConnection.setRequestProperty("Content-Type", file.getContentType());
    httpUrlConnection.setRequestProperty("Content-Length", String.valueOf(file.getSize()));
    
    httpUrlConnection.setDoOutput(true);
    OutputStream outputStream = httpUrlConnection.getOutputStream();
    outputStream.write(file.getBytes());
    outputStream.flush();
    outputStream.close();

    return httpUrlConnection.getResponseCode();
}

今まで紹介したメソッドは、WebDavサーバの情報を保持するオブジェクトクラス意外全てをサービスクラスに記載します。
全てをまとめると、サービスクラスは以下のようになります。

package com.example;

import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Base64;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.example.WebDavServerObject;


@Service
public class WebdavFileManagementService {

public Integer writeFile4WebDav(MultipartFile file, WebDavServerObject davServer) throws IOException {

    // フォルダの存在を確認
    String webdavServerUrl = davServer.getDavUrl() + "/folderPath/";
    if (!checkWebDavFolderExistence(webdavServerUrl, davServer.getDavUserId(), davServer.getDavUserPass())) {
        // フォルダを作成
        createFolderIfNotExists(davServer);
    }

    // ファイルの存在を確認
    webdavServerUrl = davServer.getDavUrl() + "/folderPath/" + file.getOriginalFilename();
    if (checkWebDavFolderExistence(webdavServerUrl, davServer.getDavUserId(), davServer.getDavUserPass())) {
        throw new IOException("the same file exists.");
    }

    URL url = new URL(webdavServerUrl);
    HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();
    httpUrlConnection.setRequestProperty("Authorization", "Basic "
        + getAuthorizationString(davServer.getDavUserId(), davServer.getDavUserPass()));
    httpUrlConnection.setRequestMethod("PUT");
    httpUrlConnection.setRequestProperty("Content-Type", file.getContentType());
    httpUrlConnection.setRequestProperty("Content-Length", String.valueOf(file.getSize()));
    
    httpUrlConnection.setDoOutput(true);
    OutputStream outputStream = httpUrlConnection.getOutputStream();
    outputStream.write(file.getBytes());
    outputStream.flush();
    outputStream.close();

    return httpUrlConnection.getResponseCode();
}


// 認証情報作成
private static String getAuthorizationString(String username, String password) {
    String userpass = username + ":" + password;
    return Base64.getEncoder().encodeToString(userpass.getBytes());
}


// WebDavフォルダの存在確認
private static boolean checkWebDavFolderExistence(String webdavUrl, String username, String password) {
    try {
        URL url = new URL(webdavUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("HEAD");
        connection.setRequestProperty("Authorization", "Basic "
            + getAuthorizationString(username, password));
        int responseCode = connection.getResponseCode();
        connection.disconnect();
        return responseCode == HttpURLConnection.HTTP_OK;
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    }
}


// フォルダが存在しない場合は作成する
private boolean createFolderIfNotExists( WebDavServerObject davServer) throws IOException {

    String webdavServerUrl = davServer.getDavUrl() + "/folderPath/";

    URL url = new URL(webdavServerUrl);
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setRequestMethod("PUT");
    connection.setDoOutput(false);
    connection.setRequestProperty("Authorization", "Basic "
        + getAuthorizationString(davServer.getDavUserId(), davServer.getDavUserPass()));
    connection.setRequestProperty("Content-Type", "application/octet-stream");
    connection.setRequestProperty("Content-Length", "0");
    connection.setUseCaches(false);
    connection.setInstanceFollowRedirects(false);

    int responseCode = connection.getResponseCode();
    connection.disconnect();
    if (responseCode == 201 || responseCode == 204) {
        return true;
    } else if (responseCode == 405) {
        // フォルダが既に存在する場合
        return true;
    } else {
        return false;
    }
}
}

コントローラークラスから呼び出す

WebDavに書き込むメソッドを呼び出すコントローラークラスを作成します。
ブラウザなどからファイル書き込みの命令を受け取るのは、このコントローラークラスになります。

package com.example;

import java.io.IOException;
import java.net.HttpURLConnection;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import com.example.WebDavServerObject;

@RestController
public class WebdavFileManagementController {

    @Autowired
    private WebdavFileManagementService webdavFileManagementService;

    @PostMapping("/upload")
    public Integer uploadFile(
        @RequestParam("file") MultipartFile file
    ,   HttpServletRequest request
    ) {
        // 適切にWebDavServer情報を取得するよう書き換えてください
        WebDavServerObject davServer = new WebDavServerObject();

        try {
            return webdavFileManagementService.writeFile4WebDav(file, davServer);
        } catch (IOException e) {
            e.printStackTrace();
            return 500;
        }
    }
}

まとめ

今回は、WebDavにファイルを書き込む方法を解説しました。
他にもWebDavに関する以下の記事を公開していますので、よろしければそちらもご覧ください。

それでは〜。

コメント

タイトルとURLをコピーしました