我已经制作了这个Java方法,用于验证字符串插入表单字段:
public void validateDatacenterName(FacesContext context, UIComponent component,
Object value) throws ValidatorException, SQLException {
String l;
String s = value.toString().trim();
if (s.length() > 18) {
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
" Value is too long! (18 digits max)", null));
}
try {
// l = Long.parseLong(s);
// if (l > Integer.MAX_VALUE)
// {
// throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
// " '" + l + "' is too large!", null));
// }
} catch(NumberFormatException nfe) {
l = null;
}
if (s != null) {
if (ds == null)
throw new SQLException("Can't get data source");
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs;
int cnt = 0;
try {
conn = ds.getConnection();
ps = conn.prepareStatement("SELECT count(1) from COMPONENTSTATS where COMPONENTSTATSID = ?");
ps.setString(1, s);
rs = ps.executeQuery();
while(rs.next())
cnt = rs.getInt(1);
if (cnt > 0) {
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
" '" + s + "' is already in use!", null));
}
} catch(SQLException x) {
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
" SQL error!", null));
} finally {
if (ps != null)
ps.close();
if (conn != null)
conn.close();
}
} else {
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
s.isEmpty() ? " This field cannot be empty!" : " '" + s + "' is not a valid name!", null));
}
}
我如何改进此代码?我是否可以添加任何其他检查以改进表单验证器?
任何帮助都将受到高度赞赏!
答案 0 :(得分:3)
StackOverflow读者不会从您的描述中知道什么是有效的数据中心名称,因为我们不知道您的应用程序。唯一的要求是数字吗?
如果该值应为数字,为什么要注释掉调用parseLong()
的代码?
检查COMPONENTSTATS中是否有正在使用的值会创建race condition。也就是说,即使在检查之后,其他一些应用程序线程也可以在插入之前插入相同的值。为什么不使用UNIQUE
约束强制数据库中的唯一性?
当您知道s.isEmpty()
时,如何在else
区块中致电s == null
?
如果此方法是实现javax.faces.validator.Validator的类的一部分,那么该方法不应该命名为validate()
吗?
答案 1 :(得分:2)
如果确实需要,则应该只使用正则表达式。使用您当前使用的验证,标准String
方法就足够了。
您应该尽可能地保持验证相关任务的方法。为此,您应该将数据库调用提取到单独的方法中。
此外,您还有NullPointerException
等待发生:
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
s.isEmpty() ? " This field cannot be empty!" : " '" + s + "' is not a valid name!", null));
此时s
将null
,NullPointerException
将被抛出,然后您可以抛出ValidatorException
。
答案 2 :(得分:1)
我会用regexp验证。
不幸的是,我没有足够的知识来提供确切的字符串,但我确信谁在每天使用它将在3秒内没有它:)我知道这将是最好的方式。
答案 3 :(得分:1)
要么我会在网上搜索已经实现的验证,要么我会创建一个字符列表,我想要允许字符串,而不是检查输入,例如使用正则表达式,输入不包含任何其他字符。
答案 4 :(得分:1)
在if (s.length() > 18)
检查之前,我认为您应该检查s是否为空
if (s !=null && s.length() > 18)
最好还是对字符串s.isEmpty()
进行空检查
答案 5 :(得分:1)
一些建议:
Regex
通过定义一组允许的字符和/或符号来验证Stirng
的结构if(s.length() > 18)
之前移动空检查逻辑。如果s
为null
,则该子句将产生NullPointerException
。if (s != null)
将允许s = ""
,因为它不为空,打破您尝试验证空字符串的else语句(当您执行时会导致NullPointerException
创建验证消息)。如果要在两种情况下执行不同的逻辑,请使用if(s != null && !s.isEmpty())
或将验证分成两部分。