SpringMVC-4

springmvc的标签:

通过springmvc的标签可以实现将模型数据中的属性和HTML表单绑定,用来实现表单数据更便捷的编辑和表单值的回显。
<form:form>无需通过action属性指定表单提交的URL
可以通过modelAttribute属性指定绑定的模型数据,如果没有指定绑定的模型数据,则默认的从request属性范围中去查找,找一个command Bean对象,如果这个对象也不存在则会抛出异常。
SpringMVC提供了多个表单组件的标签例如:
<form:input/>用以绑定表单字段的属性值,他们共有的属性如下:
path:表单字段,对应HTML的name属性。支持级联属性
htmlEscape:是否对表单值的HTML特殊字符进行转换
cssClass:表单组件对应的CSS样式类名

<form:input>、<form:password>、<form:hidden>、<form:textarea>:分别对应着HTML表单的text password hidden
textarea
例子
(1)input的代码

<form:form action = "emp" method = "POST" modelAttribute="employee">
  		Name :<form:input path="empName"/>
  		<form:errors path ="empName"></form:errors><br/>
  		<%
  			Map<String , String> sexs = new HashMap<String ,String>();
  			sexs.put("1", "male");
  			sexs.put("0", "female");
  			request.setAttribute("sexs",sexs);
  		 %>
  		 <c:if test="${employee.empId!=null}">
  		 	<form:input path="empId"  type = "hidden" value = "${employee.empId}"/>
  		 	<input  type= "hidden"  name = "_method" value= "PUT" >
  		 </c:if>
  		 email:<form:input path="email"/>
  		 <form:errors path = "email"></form:errors><br/>
  		 Sexs:<form:radiobuttons path="empSex" items="${sexs}"/><br/>
  		 depts:<form:select path="dept.deptId" items="${depts}" itemLabel="deptName"
  		 		itemValue="deptId"></form:select><br/>
  		 birday:<form:input path="birDate"/>
  		  
  		<input type = "submit" value = "submit">
  	</form:form>

(2)handler处理跳转的方法:

	@RequestMapping(value = "/emp")
	public String input(Map<String, Object> map){
		employee  emp = new employee();
		map.put("employee", emp);
		map.put("depts", deptDao.getAll());
		return "input" ; 
	}

注:(1)我们使用SpringMVC提供的form时我们需要导入:

<%@taglib  prefix= "form" uri="http://www.springframework.org/tags/form"%>

(2)我们在跳转请求的时候需要在页面中传递一个form表单需要解析的类型,map.put("employee", emp);就是这个用处。

处理静态资源
优雅的REST风格的URI是不希望我们的资源带有后缀名。
如果将DospatcherServlet请求映射为/,SpringMVC将捕获WEB容器的所有请求,包括静态资源的请求,SpringMVC会将他们当成一个普通的请求处理,因此会出现找不到的错误。

可以在SpringMVC的配置文件中配置mvc:default-servlet-handler/

springMVC 数据绑定流程

数据绑定流程:
1.SpringMVC将ServletRequest对象以及目标方法中的参数实例传递给WebDataBinderFactory对象,用来创建DataBinder实例化对象
2.DataBinder调用装配在SpringMVC上下文中的ConversionService组件进行数据类型的转换,数据格式化的工作。将Servlet中的请求信息填充到方法的参数中。
3.调用Validator组件对已经绑定了请求消息的参数对象进行数据的合法性的校验并最终生成数据绑定结果BindingData对象
4.SpringMVC抽取BindingResult中的参数对象和校验错误对象将他们赋值给处理方法的参数。

数据转换:

SpringMVC上下文中内建了很多的处理器,基本上满足了我们需要使用到的转换。

<mvc:annotation-driven/>

因为<mvc:annotation-driven/>标签会自动注册RequestMappingHandlerMapping、RequestMappingHandlerAdapter和ExceptionHandlerExceptionResolver这三个bean
同时,还提供以下的支持:
1.支持使用ConversionService实例对表单参数进行类型转换
2.支持使用@NumberFormat annotation @DataTimeFormat注解完成数据类型的格式化
3.支持使用@Valid注解对JavaBean实例进行JSR303验证
4.支持使用@RequestBody和@ResponseBody注解

数据格式化

对属性对象的输入或者是输出进行格式化,从器本质上来讲依然属于类型转换的范畴。
Spring在格式化模块中定义了一个实现ConversionService接口的FormattingConversonService实现类,该实现类扩展了GenericeConversionService,因此他既具有类型转换的功能,又具有格式化的功能。
FormattingConversonService拥有一个叫做FormattingConversonServiceFactoryBean这样的一个工厂类,用于在Spring上下文当中构造FormattingConversonService

在FormattingConversonServiceFactoryBean工厂类中已经注册了:
NumberFormatAnnotationFormatterFactory:支持对数字进行格式的@NumberFormat注解
JodaDateTimeFormatAnnotationFormatterFactory:支持对日期类型的属性使用@DateTimeFormat注解

@DataTimeFormat
可以对java.util.Date、java.util.Calendar、java.long.Long时间类型进行标注
1.pattern:类型为字符串。指定解析或者是格式化的数据的格式
2.iso:类型是DataTimeFormat.ISO。指定解析或者是格式化数据的ISO模式,包括四种:ISO.NONE(不推荐使用) 默认的是ISO。DATE(yyyy-MM-dd) ISO.TIME(hh:mm:ss:SSS) ISO.DATE_TIME(yyyy-MM-dd hh:mm:ss:SSS)
3.style:字符串类型的,通过指定日期时间格式,有两位字符组成,第一位字符表示日期的格式,第二位字符表示时间的格式。S:短日期/时间的格式,M:中日期/时间的格式,L:长日期/时间的格式,F:完整日期/时间的格式,-:忽略日期/时间的格式
@NumberForma
数值格式化
@NumberFormat可以对数字类型的属性进行标注,它拥有两个互斥的属性。
1.style:类型是NumberFormat.Style.用于指定样式类型,包括三种:Style.NUMBER(正常的数字类型) Style.CURRENCY(货币类型) Style.PERCENT(百分数类型)

2.pattern:;类型为String,自定义的样式
例如pattern="#,###"
例子1:
在员工属性定义data类型的数据如果是直接在form表单中输入“1990-10-21”springMVC是无法识别这个数据的所以要使用@DateTimeFormat(pattern="yyyy-mm-dd")注释这样数据传递之后SpringMVC后就可以进行处理了。

	@DateTimeFormat(pattern="yyyy-mm-dd")
	private Date birDate;

数据校验:

1.springMVC还支持对JRE303的支持:可以在需要校验的参数前面写上@springmvc就自动开始校验,需要注意的是当对象需要被处理的时候需要在对线前面写上@Valid 注解。

2.当一个属性校验失败之后,检验框架会为该属性生成4个消息代码,这些代码以校验注解类型为前缀,结合ModelAttribute、属性名以及属性类型名生成多个对应的消息代码:例如User类中的password属性标注了一个@Pattern注解,当该属性值不满足@Pattern定义的规则时,就会产生以下4个错误代码:
1.Pattern.user.password
2.Pattern.password
3.Pattern.java.lang.String
4.Pattern
例子:
(1)employee的部分属性如下:

	@NotEmpty
	private String empName  
	@Email
	private String email ;

(2)input部分表单如下:

 		email:<form:input path="email"/>
  		 <form:errors path = "email"></form:errors><br/>
  		 Name :<form:input path="empName"/>
  		<form:errors path ="empName"></form:errors><br/>

(3)handler代码如下:

	@RequestMapping(value = "/emp",method = RequestMethod.POST)
	public String save(@Valid employee employee, BindingResult result ,Map<String, Object> map){
		System.out.println(employee);
		if(result.getErrorCount()>0){
			System.out.println("出错了");
			for(FieldError error: result.getFieldErrors()){
				System.out.println(error.getField()+""+error.getDefaultMessage());
			}
			map.put("depts", deptDao.getAll());
			return "input";
		}
		empDao.save(employee);
		return "redirect:emps";
	}

注意:
(1)我们需要导入Valid 的jar包;
(2) BindingResult result对象用来储存传递过来的错误信息。
(3)当我们使用SpringMVC标签去显示错误信息的时候,SpringMVC或查看WEB上下文中是否装配了对应的国际化消息,如果没有,则显示默认的错误消息,否则使用国际化消息。
如果数据类型转换或者数据格式转换发生错误的时候,或者有参数不存在或者调用处理方法的时候发生错误,都会在隐含对象中创建错误消息。错误代码的前缀说明如下:
1.required:必要的参数不存在。比如@RequiredParam(“param1”)标注一个参数,但是该参数不存在
2.typeMismatch:在数据绑定时,发生数据类型不匹配的问题。
3.methodInvocation:SpringMVC在调用处理方法的时候发生了错误。

HttpMessageConverter接口

此接口是Spring3.0新添加的一个接口,负责将请求信息转换为一个对象(类型就是T指定的类型),将对象输出为响应信息。
(1)HttpMessageConverter接口定义了如下的方法:
1.Boolean canRead(Class<?> clazz,MediaType mediaType):指定转换器可以读取的对象类型,即转换器是否可将请求信息转换为claszz类型的对象,同时指定支持MIME的类型。
2.Boolean canWrite(Class<?> clazz,MediaType mediaType):指定转换器是否可将clazz类型的对象写到响应中,响应的类型支持的媒体类型在mediaType当中指定。
3.List getSupportMediaType():获取该转换器支持的媒体类型
4.T read(Class<? extends T> clazz,HttpInputMessage inputMessage):将请求信息转换为T类型的对象
5.void write(T t,MediaType contentType,HttpOutputMessage outMessage):将T类型的对象写到响应流中,同时指定相对应的媒体类型。

(2)如何使用HttpMessageConverter接口

Spring提供了两种途径:
1.使用@RequestBody/@ResponseBody对处理方法进行标注
2.使用HttpEntity/ResponseEntity作为处理方法的参数或者是返回值
当我们的控制器处理方法使用到@RequestBody/@ResponseBody或者HttpEntity/ResponseEntity时Spring首先根据请求头或者响应头的Accept属性选择匹配的HttpMessageConverter。进而根据参数类型或者是泛型类型的过滤得到匹配的HttpMessageConverter。
如果找不到可用的HttpMessageConverter将会报错。

处理JSON:

1.加入Jar包
2.编写目标方法,使其返回Jason格式的数据
3.在方法上添加@ResponseBody注解
例子:
(1)引入jar包
(2)在handler编写如下方法:

	@Autowired
	private EmpDao empDao ;
	@RequestMapping(value = "/testJSON")
	//将返回的Collection<employee>转换成了json格式的数据
	@ResponseBody
	public  Collection<employee> testJSON(){
		return empDao.getAll();
	}

(3)test.jsp代码

	<script type="text/javascript" src= "scripts/jquery.js">	   </script>
	<script type="text/javascript">
		$(document).ready(function(){
			var a = $("#a1");
			var href = a.attr("href");
			a.click(function(){
				$get(href,{}, function(data){
					for(var i = 0; i<data.length;i++){
						var emp = data[i];
						id =emp.empID; 
						name = emp.empName;
						alert(id);
						alert(name);
					}
				});
				return false ;
			});
		});
	</script>
	<a  id = "a1" href = "testJSON"> testJSON</a><br/>

注:由于导入了 jQuery文件需要在springmvc.xml中配置

<mvc:annotation-driven></mvc:annotation-driven>

用RequestBody与reponse实现文件的下载

(1)首先在test.jsp中写入表单元素代码如下

<form action="filetest" method = "post" enctype="multipart/form-data">  	
  		<input type = "file" name ="file">
  		<input type= "text" name = "desc">
  		<input type= "submit" value= "loadon">
  	</form>

(2)在handler方法中写处理方法:

@RequestMapping("filetest")
	@ResponseBody
	public String filetest(@RequestBody String body){
		System.out.println(body);
		return "hello"+new Date();
		
	}

注:需要将表单元素的enctype更改为multipart类型,才可以处理上传的文件。

使用ResponseEntity实现文件的下载功能

(1)handler代码如下:

@RequestMapping("/testdown")
	public ResponseEntity<byte[]> testResponseEntity(HttpSession httpSession) throws IOException{
		//创建一个byte数组用来接收文件
		byte[] body = null;
		//获得上下文路径
		ServletContext servletContext = httpSession.getServletContext();
		//获得输入流数据
		InputStream in = servletContext.getResourceAsStream("/file/1.txt");
		//读取数据流文件
		body = new byte[in.read()];
		//设置http响应头文件
		HttpHeaders httpHeaders = new HttpHeaders();
		httpHeaders.add("Content-Disposition", "attachment;filename=file/1.txt");
		//设置http相应状态
		HttpStatus httpStatusCode = HttpStatus.OK;
		//创建ResponseEntity对象
		ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(body,httpHeaders, httpStatusCode);
		return responseEntity ;
	}

(2)test.jsp文件代码:

<a href = "testdown" > testdown</a>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值