我正在使用apache CXF。
以下API用于发布联系人。
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
ResponseResult create(@Context HttpHeaders httpHeaders, @Context Request request, @Context UriInfo uriInfo,
UserContact contact) throws MDMException;
这里的UserContact类包含有关用户的联系信息,该联系信息作为JSON传递到正文中。
我需要对此UserContact对象进行一些业务验证。但是我不喜欢在单个类中包含太多验证代码。
我想做类似以下的事情。但是我面对泛型的问题。
interface Rule<S>
{
void applyRule(S s)throws Exception;
}
interface Validatable
{
void validate() throws Exception;
}
public class MyValidator
{
private HashMap<? extends Rule ,?> map = new HashMap<>();
public void validate() throws Exception
{
for(Rule rule : map.keySet())
{
rule.applyRule(map.get(rule));
}
}
public <S> void addRule(Rule<S> rule, S data)
{
this.map.put(rule, data);
}
}
class EMailValidationRule implements Rule<String>
{
private static final Pattern emailPattern = Pattern.compile("email-regex");
public void applyRule(String s) throws Exception
{
if(!emailPattern.matcher(s).matches())
throw new Exception("Not a valid EMail");
}
}
因此,UserContact必须执行以下操作以进行验证。这样可以使代码紧凑(IMO)。
class UserContact implements Validatable
{
// some
// code
// related to User Contact
public void validate() throws Exception
{
MyValidator validator = new MyValidator();
validator.addRule(new EMailValidationRule(), "[email protected]");
validator.addRule(new PhoneValidationRule(), "+1234567890");
validator.validate();
}
}
我不断收到类似的错误:
HashMap类型的put(capture#5-of?扩展Rule,capture#6-of?)方法不适用于参数(Rule,S)
上述设计是否也适合进行验证?
问题是,尽管您的封装确保了这一点,但是编译器无法确保所检索Rule<...>
的类型参数与所检索的数据具有相同的类型。
还有一个问题是无法插入Rule<T>
带有的子类型的数据T
。如果您有Rule<S> rule, S data
类型,则必须完全匹配。虽然aRule<S>
可以处理一个S
很好的子类型。
虽然这MyValidator
是一个很棒的小班,但我真的看不出有什么意义。特别是因为您每次调用都会创建一个新文件validate
。由于规则是静态的(对于类的每个实例都是相同的),并且数据来自各个实例(我会假设),因此也很难进行缓存。
您也可以这样做:
class UserContact implements Validatable
{
// some
// code
// related to User Contact
// 1 rule instance for the entire class, not a new one per call to 'validate'
private static EMailValidationRule emailRule = new EmailValidationRule();
private static PhoneValidationRule phoneRule = new PhoneValidationRule();
public void validate() throws Exception
{
emailRule.applyRule("[email protected]");
phoneRule.applyRule("+1234567890");
}
}
不管怎样,这是的工作版本MyValidator
:
class MyValidator {
private Map<Rule<?>, RuleNode<?>> map = new HashMap<>();
public void validate() throws Exception {
for(RuleNode<?> node : map.values())
node.apply();
}
public <T, D extends T> void addRule(Rule<T> rule, D data) {
@SuppressWarnings("unchecked") // unchecked, but safe due to encapsulation
RuleNode<T> r = (RuleNode<T>) map.get(rule);
if(r == null) {
r = new RuleNode<T>(rule);
map.put(rule, r);
}
r.add(data);
}
private static class RuleNode<T> { // Maintains that the rule and data are compatible
private final Rule<T> rule;
private final List<T> list = new ArrayList<>();
public RuleNode(Rule<T> rule) {
this.rule = rule;
}
public void add(T data) {
list.add(data);
}
public void apply() throws Exception {
for(T data : list)
rule.applyRule(data);
}
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句