列挙型作成
- 型を
enum
として宣言することで列挙型となる
- 取りうる値は
,
区切りで並べればよい
public enum FieldType {
Number,
Text,
List
}
アノテーション作成
- 型を
@interface
として宣言することでアノテーションとなる
- 保持期間は
@Retention
で指定
- 付与可能な対象は
@Target
で指定
- フィールドのデフォルト値は
default
で指定
import static java.lang.annotation.ElementType.FIELD;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Target;
import static xxx.FieldType.Text;
import xxx.FieldType;
@Retention(RUNTIME)
@Target(FIELD)
public @interface Attr {
int length() default 0;
int size() default 1;
boolean isDummy() default false;
FieldType type() default Text;
}
アノテーションを付与
@Target
に対応した要素の前にアノテーションを記載する
@Attr(length=10, type=Number, isDummy=false)
String value1;
@Attr(length=3、size=10, type=List, isDummy=false)
SampleItem[] items;
アノテーションの取得
import java.lang.reflect.Field;
:
// 全フィールド取得
Field[] fields = this.getClass().getDeclaredFields();
// 指定フィールド取得
Field field = this.getClass().getDeclaredField("フィールド名");
:
Attr attr = field.getAnnotation(Attr.class);
実践
Controller
package com.example.demo.controller;
import com.example.models.SampleData;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("api/v1")
public class SampleController {
@RequestMapping("sample")
public Object get(@RequestBody @Validated SampleData data, BindingResult result) {
if (result.hasErrors()) {
return result.getAllErrors();
}
return "[" + data.toFixedString() + "]";
}
}
DTOの抽象クラス
package com.example.models;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.HashMap;
public abstract class BaseData {
private Map<String, Attr> attrMap = createMap();
private Map<String, Attr> createMap() {
Map<String, Attr> attrMap = new HashMap<String, Attr>();
Field[] fields = this.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
Attr attr = field.getAnnotation(Attr.class);
attrMap.put(field.getName(), attr);
}
return attrMap;
}
abstract public String toFixedString();
public String toFixedString(String name, String value) {
Attr attr = attrMap.get(name);
if (value == null) {
return toFixedBlank(attr);
}
switch (attr.type()) {
case Text:
return String.format("%-" + attr.length() + "s", value);
case Number:
return String.format("%" + attr.length() + "s", value).replace(" ", "0");
default:
return "<error>";
}
}
public String toFixedString(String name, BaseData[] items) {
Attr attr = attrMap.get(name);
if (items == null) {
return toFixedBlank(attr);
}
StringBuilder sb = new StringBuilder();
String blank = String.format("%" + attr.length() + "s", " ");
for (int i = 0; i < attr.size(); i++) {
if (items == null || i >= items.length) {
sb.append(blank);
} else {
sb.append(items[i].toFixedString());
}
}
return sb.toString();
}
private String toFixedBlank(Attr attr) {
return String.format("%" + attr.length() * attr.size() + "s", " ");
}
}
DTO(親)
package com.example.models;
import static com.example.models.FieldType.*;
import javax.validation.Valid;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.Length;
import lombok.Data;
@Data
public class SampleData extends BaseData {
@Length(max=10)
@Attr(length=10, type=Text, isDummy=false)
public String value1;
@Length(max=5)
@Pattern(regexp="[0-9]+")
@Attr(length=5, type=Number, isDummy=true)
public String value2;
@Valid
@Size(max=3)
@Attr(length=SampleItem._length, size=3, type=List, isDummy=false)
SampleItem[] items;
public SampleItem[] getItems() { return this.items; }
public void setItems(SampleItem[] items) { this.items = items; }
public String toFixedString() {
StringBuilder sb = new StringBuilder();
sb.append(toFixedString("value1", value1));
sb.append(toFixedString("value2", value2));
sb.append(toFixedString("items", items));
return sb.toString();
}
}
DTO(子)
package com.example.models;
import static com.example.models.FieldType.*;
import org.hibernate.validator.constraints.Length;
import lombok.Data;
@Data
public class SampleItem extends BaseData {
public static final int _length = 18;
@Length(max=9)
@Pattern(regexp="[0-9]+")
@Attr(length=9, type=Number, isDummy=false)
String valueA;
@Length(max=9)
@Attr(length=9, type=Text, isDummy=true)
String valueB;
public String toFixedString() {
StringBuilder sb = new StringBuilder();
sb.append(toFixedString("valueA", valueA));
sb.append(toFixedString("valueB", valueB));
return sb.toString();
}
public String getValueA() { return this.valueA; }
public void setValueA(String valueA) { this.valueA = valueA; }
public String getValueB() { return this.valueB; }
public void setValueB(String valueB) { this.valueB = valueB; }
}