読者です 読者をやめる 読者になる 読者になる

google cloud storage ファイル削除 【google app engine for java】

アプリからバケット内のファイルを削除するための実装を記載します。
本投稿では実装方法のみ。アプリからGCSへのアクセスの仕組みや、ソースの解説はまた今度。

目次
①前提条件
②必要なjarを取得、ビルドパスを設定
③実装(ソース)


①前提条件
 以下の設定が行われていること。
 ・webの管理コンソールから課金設定を有効にする
  https://console.cloud.google.com/
 ・バケットを作成する
 ・作成したバケットにファイルを格納する


②必要なjarのビルドパスを設定
 1.以下のjarを取得する
 ---
 ・google-api-client-1.21.0.jar
 ・google-http-client-1.21.0.jar
 ・google-http-client-jackson2-1.21.0.jar
 ・google-api-services-storage-v1-rev88-1.22.0.jar
 ---
 ※mavenリポジトリーからダウンロード
  http://mvnrepository.com/

 2.ビルドパスを設定
  /プロジェクト名/war/WEB-INF/lib配下に配置して、
  プロジェクトを右クリック → javaのビルド・パス → jar追加をクリック
  配置したjarを選択しOK


③実装(ソース)

	// GCS ファイル削除処理
	boolean deleted;
	try {
		for (int i = 0; i < 1; i++) {
			// バケット名, xx/xx.jpeg 先頭に/は不要
			deleteFile(BUCKET_NAME, fileNames);
		}
		deleted = true; // 削除成功
	} catch (Exception e) {
		deleted = false; // 削除失敗
		e.printStackTrace();
	}
	private static void deleteFile(String bucketName, String fileName)
			throws Exception {

		Storage storage = getStorage();

		storage.objects().delete(bucketName, fileName).execute();
	}
	private static Storage getStorage() throws Exception {

		if (storage == null) {

			HttpTransport httpTransport = new NetHttpTransport();
			JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();

			List<String> scopes = new ArrayList<String>();
			scopes.add(StorageScopes.CLOUD_PLATFORM);
			scopes.add(StorageScopes.DEVSTORAGE_FULL_CONTROL);
			scopes.add(StorageScopes.DEVSTORAGE_READ_WRITE);

			GoogleCredential credential = GoogleCredential
					.getApplicationDefault();
			if (credential.createScopedRequired()) {
				credential = credential.createScoped(scopes);
			}
			storage = new Storage.Builder(httpTransport, jsonFactory, null)
					.setHttpRequestInitializer(credential)
					.setApplicationName(
							getProperties().getProperty(
									APPLICATION_NAME_PROPERTY)).build();
		}
		return storage;
	}
	private static Properties getProperties() throws Exception {

		if (properties == null) {
			properties = new Properties();
			InputStream stream = DeleteUploadedFiles.class
					.getResourceAsStream("/resources/cloudstorage.properties");
			try {
				properties.load(stream);
			} catch (IOException e) {
				throw new RuntimeException(
						"cloudstorage.properties must be present in classpath",
						e);
			} finally {
				stream.close();
			}
		}
		return properties;
	}

こんな感じで出来ました。^^

リモートリポジトリにプッシュ 【GitHub】

プロジェクトをGitHubのリモートリポジトリにプッシュする

目次
①プロジェクトを右クリック
②リモートリポジトリの情報を入力
③プッシュする内容を選択して完了


①プロジェクトを右クリックする
f:id:hatehate_masaki:20160928002826j:plain

②リモートリポジトリの情報を入力する
 ・URI
 ・ユーザ
 ・パスワード
f:id:hatehate_masaki:20160928002958j:plain

③プッシュする内容を選択して、完了する
f:id:hatehate_masaki:20160928003316j:plain


以上。

ローカルプロジェクトをバージョン管理 【GitHub】

ローカルで作成した既存のプロジェクトをGitHubでバージョン管理する

目次
①ローカルリポジトリの作成
②作成したリポジトリにプロジェクトをコミット

環境
eclipse:Kepler 4.3.2
・プロジェクトは作成済みとする


①ローカルリポジトリの作成
・プロジェクトを右クリック → プロジェクトの共用
f:id:hatehate_masaki:20160927232056j:plain

・Gitを選択して、次へ
f:id:hatehate_masaki:20160927232309j:plain

リポジトリーの作成
 ・赤枠にチェックを入れる
 ・青枠を押下 (チェックは入れない)
 ・リポジトリーの作成を押下
 ・完了を押下
f:id:hatehate_masaki:20160927232106j:plain

②作成したリポジトリにプロジェクトをコミット
・プロジェクトを右クリック → チーム → コミット → すべてのファイルを選択 → コミット


★以下の様にプロジェクトのアイコンに筒マークが付いていたら完了
f:id:hatehate_masaki:20160927234013j:plain




※Creation of repositories in the Eclipse workspace is not recommendedについて
リポジトリの作成場所をC:\Users\xxxx\git\リポジトリ名 などに変更すれば本警告は出なくなります。お好みで。

アカウント作成 & リモートリポジトリ作成 【GitHub】

GitHubにアカウント、リポジトリを作る手順

目次
手順① GitHubのトップページにアクセスする
手順② 利用プランを選択してFinish sign upをクリックする
手順③ アカウント登録通知メールのURLにアクセスする
手順④ 必要事項を入力してリモートリポジトリを作成する

手順① GitHubのトップページにアクセス
How people build software · GitHub
・赤枠を入力してSign up for GitHubをクリック
f:id:hatehate_masaki:20160821195423j:plain

手順② 無料版を選択して、Finish sign upをクリック
f:id:hatehate_masaki:20160821195431j:plain

手順③登録したメールアドレスに通知メールが来るので、URLをクリック
 1. 赤枠を入力する。青枠は入力不要
 2. Create repository をクリック
f:id:hatehate_masaki:20160821195435j:plain

 3. リポジトリ作成完了
f:id:hatehate_masaki:20160821195438j:plain

以上。

ajax, servlet連携

・画面側

$(document).ready(function() {
    $("input:button").click(function() {
        if (window.confirm('○○しますか?')) {
            // xxチェック
            var _return = isExistXX();
            var obj = JSON.parse(_return);
            if (obj['message'] == "success") {
                dropzone.processQueue();
            } else {
            alert("~が存在しません。~して下さい。");
            }
        }
    });
});
function isExistXX() {
    var param1 = document.forms[0].xx.value;
    return $.ajax({
    url : '/IsExistXX',
    // async(非同期) : false
    async : false,
    type : 'POST',
    dataType : 'json',
    data : {
        parameter1 : param1
    },
    timeout : 10000,
    success : function(data) {
    // alert("成功");
    },
    error : function(XMLHttpRequest, textStatus, errorThrown) {
    // alert("失敗");
    }
    }).responseText;
}

・サーバ側

public void doPost(HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException {

String xx= req.getParameter("parameter1");

String aaa = Util.getZZZ(xx);

String message = "";
    if (!aaa.isEmpty()) {
    message = "success";
    } else {
    message = "fail";
    }
String responseJson = "{\"message\":\"" + message + "\"}";
res.setContentType("application/json;charset=UTF-8");
PrintWriter out = res.getWriter();
out.write(responseJson);
// out.print(responseJson); ← printだとjs側でJSON.parseができないので注意
}

ソースコードレビューでの指摘事項

コーディングの際に意識すること

 

・メソッドの引数、戻り値を見ただけで何をするメソッドか分かるように書くこと。

もちろんメソッド名でも処理内容が推察できること。

⇒引数にメソッド内の条件判定に必要な情報を渡したら、その条件ごとに処理したオブジェクトが返ってくるような設計にする。

 

・if文の判定条件には、ほかの状態に依存するような変数は使わないこと。

例:

// 処理A

if ("0".equals(xxStatus)) {

    xx = false;

} else if ("1".equals(xxStatus)) {

    xx = false;

} else if ("2".equals(xxStatus)) {

    xx = true;

} else {

    xx = false;

}

// 処理B    ←    ここではxxStatusがtrueの場合だけ更新処理を行う仕様なのに前段の判定処理に結果が依存しているからNG

if (xx = ture) {

    // 更新処理を行う

} else {

    // 更新処理を行わない

}

 

・IsExistメソッドでの一撃returnはよろしくない場合がある

⇒戻り値が結果として同じになるからといって、同レベルでない判定を一行で書くべきではない。

例:

boolean IsExist (String xx) {

    // return "0".equals(xxStatus) || "0".equals(xxStatus) && "1".equals(xxFlg)    ←    NG

    if (return "0".equals(xxStatus) || "0".equals(xxStatus)) {

        if ("1".equals(xxFlg)) {

        return ture;

        }

    } else {

        return false;

    } 

}

 

 

// TODO 随時追加する。

 

 

データストア query.addFilterは非推奨 【google app engine for java】

クエリを用いて条件検索する方法

 

// インポート文

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.FilterOperator;

 

private static DatastoreService datastoreService = DatastoreServiceFactory
.getDatastoreService();

 

Query query = new Query("テーブル名");

query.setFilter(FilterOperator.EQUAL.of("検索するカラム名","検索したい文字列"));

PreparedQuery pQuery = datastoreService.prepare(query);

for(Entity entity: pQuery.asIterable()){
    xx = entity.getProperty("取得したいカラム名").toString();

}

 

・実行SQL

SELECT 取得したいカラム名 FROM テーブル名 WHERE 検索するカラム名 = "検索したい文字列";