在 grails 中处理来自服务的错误
Posted
技术标签:
【中文标题】在 grails 中处理来自服务的错误【英文标题】:Handle errors from service in grails 【发布时间】:2012-06-28 03:43:27 【问题描述】:我的代码有问题。如何处理从服务到我的 gsp 的错误?我尝试使用来自服务或控制器的渲染,但类似于 [属性 [0] 的类 [1] 的值 [2] 不是有效的电子邮件地址] 并得到一个带有完整异常跟踪的错误 500:内部服务器错误。我的消息来源:
UserController.groovy
def saveUser()
def salt = new SecureRandomNumberGenerator().nextBytes().getBytes()
def user
try
user = userService.registerMethod(params.username, params.passwordHash, params.passwordHash2,
salt, params.firstName, params.lastName, params.sex, params.email, params.mobile, params.userType)
session.user = user
flash.message = "User $user.profile.firstName $user.profile.lastName was successfuly created!"
redirect(uri:"/")
catch (UserRegistrationException ure)
user = ure.user
if (user)
render(view:"registration",model:[user:user])
else
flash.message = ure.message
redirect(action:"registration")
UserService.groovy
class UserRegistrationException extends RuntimeException
String message
User user
class UserService
boolean transactional = true
User registerMethod(String username, String password1, String password2, Object salt, String firstName, String lastName,
String sex, String email, String mobile, String userType)
def user = User.findByUsername(username)
if(user)
//flash.message = "User already exists with login $username"
throw new UserRegistrationException(message:"User already exists with login $username")
redirect(uri:"/")
else
if (password1 != password2)
//flash.message = "Passwords don't match"
throw new UserRegistrationException(message:"Passwords don't match")
else
def profile = Profile.findByEmail(email)
if (profile && (email == profile.email))
//flash.message = "User with this email is already exists!"
throw new UserRegistrationException(message:"User with this email is already exists!")
else
user = new User(
username:username,
passwordHash: new Sha512Hash(password1, salt, 1024).toHex(),
passwordSalt:salt,
profile: new Profile(
firstName:firstName,
lastName:lastName,
sex:sex,
email:email,
mobile:mobile,
userType:userType
)
)
if (!user.hasErrors() && user.save(flush:true,failOnError:true))
def authToken = new UsernamePasswordToken(username, password1)
SecurityUtils.subject.login(authToken)
return user
else
throw new UserRegistrationException(message:"Can't create user");
registration.gsp
<body>
<h1>Registration Page</h1>
<g:if test="$ flash.message ">
$ flash.message
</g:if>
<g:hasErrors bean="$ user ">
<g:renderErrors bean="$ user " as="list"/>
</g:hasErrors>
<div id="registration">
<g:form action="saveUser">
<table>
<tr>
<td><label for="username">Login: </label></td>
<td><g:textField name="username" id="username" /></td>
</tr>
<tr>
<td><label for="firstName">First Name: </label></td>
<td><g:textField name="firstName" id="firstName"/></td>
</tr>
<tr>
<td><label for="lastName">Last Name: </label></td>
<td><g:textField name="lastName" id="lastName"/></td>
</tr>
<tr>
<td><label for="sex">Sex: </label></td>
<td><g:radioGroup values="['M','F']" name="sex" labels="['Male','Female']">
<p>$ it.radio $ it.label </p>
</g:radioGroup></td>
</tr>
<tr>
<td><label for="email">Email: </label></td>
<td><g:textField name="email" id="email"/></td>
</tr>
<tr>
<td><label for="mobile">Mobile: </label></td>
<td><g:textField name="mobile" id="mobile"/></td>
</tr>
<tr>
<td><label for="passwordHash">Password: </label></td>
<td><g:passwordField name="passwordHash" id="passwordHash"/></td>
</tr>
<tr>
<td><label for="passwordHash2">Confirm password: </label></td>
<td><g:passwordField name="passwordHash2" name="passwordHash2" id="passwordHash2" /></td>
</tr>
<tr>
<td><label for="userType">User Type: </label></td>
<td>
<g:radioGroup values="['F','H']" name="userType" labels="['Freelancer','Client']">
<p>$ it.radio $ it.label </p>
</g:radioGroup>
</td>
</tr>
<tr>
<td><g:submitButton name="saveUser" value="Register"/> </td>
</tr>
</table>
</g:form>
</div>
</body>
也许我的代码有问题?
我只想向用户显示错误,而不是完整的异常跟踪
【问题讨论】:
【参考方案1】:您正在使用save(failOnError:true)
,当您的保存失败时会引发异常。由于您只捕获 UserRegistrationException
,因此来自 save()
的异常会产生 500 内部服务器错误。您可以删除 failOnError
并且您的服务方法应该落入您的 throw new UserRegistrationException
块并按照您的预期运行。
【讨论】:
老兄,你是我的救星。最好的问候【参考方案2】:我只想补充一点,对控制流使用异常不是好的程序设计,而且非常昂贵。我建议删除 UserRegistrationException
而只返回一个布尔值 false
并在控制器中检查它。请记住,groovy 方法是动态类型的,你可以返回任何你想要的。
【讨论】:
只返回false
的问题是你不知道它失败的原因。因此,如果通过,您可以返回 null
,如果失败则返回消息。但是由于null
被认为是“虚假的”,因此通过它获得成功感觉很奇怪。或者,您可以将您的异常更新为 not 创建一个堆栈跟踪,从而消除大量异常成本。实现细节见***.com/questions/11434431/…。以上是关于在 grails 中处理来自服务的错误的主要内容,如果未能解决你的问题,请参考以下文章
来自服务的 Grails Spring Security 身份验证