我制作了这个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));
}
}
如何改进此代码?为了改进表单验证器,我是否可以添加其他检查?
如有任何帮助,我们将不胜感激!
-
StackOverflow的读者从您的描述中不知道什么是有效的数据中心名称,因为我们不知道您的应用程序。唯一的要求是它是数字吗?
-
如果该值应该是数字,为什么要注释掉调用
parseLong()
的代码? -
检查COMPONENTSTATS中已使用的值会创建竞争条件。也就是说,即使在检查之后,其他应用程序线程也可以在您插入相同的值之前插入它。为什么不使用
UNIQUE
约束在数据库中强制执行唯一性呢? -
当您知道
s == null
时,如何在您的else
块中调用s.isEmpty()
? -
如果该方法是实现javax.faces.validator.validator的类的一部分,那么该方法不应该命名为
validate()
吗?
只有当确实需要时,才应该使用正则表达式。根据您正在使用的当前验证,标准的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
之前抛出。
我将使用regexp进行验证。
不幸的是,我不知道给出确切的字符串,但我相信每天使用它的人会在3秒钟内不使用它:(我知道这将是最好的方法。
要么我会在web上搜索已经实现的验证,要么我会列出一个字符列表,我想允许字符串使用这些字符,然后检查输入,例如用正则表达式检查输入不包含任何其他字符。
在if (s.length() > 18)
检查之前,我认为您应该检查s是否为空
if (s !=null && s.length() > 18)
并且最好对字符串s.isEmpty()
进行空检查
一些建议:
- 使用
Regex
通过定义一组允许的字符和/或符号来验证Stirng
的结构 - 将空检查逻辑移到
if(s.length() > 18)
之前。如果s
是null
,则该子句将产生NullPointerException
- 修复您的null检查:
if (s != null)
将允许s = ""
,因为它不是null,从而破坏了您尝试验证空字符串的else语句(这将在创建验证消息时导致NullPointerException
(。如果您想在两种情况下执行不同的逻辑,请使用if(s != null && !s.isEmpty())
或将验证一分为二