https://www.baeldung.com/spring-mvc-form-tags
 
 

1. Overview

In the first article of this series we introduced the use of the form tag library and how to bind data to a controller.

In this article, we’ll cover the various tags that Spring MVC provides to help us create and validate forms.

2. The input Tag

We’ll get started with the input tag. This tag renders an HTML input tag using the bound value and type=’text’ by default:

1
<form:input path="name" />

Starting with Spring 3.1 you can use other HTML5-specific types, such as email, date, and others. For example, if we wanted to create an email field, we can use type=’email’:

1
<form:input type="email" path="email" />

Similarly, to create a date field, we can use type=’date’, which will render a date picker in many browsers compatible with HTML5:

1
<form:input type="date" path="dateOfBirth" />

3. The password Tag

This tag renders an HTML input tag with type=’password’ using the bound value. This HTML input masks the value typed into the field:

1
<form:password path="password" />

4. The textarea Tag

This tag renders an HTML textarea:

1
<form:textarea path="notes" rows="3" cols="20"/>

We can specify the number of rows and columns in the same way we would an HTML textarea.

5. The checkbox and checkboxes Tag

The checkbox tag renders an HTML input tag with type=’checkbox’. Spring MVC’s form tag library provides different approaches to the checkbox tag which should meet all our checkbox needs:

1
<form:checkbox path="receiveNewsletter" />

The above example generate a classic single checkbox, with a boolean value. If we set the bound value to true, this checkbox will be checked by default.

The following example generates multiple checkboxes. In this case, the checkbox values are hard-coded inside the JSP page:

1
2
3
Bird watching: <form:checkbox path="hobbies" value="Bird watching"/>
Astronomy: <form:checkbox path="hobbies" value="Astronomy"/>
Snowboarding: <form:checkbox path="hobbies" value="Snowboarding"/>

Here, the bound value is of type array or java.util.Collection:

1
String[] hobbies;

The purpose of the checkboxes tag is used to render multiple checkboxes, where the checkbox values are generated at runtime:

1
<form:checkboxes items="${favouriteLanguageItem}" path="favouriteLanguage" />

To generate the values we pass in an Array, a List or a Map containing the available options in the items property. We can initialize our values inside the controller:

1
2
3
4
List<String> favouriteLanguageItem = new ArrayList<String>();
favouriteLanguageItem.add("Java");
favouriteLanguageItem.add("C++");
favouriteLanguageItem.add("Perl");

Typically the bound property is a collection so it can hold multiple values selected by the user:

1
List<String> favouriteLanguage;

6. The radiobutton and radiobuttons Tag

This tag renders an HTML input tag with type=’radio’:

1
2
Male: <form:radiobutton path="sex" value="M"/>
Female: <form:radiobutton path="sex" value="F"/>

A typical usage pattern will involve multiple tag instances with different values bound to the same property:

1
private String sex;

Just like the checkboxes tag, the radiobuttons tag renders multiple HTML input tags with type=’radio’:

1
<form:radiobuttons items="${jobItem}" path="job" />

In this case, we might want to pass in the available options as an Array, a List or a Map containing the available options in the items property:

1
2
3
List<String> jobItem = new ArrayList<String>();
jobItem.add("Full time");
jobItem.add("Part time");

7. The select Tag

This tag renders an HTML select element:

1
<form:select path="country" items="${countryItems}" />

To generate the values we pass in an Array, a List or a Map containing the available options in the items property. Once again, we can initialize our values inside the controller:

1
2
3
4
5
Map<String, String> countryItems = new LinkedHashMap<String, String>();
countryItems.put("US", "United States");
countryItems.put("IT", "Italy");
countryItems.put("UK", "United Kingdom");
countryItems.put("FR", "France");

The select tag also support the use of nested option and options tags.

While the option tag renders a single HTML option, the options tag renders a list of HTML option tags.

The options tag takes an Array, a List or a Map containing the available options in the items property, just like the select tag:

1
2
3
4
<form:select path="book">
    <form:option value="-" label="--Please Select--"/>
    <form:options items="${books}" />
</form:select>

When we have the need to select several items at once, we can create a multiple list box. To render this type of list, just add the multiple=”true” attribute in the select tag.

1
<form:select path="fruit" items="${fruit}" multiple="true"/>

Here the bound property is an array or a java.util.Collection:

1
List<String> fruit;

8. The hidden Tag

This tag renders an HTML input tag with type=’hidden’ using the bound value:

1
<form:hidden path="id" value="12345" />

9. The errors tag

Field error messages are generated by validators associated with the controller. We can use the errors tag to render those field error messages:

1
<form:errors path="name" cssClass="error" />

This will display errors for the field specified in the path property. The error messages are rendered within a spantag by default, with .errors appended to the path value as the id, and optionally a CSS class from the cssClassproperty, which can be used to style the output:

1
<span id="name.errors" class="error">Name is required!</span>

To enclose the error messages with a different element instead of the default span tag, we can specify the preferred element inside the element attribute:

1
<form:errors path="name" cssClass="error" element="div" />

This renders the error messages within a div element:

1
<div id="name.errors" class="error">Name is required!</div>

In addition to having the capability to show errors for a specific input element, we can display the entire list of errors (regardless of field) for a given page. This is achieved by the use of the wildcard *:

1
<form:errors path="*" />

9.1. The Validator

To display errors for a given field we need to define a validator:

1
2
3
4
5
6
7
8
9
10
11
12
public class PersonValidator implements Validator {
 
    @Override
    public boolean supports(Class clazz) {
        return Person.class.isAssignableFrom(clazz);
    }
 
    @Override
    public void validate(Object obj, Errors errors) {
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "required.name");
    }
}

In this case, if the field name is empty, the validator returns the error message identified by required.name from the resource bundle.

The resource bundle is defined in the Spring XML configuration file as follows:

1
2
3
<bean class="org.springframework.context.support.ResourceBundleMessageSource" id="messageSource">
     <property name="basename" value="messages" />
</bean>

Or in a pure Java configuration style:

1
2
3
4
5
6
@Bean
public MessageSource messageSource() {
    ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    messageSource.setBasenames("messages");
    return messageSource;
}

The error message is defined inside the messages.properties file:

1
required.name = Name is required!

To apply this validation, we need to include a reference to the validator in our controller and call the method validate in the controller method which is called when user submits the form:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@RequestMapping(value = "/addPerson", method = RequestMethod.POST)
public String submit(
  @ModelAttribute("person") Person person,
  BindingResult result,
  ModelMap modelMap) {
 
    validator.validate(person, result);
 
    if (result.hasErrors()) {
        return "personForm";
    }
     
    modelMap.addAttribute("person", person);
    return "personView";
}

9.2. JSR 303 Bean Validation

Starting from Spring 3, we can use JSR 303 (via the @Valid annotation) for bean validation. To do this we need a JSR303 validator framework on the classpath. We will use the Hibernate Validator (the reference implementation). Following is the dependency that we need to include in the POM:

1
2
3
4
5
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.1.1.Final</version>
</dependency>

To make Spring MVC support JSR 303 validation via the @Valid annotation, we need to enable the following in our Spring configuration file:

1
<mvc:annotation-driven/>

Or use the corresponding annotation @EnableWebMvc in a Java configuration:

1
2
3
4
5
@EnableWebMvc
@Configuration
public class ClientWebConfigJava implements WebMvcConfigurer {
    // All web configuration will go here
}

Next, we need to annotate the controller method that we want to validate with the @Valid annotation:

1
2
3
4
5
6
7
8
9
10
11
12
13
@RequestMapping(value = "/addPerson", method = RequestMethod.POST)
public String submit(
  @Valid @ModelAttribute("person") Person person,
  BindingResult result,
  ModelMap modelMap) {
  
    if(result.hasErrors()) {
        return "personForm";
    }
      
    modelMap.addAttribute("person", person);
    return "personView";
}

Now we can annotate the entity’s property to validate it with Hibernate validator annotation:

1
2
@NotEmpty
private String password;

By default, this annotation will display “may not be empty” if we leave the password input field empty.

We can override the default error message by creating a property in the resource bundle defined in the validator example. The key of the message follows the rule AnnotationName.entity.fieldname:

1
NotEmpty.person.password = Password is required!

10. Conclusion

In this tutorial we explored the various tags that Spring provides for working with forms.

We also had a look at the tag for validation error displaying and the configuration needed to display custom error messages.

All the examples above can be found in a GitHub project. This is an Eclipse-based project, so it should be easy to import and run as it is.

When the project runs locally, the form example can be accessed at:

springmvc 标签的更多相关文章

  1. ASP.NET MVC View中的标签(tag)

    在编辑View的时候会用到各种HTML标签,如<a>,<input>,<p>等待,这些标签在ASP.NET MVC中都有对应的编程语法,它叫Razor,它是帮助我们 ...

  2. ASP.NET MVC View 和 Web API 的基本权限验证

    ASP.NET MVC 5.0已经发布一段时间了,适应了一段时间,准备把原来的MVC项目重构了一遍,先把基本权限验证这块记录一下. 环境:Windows 7 Professional SP1 + Mi ...

  3. SpringMVC <mvc:view-controller path=""/>标签

    <mvc:view-controller path=""/>标签的作用 对应WEB-INF目录下面的JSP页面,我们知道是不能直接使用URL访问到.需要通过转发的方式, ...

  4. <mvc:view-controller path=""/>标签的作用

    <mvc:view-controller path=""/>标签的作用 对应WEB-INF目录下面的JSP页面,我们知道是不能直接使用URL访问到.需要通过转发的方式, ...

  5. ASP.NET MVC中controller和view相互传值的方式

    ASP.NET MVC中Controller向view传值的方式: ViewBag.ViewData.TempData 单个值的传递 Json 匿名类型 ExpandoObject Cookie Vi ...

  6. MVC模式(Model View Controller)下实现数据库的连接,对数据的删,查操作

    MVC模式(Model View Controller): Model:DAO模型 View:JSP  在页面上填写java代码实现显示 Controller:Servlet 重定向和请求的转发: 若 ...

  7. MVC(Model View Controller)框架

    MVC框架 同义词 MVC一般指MVC框架 MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一 ...

  8. MVC:Controller向View传值方式总结

    Controller向View传值方式总结 总结发现ASP.NET MVC中Controller向View传值的方式共有6种,分别是: ViewBag ViewData TempData 向普通Vie ...

  9. 深入浅出Java MVC(Model View Controller) ---- (JSP + servlet + javabean实例)

    在DRP中终于接触到了MVC,感触是确实这样的架构系统灵活性不少,现在感触最深的就是使用tomcat作为服务器发布比IIS好多了,起码发布很简单,使用起来方便. 首先来简单的学习一下MVC的基础知识, ...

  10. C# -- 等待异步操作执行完成的方式 C# -- 使用委托 delegate 执行异步操作 JavaScript -- 原型:prototype的使用 DBHelper类连接数据库 MVC View中获取action、controller、area名称、参数

    C# -- 等待异步操作执行完成的方式 C# -- 等待异步操作执行完成的方式 1. 等待异步操作的完成,代码实现: class Program { static void Main(string[] ...

随机推荐

  1. 编写可维护的JavaScript----笔记(一)

    1.缩进层级 建议使用4个空格为一个缩进层级,避免使用制表符进行缩进,可以通过配置文本编辑器来改变 缩进层级表示的内容. 2.语句末尾 有赖于分析器的自动分号插入机制(ASI),JavaScript可 ...

  2. RMAN Maintenance

    CROSSCHECK: 确认 rman repository 与 实际的备份集 是否同步. 你可以先使用 LIST 命令查看你之前做的备份的情况, 然后使用 CROSSCHECK 命令来确认这些文件还 ...

  3. Easyui控制combotree只能选择叶子节点

    $(function() { $('#tt').combotree({ url: 'getTree.do', onBeforeSelect: function(node) { if (!$(this) ...

  4. js for in

    JavaScript中for..in循环陷阱 大家都知道在JavaScript中提供了两种方式迭代对象:   (1)for 循环:   (2)for..in循环: 使用for循环进行迭代数组对象,想必 ...

  5. db2 reorg pending

    通常在数据库上线之前,我们都会对数据库做周密的规划,无论在测试阶段还是上线之初,也难免由于需求的更改会对数据中的表做一些更改.而某些alter table语句则会导致该表处于reorg-pending ...

  6. session和cookie的联系与区别

    区别: 1.cookie是存放在浏览器上的,session是存放在服务器上的: 2.cookie不安全,别人可以通过分析本地的cookie并进行cookie欺骗,session比cookie安全: 3 ...

  7. jQery 操作CSS

    jQuery操作CSS也是很方便的,咱先看看这几个常用的方法: addClass():向一个元素添加一个或者多个类. removeClass():从一个元素中删除一个类或多个类. toggleClas ...

  8. linux连接mysql命令

    连接MYSQL: 格式: mysql -h主机地址 -u用户名 -p用户密码 1.例1:连接到本机上的MYSQL 找到mysql的安装目录,一般可以直接键入命令mysql -uroot -p,回车后提 ...

  9. 71、Android上对Cookie的读写操作

    Cookie是为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据,在Android中也经常用到,接下来我们介绍Cookie在Android里是如何进行读写的.   Cookie其实就 ...

  10. Delphi数据库处理

    Delphi数据库处理 第一节 BDE.ADO.InterBase和dbExpress Delphi中处理数据库主要有两种方法,也就是BDE.ADO,从Delphi 6.0开始还加入了一种dbExpr ...