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

使用@Valid会引发异常

温亮
2023-03-14

我正在使用Spring In Action 3 Action学习Spring MVC,我已经实现了显示用户注册表的基本程序,一旦我们提交表单,它将使用@Valid进行验证。

这是我的Spring控制器:

@Controller
@RequestMapping("/spitter")
public class SpitterController {
        private final SpitterService spitterService;

        @Inject
        public SpitterController(SpitterService spitterService) {
            this.spitterService = spitterService;
        }

        @RequestMapping(method = RequestMethod.GET, params = "new")
        public String createSpitterProfile(Model model) {
            Spittle spittle = new Spittle();
            model.addAttribute(spittle);

            model.addAttribute(new Spitter());
            return "spittles/edit";
        }

            @RequestMapping(method = RequestMethod.POST)
            public String addSpitterFromForm(@Valid Spitter spitter,
            BindingResult bindingResult) {
               if (bindingResult.hasErrors()) {
                    return "spittles/edit";
               }
               spitterService.saveSpitter(spitter);
               return "redirect:/spitter/" + spitter.getUsername();
                }
             }

这是我的Spitter类文件:

package com.habuma.spitter.domain;

import java.util.List;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

public class Spitter {
    private Long id;

    @Size(min = 3, max = 20, message = "User name must be between 3 and 20 characters long.")
    @Pattern(regexp = "^[a-zA-Z0-9]+$", message = "Username must be alphanumeric with no spaces")
    private String username;

    @Size(min = 6, max = 20, message = "The password must be atleast 6 characters long.")
    private String password;

    @Size(min = 3, max = 50, message = "Your full name must be between 3 and 50 characters long.")
    private String fullName;

    @Pattern(regexp = "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}", message = "Invalid email address.")
    private String email;

    private List<Spittle> spittles;
    private boolean updateByEmail;

    ......Setters & Getters.....

    @Override
    public boolean equals(Object obj) {
        Spitter other = (Spitter) obj;
        return other.fullName.equals(fullName)
                && other.username.equals(username)
                && other.password.equals(password);
    }

    @Override
    public int hashCode() {
        return super.hashCode();
    }
}

这是我的编辑。显示给用户注册的jsp文件:

<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%>
<div>
    <h2>Create a free Spitter account</h2>
    <sf:form method="POST" modelAttribute="spitter" enctype="multipart/form-data">
        <fieldset>
            <table cellspacing="0">
                <tr>
                    <th><label for="user_full_name">Fullname:</label></th>
                    <td><sf:input path="fullName" size="15" id="user_full_name" />
                        <sf:errors path="fullName" cssClass="error" /></td>
                </tr>
                <tr>
                    <th><label for="user_screen_name">Username:</label></th>
                    <td><sf:input path="username" size="15" maxlength="15"
                            id="user_screen_name" /> <small id="username_msg">No spaces,please.</small>
                        <sf:errors path="username" cssClass="error" /></td>
                </tr>
                <tr>
                    <th><label for="user_password">Password:</label></th>
                    <td><sf:password path="password" size="30" showPassword="true"
                            id="user_password" /> <small>6
                            characters or more (betricky!)</small> <sf:errors path="password"
                            cssClass="error" /></td>
                </tr>
                <tr>
                    <th><label for="user_email">EmailAddress:</label></th>
                    <td><sf:input path="email" size="30" id="user_email" /> <small>In
                            case you forget something</small> <sf:errors path="email"
                            cssClass="error" /></td>
                </tr>
                <tr>
                    <th></th>
                    <td><sf:checkbox path="updateByEmail"
                            id="user_send_email_newsletter" /> <label
                        for="user_send_email_newsletter">Send me email updates!</label></td>
                </tr>
                <tr>
                    <th><label for="image">Profile image:</label></th>
                    <td><input name="image" type="file" />
                </tr>
                <tr>
                    <th></th>
                    <td><input name="commit" type="submit"
                        value="I accept.Createmyaccount." /></td>
                </tr>
            </table>
        </fieldset>
    </sf:form>
</div>

要加载表单,我将访问URL为:http://localhost:8081/SpringInAction3/spitter?new,一旦表单被加载,我只需提交表单而无需输入任何详细信息,以便我可以检查我的表单是否得到验证。但是我得到了以下例外:

java.lang.NullPointerException
    com.habuma.spitter.domain.Spitter.equals(Spitter.java:87)
    org.hibernate.validator.engine.resolver.SingleThreadCachedTraversableResolver$TraversableHolder.equals(SingleThreadCachedTraversableResolver.java:138)
    java.util.HashMap.get(HashMap.java:305)
    org.hibernate.validator.engine.resolver.SingleThreadCachedTraversableResolver.isReachable(SingleThreadCachedTraversableResolver.java:45)
    org.hibernate.validator.engine.ValidatorImpl.isValidationRequired(ValidatorImpl.java:757)
    org.hibernate.validator.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:324)
    org.hibernate.validator.engine.ValidatorImpl.validateConstraintsForRedefinedDefaultGroup(ValidatorImpl.java:273)
    org.hibernate.validator.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:256)
    org.hibernate.validator.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:210)
    org.hibernate.validator.engine.ValidatorImpl.validate(ValidatorImpl.java:119)
    org.springframework.validation.beanvalidation.SpringValidatorAdapter.validate(SpringValidatorAdapter.java:106)
    org.springframework.validation.DataBinder.validate(DataBinder.java:760)

我在我的equals方法Splitter类中得到了NullPointerException。请让我知道我哪里做错了?

编辑:

当我尝试打印Spitter对象中字段的值时,我为所有字段获取null,从而导致NullPointerException

这次我从我的Spitter类中删除了equals和hashCode方法,现在当我提交表单时,验证没有发生,页面将转到http://localhost:8081/SpringInAction3/spitter/null不显示任何错误。

为什么在这种情况下没有进行验证?此外,如果我只是按照那本书中的步骤操作,我将得到NullPointerException,这是不期望的。请让我知道我在哪里犯了错误?

根据这篇SO帖子:@Valid(jsr 303)在Spring mvc 3.0中不工作,我也有标签


共有1个答案

澹台成龙
2023-03-14

到目前为止,我发现了一个错误。sf:form属性enctype被设置为多部分/表单数据,但仅在文件上载时使用,因此我猜spring mvc使用的是多部分解析器,而不是将表单数据绑定到表单支持对象的数据绑定机制,请尝试将其更改为application/x-www-form-urlencoded,这是您案例的默认和正确类型。

 类似资料:
  • 我正在尝试使用@Valid验证我的JPA实体,如下所示: 它工作了一段时间,但现在它停止工作,我不知道为什么。我试着在< code>persist方法中手动执行,它按预期工作: 可能会发生什么情况,或者我该如何调试?

  • 问题内容: 我有一个简单的方法,可将命令打印到屏幕上,扫描用户的输入,然后将其作为字符串返回。如果用户输入无效,它将通知用户并再次询问。该方法运行完美,但是我的讲师提到我们应该始终关闭资源,因此我回过头来添加了close方法,现在无论用户输入什么,每次调用该方法时都会收到NoSuchElementException。这是代码… 例外总是指向用户输入以scan.nextLine()。trim()开头

  • 根据Hibernate文档,在Hibernate抛出异常后使用会话是不安全的。 如果会话抛出异常,包括任何SQLException,立即回滚数据库事务,调用Session.close()并放弃会话实例。某些会话方法不会使会话处于一致状态。Hibernate抛出的任何异常都不能被视为可恢复的。确保通过在finally块中调用close()来关闭会话。 在我的代码中,我正在做批量插入。我正在使用会话。

  • 本文向大家介绍在MySQL中使用“ TYPE = InnoDB”会引发异常吗?,包括了在MySQL中使用“ TYPE = InnoDB”会引发异常吗?的使用技巧和注意事项,需要的朋友参考一下 您可以使用ENGINE = InnoDB代替TYPE = InnoDB,因为TYPE的用法在MySQL 5.1版中已过时。 我们用于示例的版本是MySQL 8.0.12。让我们检查MySQL版本。查询如下-

  • 问题内容: 我需要在运行时创建添加servlet。当我运行以下代码时。 我收到以下错误。 java.lang.IllegalStateException:PWC1422:无法为servlet上下文/ 123-LBS的servlet 1114600676配置映射,因为此servlet上下文已经被初始化 是否不可能在运行时即在初始化Servlet上下文之后添加新的servlet,还是我做错了什么? 问