Spring表单
Spring提供了自己的一套表单标签库,通过使用Spring标签库,可以很容易的将模型数据中的表单对象绑定到HTML表单元素中。
使用步骤:
第1步: 编写SpringMVC表单
示例:
<%@taglib prefix="fm" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>添加用户</title>
</head>
<body>
<fm:form action="${pageContext.servletContext.contextPath}/user/add" method="post" modelAttribute="user">
姓名:<fm:input path="name"/><br/>
密码:<fm:password path="password"/><br/>
性别:<fm:radiobutton path="sex" value="男" checked="checked"/>男<fm:radiobutton path="sex" value="女"/>女<br/>
年龄:<fm:input path="age"/><br/>
地址:<fm:select path="address">
<fm:option value="请选择">请选择</fm:option>
<fm:option value="北京">北京</fm:option>
<fm:option value="上海">上海</fm:option>
<fm:option value="南京">南京</fm:option>
</fm:select><br/>
<input type="submit" value="提交">
</fm:form>
</body>
</html>
进入SpringMVC表单后,SpringMVC会从request容器中根据modelAttribute的值,取出1个实体对象.
然后根据实体对象的属性名与表单组件的path值匹配,匹配成功后,将属性值作为表单组件的默认值/初始值.
注意: 若在request容器中找不到modelAttribute指定的对象,将报错。
第2步: 编写进入SpringMVC表单的controller方法
Actioncontroller中提供SpringMVC表单绑定的对象.[在request容器中,存入实体类对象]。
建议方式
@GetMapping("/映射路径")
public String Action方法A(@ModelAttribute 实体类名 参A){省略}
如:
@GetMapping("/add")
进入表单页面的方法
public String test1(@ModelAttribute User user){
System.out.println("test1()方法执行");
return "add";
}
在方法参数上添加ModelAttribute 注解,可以把该参数添加在model模型中。
第3步: 访问controller方法,进入SpringMVC表单
首先访问 进入表单页面的controller方法,然后由方法内转发到SpringMVC表单页.
注意: 不能直接访问SpringMVC表单页。
@PostMapping("/add")
处理表单提交过来的数据的方法
public String test2(User user){
System.out.println("test2()方法执行");
System.out.println(user);
user.setName("李四");
return "add";
}
把表单页面和提交表单页面的URL地址设成相同的,如”/user/add“,通过method属性的值是GET还是POST就可以确定需要进入表单控制器的哪个接口进行请求处理。fm:from标签中也可以不指定action属性,因为在不指定表单要提交的URL地址时,会自动以获取表单页面的URL即 (/user/add)为目标进行提交。
数据效验
数据合法性是每个web项目必不可少的工作。
开发步骤
备注: SpringMVC数据校验需要基于SpringMVC表单实现.
JSR303注解
根据口以上示例添加数表单效验:
修改User类为需要添加数据验证的属性添加效验注解。
public class User {
private Integer id;
@NotEmpty(message = "姓名不能为空")
private String name;
@NotEmpty(message = "密码不能为空")
@Length(min = 6,max = 12,message = "密码在6~12位之间")
private String password;
@NotEmpty(message = "性别不能为空")
private String sex;
@Max(value = 99,message = "年龄在18~99之间")
@Min(value = 18,message = "年龄在18~99之间")
private Integer age;
@NotEmpty(message = "地址不能为空")
private String address;
通过在controller处理方法的入参上标注Vaild注解:
@PostMapping("/add")
public String test2(@Valid User user, BindingResult result){
System.out.println("test2()方法执行");
判断提交过来的数据是否有错误
if (result.hasErrors()){
有错误跳转到add.jsp页面显示错误
return "add";
}
System.out.println(user);
跳转到成功页面
return "test2";
}
在上述代码中,通过为入参对象user添加Vaild注解,就可以调用效验框架根据注解声明的效验规则进行效验,效验的结果会存入后面紧跟的入参对象中即(result)这个入参对象必须是BindingResult 或Error类型,
在表单上显示错误信息:
<html>
<head>
<title>添加用户</title>
</head>
<body>
<fm:form action="${pageContext.servletContext.contextPath}/user/add" method="post" modelAttribute="user">
姓名:<fm:input path="name"/><fm:errors path="name"/> <br/>
密码:<fm:password path="password"/><fm:errors path="password"/><br/>
性别:<fm:radiobutton path="sex" value="男" checked="checked"/>男<fm:radiobutton path="sex" value="女"/>女<fm:errors path="sex"/><br/>
年龄:<fm:input path="age"/><fm:errors path="age"/> <br/>
地址:<fm:select path="address"><fm:errors path="address"/>
<fm:option value="请选择">请选择</fm:option>
<fm:option value="北京">北京</fm:option>
<fm:option value="上海">上海</fm:option>
<fm:option value="南京">南京</fm:option>
</fm:select><br/>
<input type="submit" value="提交">
</fm:form>
</body>
</html>
文件上传
开发步骤:
示例:
在SpringMVC配置文件定义上传解析器
<!--配置文件上传的解析器-->
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
<property name="maxUploadSize" value="50000000"/>允许文件上传的大小
<property name="defaultEncoding" value="UTF-8"/>设置默认编码
<property name="uploadTempDir" value="uploadFile"/>设置上传文件存储目录
</bean>
</beans>
编写提交文件的JSP页面,必须设置enctype="multipart/form-data"属性
<html>
<head>
<title>文件上传</title>
</head>
<body>
<form action="${pageContext.servletContext.contextPath}/user/upload" method="post" enctype="multipart/form-data">
文件:<input type="file" name="uploadfile"><br/>
<input type="submit" value="提交">
</form>
</body>
</html>
编写处理文件提交的controller方法,通过MultipartFile对象获得字节输入流
@PostMapping("/upload")
public String test(@RequestParam("uploadfile") MultipartFile multipartFile, HttpServletRequest request, Model model) throws IOException {
System.out.println("文件名:"+multipartFile.getOriginalFilename());
System.out.println("文件大小:"+multipartFile.getSize());
System.out.println("文件类型:"+multipartFile.getContentType());
//拿到文件后缀
String houzhui = FilenameUtils.getExtension(multipartFile.getOriginalFilename());
//根据UUID生成新的文件名别忘了加后缀
String newName = Tool.getUUID()+"."+houzhui;
//拿到文件的根目录
String rootPath = request.getServletContext().getRealPath("/");
//相对路径,用于保存到数据库,以后还可以读取出来显示
String xiangduiPath = "/uploadFile/"+newName;
//拿到完整路径
String fullPath = rootPath+xiangduiPath;
model.addAttribute("imgpath",xiangduiPath);
/*System.out.println(fullPath);
System.out.println(rootPath);*/
//上传文件
multipartFile.transferTo(new File(fullPath));
return "test";
}
上传成功跳转到新的页面显示图片:
<html>
<head>
<title>显示图片</title>
</head>
<body>
<img width="200px" src="${pageContext.servletContext.contextPath}/${imgpath}">
</body>
</html>
还可以一次上传多个文件:
<html>
<head>
<title>上传多个文件</title>
</head>
<body>
<form action="${pageContext.servletContext.contextPath}/user/upload2" method="post" enctype="multipart/form-data">
文件:<input type="file" name="uploadfile2"><br/>
<input type="file" name="uploadfile2"><br/>
<input type="submit" value="提交">
</form>
</body>
</html>
@PostMapping("/upload2")
public String test2(@RequestParam("uploadfile2") MultipartFile[] multipartFile, HttpServletRequest request, Model model) throws IOException {
for (MultipartFile multipartFile1 : multipartFile){
//拿到文件后缀
String houzhui = FilenameUtils.getExtension(multipartFile1.getOriginalFilename());
//根据UUID生成新的文件名别忘了加后缀
String newName = Tool.getUUID()+"."+houzhui;
//拿到文件的根目录
String rootPath = request.getServletContext().getRealPath("/");
//相对路径,用于保存到数据库,以后还可以读取出来显示
String xiangduiPath = "/uploadFile/"+newName;
//拿到完整路径
String fullPath = rootPath+xiangduiPath;
model.addAttribute("imgpath",xiangduiPath);
/*System.out.println(fullPath);
System.out.println(rootPath);*/
//上传文件
multipartFile1.transferTo(new File(fullPath));
}
return "test2";
}
只需把MultipartFile对象改为数组就好了。