当前位置: 首页 > 知识库问答 >
问题:

在grails中处理来自服务的错误

罗毅
2023-03-14

我的代码有问题。如何处理从服务到GSP的错误?我使用render from service或controller进行了尝试,但类似于[值为[{2}]的类[{1}]的属性[{0}]不是有效的电子邮件地址],并得到错误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")
        }
    }

}
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");
                }
            }
        }
    }
}
<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个答案

郎华皓
2023-03-14

我只想补充一点,对控制流使用异常不是很好的程序设计,而且非常昂贵。我建议删除UserRegistrationException,而只返回一个布尔false,并在控制器中检查该值。请记住,groovy方法是动态类型化的,您可以返回您想要的任何东西。

 类似资料:
  • 我有一个场景,当一个对象被两个不同的线程更新。下面是grails服务类中的代码。我能够捕捉StaleObject异常,但当我试图从数据库中再次获取它并重试保存值时,它不起作用。 为什么上面的代码不更新/保存catch块中的值?我也试过了。get(id)方法从数据库中获取最新的,但它不起作用。 但当我尝试此操作时,它会更新最新的计时器值: 在控制器中:- 在职: 如果在控制器/服务中抛出和处理它,则

  • 问题内容: 我正在向我的API发出请求,并且正在使用AngularJS $ resource模块。它与$ http不同,因此我不知道如何处理错误。 我的服务: 我的控制器: 我想要类似这样的东西..如果我的API无法正常工作,我不知道如何处理错误。 问题答案: 您可以将错误处理程序作为第二个参数传递给。 编辑: 为了使事情更清楚一些,例如:

  • 问题内容: 当服务中抛出RuntimeException时,我使用Grail的回滚功能将所有服务更新为事务性。在大多数情况下,我都这样做: 无论如何,我想验证这是否确实会回滚事务……这让我开始思考是否在这一点上已经提交了。此外,如果没有,设置flush:true会改变这一点吗?我对Spring / Hibernate如何完成所有这些工作不是很熟悉:) 问题答案: 是的,那样做。 默认情况下,Gra

  • 我成功地从Android向Jersey服务器发送了多部分消息,如下所示: 这工作正常,但问题是当我需要使用GET从服务器接收多部分响应时。服务器还需要将一个图像和三个字符串作为多部分消息发送给我。我不知道如何处理: 我不确定如何从实体中提取值。如何从响应中获取该文件和字符串值?我知道如何处理像普通字符串或JSON这样的简单响应,但是多部分响应困扰着我。任何建议都会很有帮助。谢谢。

  • 问题内容: 我想像本例一样启用蓝牙。 但是,我的课程不是Activity,而是Service,因此我不能调用startActivityForResult。我怎么解决这个问题?。我知道还回答了其他问题,例如 使用非活动中的startActivityForResult 但这不能解决我的问题,因为我的应用程序由服务组成,而没有别的什么。 问题答案: 不幸的是你不能那样做。 我发现(破解)的唯一解决方案是

  • 我们正在构建一个JavaSDK,以简化对我们提供REST API的服务之一的访问。这个SDK将由第三方开发者使用。我正在努力寻找最好的模式来实现更适合Java语言的SDK中的错误处理。 假设我们有其余的endpoint:。这可能会返回以下HTTP状态代码: 401:用户未通过身份验证 403:用户没有访问此照片的权限 404:没有带那个身份证的照片 该服务看起来像这样: 在上面的代码中,我还没有提