1. 程式人生 > >自定義註解完成引數校驗

自定義註解完成引數校驗

在現在的專案開發中,經常會用到註解,比如Spring的@Autowired,SpringMVC的@Controller,@RequestMapping等等,大部分人只知道用,不知道這些註解的怎麼發揮作用。有沒有想過手動寫一個註解,完成引數校驗呢?

簡介

註解(Annotation),也叫元資料。一種程式碼級別的說明。它是JDK1.5及以後版本引入的一個特性,與類、介面、列舉是在同一個層次。它可以宣告在包、類、欄位、方法、區域性變數、方法引數等的前面,用來對這些元素進行說明,註釋。

作用分類:

①編寫文件:通過程式碼裡標識的元資料生成文件【生成文件doc文件】

②程式碼分析:通過程式碼裡標識的元資料對程式碼進行分析【使用反射】

③編譯檢查:通過程式碼裡標識的元資料讓編譯器能夠實現基本的編譯檢查【Override】

分類

Java註解根據標記位置分為三類。

標記在類上

標記在變數上

標記在方法上

註解類上需要加入:

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

依次是,標記的位置,註解生存週期。

標記在方法上

執行時有效

實戰

在編寫註解之前需要了解,你的引數校驗需要做哪些工作。

此次校驗是標記在變數上的,主要功能包括:

非空校驗

長度校驗

正則校驗

這幾條包含了大部分的資料校驗的功能。

開始

編寫註解:Validation.java

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)

public @interface Validation {

//校驗失敗報錯資訊

String value();

//最大值

String max();

//最小值

String min();

//正則表示式

String pattern();

}

編寫校驗程式碼:

import java.lang.reflect.Field;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.List;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

public class Check {

public static void check(Object o) {

if (null == o) {

return;

}

Class clazz = o.getClass();

ListField fieldList = new ArrayListField();

while (clazz != null) {

fieldList.addAll(new ArrayList(Arrays.asList(clazz.getDeclaredFields())));

clazz = clazz.getSuperclass();

}

fieldList.forEach(field - {

field.setAccessible(true);

try {

Object value = field.get(o);

Validation annotation = field.getAnnotation(Validation.class);

if (null == annotation) {

return;

}

checkNotNull(value, annotation);

checkPattern(value, annotation);

checkMax(value, annotation);

checkMin(value, annotation);

} catch (IllegalArgumentException e) {

e.printStackTrace();

//資料解析失敗

} catch (IllegalAccessException e) {

e.printStackTrace();

}

});

}

private static double objectToDubule(Object o) {

return Double.valueOf(o.toString());

}

private static void checkNotNull(Object value, Validation validation) {

if (validation.notNull() value == null) {

throw new RuntimeException(validation.value());

}

}

private static void checkPattern(Object value, Validation validation) {

if (null != validation.pattern() validation.pattern().length() 0) {

Pattern p = Pattern.compile(validation.pattern());

Matcher m = p.matcher(value.toString());

if (!m.matches()) {

throw new RuntimeException(validation.value());

}

}

}

private static void checkMax(Object value, Validation validation) {

if (validation.max() 0) {

if (value instanceof String) {

if (value.toString().length() validation.max()) {

throw new RuntimeException(validation.value());

}

} else {

if (objectToDubule(value) validation.max()) {

throw new RuntimeException(validation.value());

}

}

}

}

private static void checkMin(Object value, Validation validation) {

if (validation.max() = 0) {

if (value instanceof String) {

if (value.toString().length() validation.min()) {

throw new RuntimeException(validation.value());

}

} else {

if (objectToDubule(value) validation.min()) {

throw new RuntimeException(validation.value());

}

}

}

}

}

測試

編寫CheckTest.java

import org.junit.Test;

public class CheckTest {

@Test

public void check() {

TestData data = new TestData();

data.arg = 20;

data.setMobile(1368989889);

data.setName(test);

Check.check(data);

System.out.println(校驗通過);

}

class TestData {

@Validation(value = 名稱校驗失敗, notNull = true)

private String name;

@Validation(value = 手機號校驗失敗, notNull = true, pattern = ^1(3[0-9]|4[0-9]|5[0-35-9]|8[0-9]|7[0-9]|6[0-9]|9[0-9])\\d{8}$)

private String mobile;

@Validation(value = 年齡校驗失敗, notNull = true, max = 60, min = 18)

private Integer arg;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getMobile() {

return mobile;

}

public void setMobile(String mobile) {

this.mobile = mobile;

}

public Integer getArg() {

return arg;

}

public void setArg(Integer arg) {

this.arg = arg;

}

}

}

執行截圖:

手機號錯誤

資料正確