20190819のJavaに関する記事は3件です。

SpringBootでGETのリクエストパラメータenumのバリデーションってどうするのが正解なのさ

環境

  • spring boot 2.2.0.M4
  • io.spring.dependency-management 1.0.7.RELEASE
  • plugin spring 1.3.31
  • Java 11

経緯

SpringMVCでGETのリクエストパラメータでenumを使いたかった
controll adviceのハンドリングクラスで全部ハンドリングしたかった
結論だけまとめると以下概要

概要

  • custom validationを作成
  • enumで受け取らずStringで受け取る

実装

Controller

@RestController
@Validated
public class ColorController {

    @RequestMapping(value="/", method= RequestMethod.GET)
    public Boolean isDefinedColor(@ColorConstraint @Valid @RequestParam(value = "color",required = false) String color){

        //validation済みなので値を変換して使用する
        Color.fromValue(color);
        return true;
    }

}

Custom Validation

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {ColorValidator.class})
public @interface ColorConstraint {

    String message() default "not defined color";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};

}

public class ColorValidator implements ConstraintValidator<ColorConstraint, String> {


    @Override
    public void initialize(ColorConstraint constraintAnnotation) {
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        //未設定は許可
        if(value == null) return true;

        //空文字は不許可
        if(value.isEmpty()) return false;

        //値からenum引っ張れれば許可
        return Color.fromValue(value) != null;
    }
}

Enum

public enum Color {

    RED("red"),
    BLUE("blue"),
    GREEN("green");

    private String color;


    Color(String color){
        this.color = color;
    }

    public String getColor(){
        return this.color;
    }

    public static Color fromValue(String color){
        for (Color c : Color.values()) {
            if(c.getColor().equals(color))
                return c;
        }
        return null;
    }
}

補足

enumクラスのvalueOfを使わずにfromValueを作ってあげることがポイント(変換失敗時にexceptionじゃなくてnullを返してほしい)
上記実装にすることによってControllerAdviceをつけたハンドラークラスでConstraintviolationexceptionを拾うことによってvalidation共通のハンドリング処理に回すことができる

終わりに

もっといい方法があれば教えて頂きたいです・・・・・
Controller内でわざわざ変換すんのかよって感じです

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

...4333796 (DEPRECATED) Could not find an installed version of Gradle either in Android Studio, or on your system to install the gradle wrapper. Please include gradle in your path, or install Android Studio [ERROR]... が発生した時(mac)

gradleがないらしい。
gradleはインストール済みなのでパスを通す。(インストールしてない人はandroidstudioをインストールしてね)

export PATH="/Applications/Android Studio.app/Contents/gradle/gradle-5.1.1/bin":"$PATH"

を実行して次回以降発生させないために~/.bash_profileに追記する。

source ~/.bash_profile

を実行して完了。

'''''追記'''''
(gradleのバージョンは環境に合わせて変えてね...)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

空白を許さない湯婆婆

事の発端

2019/08/16に金曜ロードショーで「千と千尋の神隠し」というアニメーション映画が放送されました。
ジブリ製作の大衆向けアニメーションの舞台のモデルが風俗店というのも面白い作品だと思います。

その中で湯屋の主人・湯婆婆が迷い込んだ主人公・千尋と千尋が働くための契約を結ぶシーンがあります。
今回はそのシーンにフォーカスを当てたものになります。

さて、Twitterに面白い投稿がされました。

「湯婆婆が名前を”奪う”行為は最初の文字を取っているために、空白を入力すれば処理できない」
というものです。

このような記事もありました。
湯婆婆は参照で落ちるから名前を書かない方がいい

個人的な意見ではありますが、湯婆婆の性格上、契約者が名前を書かないという行為を許す人物ではないと思っています。
なので、今回は「空白を許さない(名前を書くまで終わらない)湯婆婆」を作ってみたいと思いました。

湯婆婆

早速ソースコードをば。

Yubaaba.java
public class Yubaaba {
    private String name ;
    private char reName;
    public void edit() {
        message("契約書に名前を書きな。働かせてやる。");
        message("その代わり嫌だとか、帰りたいとかいったらすぐ子豚にしてやるからね。");
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        while(true) {
            try {
                name = br.readLine();
                if (name.isEmpty()) {
                    throw new Exception();
                } else {
                    break;
                }
            } catch (Exception e) {
                message("だらしないねぇ。自分の名前くらいチャンと書けないのかい?");
            }
        }
        message("フン。" + name + "というのかい?贅沢な名だねぇ");
        rename(name);
        message("今からお前の名前は" + reName + "だ。いいかい、" + reName + "だよ。");
        message("分かったら返事をするんだ、" + reName + "!!");
    }

    public void message(String str) {
        System.out.println(str);
    }

    public void rename(String name) {
        Random random = new Random();
        int number = random.nextInt(name.length() - 1);
        reName = name.charAt(number);
    }
}

whileループで空白だった場合Exceptionに飛ばしてループを抜けられないようにしてあります。
「自分の名前くらいチャンと書けないのかい?」と名前の入力を強制してきます。

また、奪う文字を湯婆婆の気分で決めている、という想像を膨らませて、ランダムに決定させるようにしています。

実行させた結果が以下になっています。

契約書に名前を書きな。働かせてやる。
その代わり嫌だとか、帰りたいとかいったらすぐ子豚にしてやるからね。
千尋
フン。千尋というのかい?贅沢な名だねぇ
今からお前の名前は千だ。いいかい、千だよ。
分かったら返事をするんだ、千!!

ちゃんと湯婆婆してます。
ここで空白を入力してみましょう。

契約書に名前を書きな。働かせてやる。
その代わり嫌だとか、帰りたいとかいったらすぐ子豚にしてやるからね。
        #(空白を入力)
だらしないねぇ。自分の名前くらいチャンと書けないのかい?
        #(空白を入力)
だらしないねぇ。自分の名前くらいチャンと書けないのかい?

ちゃんと名前を要求してきます。

これにて「空白を許さない湯婆婆」のできあがりです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む