视图
在http请求到响应的整个过程中,涉及视图的过程有:控制器将模型,请求,视图名发送回DispatcherServlet
,DispatcherServlet将使用视图解析器来实现视图的实现,视图使用模型的数据渲染输出。视图名即在控制器方法的返回值,只不过这不是最终的视图名,它还需要加上视图解析器中特定的前缀和后缀。
视图解析器
SpringMvc定义了ViewResolver接口,接口接受resolveViewName()方法传入的一个视图名和Locale对象,返回一个View的实现,View接口是接受模型以及Servlet的Request和Response对象,并将输出结果渲染到response中。即将传入的逻辑视图名渲染为响应中实际的物理视图。
对于视图解析器,Spring提供了多个内置的实现。Spring自带13个视图解析器:
eg:
BeanNameViewResolver | 将视图解析为Spring应用上下文中的bean,bean的ID与视图名字相同 |
InternalResourceViewResolver | 将视图解析为Web应用的内部资源(一般为JSP) |
JasperReportsViewResolver | 将视图解析为JasperReports定义 |
...... | ...... |
InternalResourceViewResolver解析器
InternalResourceViewResolver解析器会将视图解析为JSP文件,如果jsp文件中包含JSP标签库,则会将视图解析为JstlView形式的JSP文件,从而将JSTL本地化和资源bundle变量暴露给JSTL的格式化和信息标签。有些视图解析器会直接将逻辑视图名映射到特定的View接口实现,而InternalResourceViewResolver解析器会使用特定的规则将逻辑视图名映射为实际的视图资源路径。从解析器的配置(XML),也可以使用注解的方式,我们可以看出:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
它会对传入的逻辑视图名添加前缀和后缀,前缀确定其资源的路径,后缀确定资源的类型。
JSTL的格式化标签需要一个Locale对象,用来恰当的格式化低于相关的值,信息标签借助Spring的信息资源和Locale,可以选择合适的信息渲染到HTML中,通过解析Jstlview,JSTL能够获取Locale对象以及Spring中配置的信息资源。如果InteralResourceViewResolver将视图解析为JstlView的话,我们需要设置它的viewClass属性。
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
</bean>
标签的作用是可以避免在脚本块中直接使用Java代码,Spring提供了两个标签库,一个是用来渲染HTML表单的标签,这些标签绑定Model中的某个属性,另一个则包含了一些工具类标签。
Spring的表单绑定JSP标签库包含了14个标签,大部分用于渲染HTML中的表单标签,他们会绑定模型中的对象,能够根据模型中对象的属性填充值。注意,在使用前需要对其进行声明:
<sf:form method="POST" commandName="User">
Name : <sf:input path="name" />
Email : <sf:input path="email"/>
Password:<sf:password path="password" />
<input type="submit" value="login"/>
</sf:form>/>
commandName属性用于构建针对某个模型对象的上下文信息,这里使用User对象,因此在模型中必须有一个key为User的对象,否则表单不能正常渲染,eg:
@RequestMapping(method=RequestMethod.GET)
public String printHello(ModelMap model) {
model.addAttribute("message","hello spring mvc .");
model.addAttribute(new User());
return "hello";
}
在进行渲染的时候,<sf:input>会被渲染成一个HTML<input>标签,type属性设置为text,其path属性对应这<input>标签的value属性。spring的表单绑定能带来一些提升,在效验失败后,表单中会预先填充之间输入的值,Spring3.1以后,我们可以为<sf:input>标签指定type属性,这样可以由多个类型选择。
<s:errors>用来展现错误,当指定的属性没有错误的时候,它不会渲染任何内容,当有错误的话,它会在一个HTML<span>标签中显示错误信息,也可以为sf:error设置css属性,使用cssClass属性即可,这时,属性的errors的<span>会有一个值为error的class属性。使用css设置样式的格式为:span.error{xxx}
<sf:errors path="name" cssClass="error"/>
上述方式,如果有错误,会在标签的一侧产生错误,但是对于布局会有影响,另一种处理效验错误方式就是将所有的错误信息在一个地方进行显示,可以使用如下方式:
<sf:form method="POST" commandName="user" >
<sf:errors path="*" element="div" cssClass="errors"/>
...
</sf:form>
这里的Path="*",即对所有属性的错误都进行显示,element="div",即对于错误的显式,我们放在一个div中。设置css样式可以在div中进行设置,eg:div.errors{...} 为了方便,我们也可以使用label标签。即<sf:label>标签,它也会绑定一个对象,使用path来指定它属于模型对象中的哪个属性,eg:
<sf:form method="POST" commandName="User">
<sf:lable path="Name" cssErrorClass="error"> name</sf:lable> : <sf:input path="Name" cssErrorClass="error"/> <br/>
...
</sf:from>
如果没有效验错误的话,它会渲染为:
<label for="name">name </label>
如果它所绑定的属性有任何错误的话,在渲染得到的<label>元素中,class属性会被设置为error.与之类型,<sf:input>标签的cssErrorClass属性会被设置为error.eg:
<label for="name" class="error">name</label>
为了使错误信息更易读,我们可以在属性文件中使用验证:eg:
@NotNull
@Si***=5,max=16,message="{name.size}")
private String name;
@NotNull
@Si***=5,max=20.message="{password.size}")
private String password;
将@Size注解的message设置为一个字符串,使用大括号括起来,如果没有大括号的话,message中的值将会作为展现给用户的错误信息,使用大括号,则值就是属性文件中的某一个属性,该属性包含了实际的信息。例如,创建一个名为:ValidationMessages.properties文件,将其放在根路径下:
name.size=name must be between {min} and {max} characters long.
password.size = password must be between {min} and {max} characters long.
ValidationMessages.properties文件中的每条信息的key值对应于注解中message属性占位符的值。 <s:url>标签
用于创建URL,然后将其赋值给一个变量或者渲染到响应中,它是JSTL中<c:url>标签的替代者,<s:url>会接受一个相对于Servlet上下文的URL,并在渲染的时候,预先添加上Servlet上下文路径,eg:
<a href = "<s:url href="hello/test"/>" > test </a>
如果Servlet的上下文名为item,则响应中将会渲染下面的html
<a href = "/item/hello/test">test</a>
我们在使用的时候,就不用担心Servlet上下路路径的问题。我们也可以将其赋值给一个变量:
<s:url href="/hello/test" var="hello"/>
<a href="${hello}"> test </a>
默认情况下,URL是在页面工作域内创建,但可通过设置scope属性,同时,如果希望在URL中添加参数,可以使用<s:param>标签
<s:url href="/hello/test" var="hello" >
<s:param name="min" value="20"/>
<s:param name="max" value="100"/>
</s:url>
创建带路径参数的URL:
<s:url href="/hello/test/{opp}" var="test">
<s:param name="insert" value="land"/>
</s:url>
参考《Spring实战》(第四版)