23.5 数据验证
在Spring MVC框架中,同样可以对表单数据进行验证,把错误信息返回页面,提示用户重新输入。Spring MVC框架提供了Validator接口,用户通过实现该接口来对数据进行研制,Validator的代码如下:
package org.springframework.validation;
publicinterface Validator {
boolean supports(Class clazz);
void validate(Object obj, Errors errors);
}
上面代码有两个方法,如下所述。
supports:用来判断参数clazz是否是要验证的Class类。
validate:用来对参数obj进行研制,并把错误信息存入errors对象。
下面通过一个例子来说明如何使用该接口。
【示例23-11】在示例23-6的登录页面中输入userName和password去实现登录。在该例子中,判断用户名是否包含”@”。如果不包含该字符,则提示用户重新输入。编写UserNameValidator.Java,代码如下:
package com.examp.ch23;
import org.springframework.validation.Validator;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Errors;
publicclass UserNameValidator implements Validator {
publicboolean supports(Class clzz) { //重写supports()方法
return LoginBean.class.isAssignableFrom(clzz);
}
publicvoid validate(Object obj, Errors e) {
LoginBean p = (LoginBean)obj;
boolean isvalid = false;
for(int i=0;i<p.getUserName().length();i++){
//遍历字符串,看有没有@字符
if (p.getUserName().charAt(i)==’@’)
isvalid = true; //如果有,invalid为true
}
if (isvalid == false) { //如果isvalid为false,则添加错误信息
e.rejectValue(“userName”, “invalidFormat”,”invalid userName!”);
}
}
}
可以看出,上面代码中UserNameValidator重写了validate()方法。在该方法中遍历所有的字符串,如果没有@字符,添加一条错误信息。接下来在Sping的配置文件中添加配置,如下所示。
<bean id=”userNameValidator”class=”com.examp.ch23.UserNameValidator”>
</bean>
<bean id=”loginController”class=”com.examp.ch23.LoginController”>
<property name=”formView”>
<value>welcomeView</value>
</property>
<property name=”commandClass”>
<value>com.examp.ch23.LoginBean</value>
</property>
<property name=”validator”>
<ref bean=”userNameValidator”/>
</property>
</bean>
可以看出,上面代码中首先用<bean>标签定义UserNameValidator类,然后在loginController中通过<property name=”validator”>定义该类的验证器。使用<ref bean=”userNameValidator”/>引用前面定义的userNameValidator。在浏览器中输入http://localhost:8080/ch23/login.jsp,然后再输入一些错误信息查看验证器的执行效果。
23.6 Spring和Struts 2整合
Spring 和Struts 2都是应用非常广泛的J2EE应用程序框架,Struts 2主要注重的是将视图层和控制层分开,但是不涉及对模型层的优化设计;而Spring除了实现Struts 2的MVC功能外,还可以利用其控制反转的思想实现对模型层的优化,从更深层次去降低应用程序各个组件的耦合程度。本节将结合实例讲解如何实现Spring框架和Struts 2框架的集成使用。
23.6.1 整合原理
Struts 2在发布的时候在其插件包struts-2.1.2\lib中有struts2-spring-plugin-2.1.2.jar,正是它实现了Struts 2和Spring的整合。这个插件覆盖了Struts 2的ObjectFactory,所以在Struts 2创建一个对象的时候,例如Action类,它会先到Struts 2的配置文件去寻找类的名字,然后转到Spring配置文件中去查找名字找到该类。解压struts2-spring-plugin-2.1.2.jar,可以看到有一个struts-plugin.xml文件,其内容如下:
<!DOCTYPE struts PUBLIC
“-//Apache Software Foundation//DTD Struts Configuration 2.0//EN”
“http://struts.apache.org/dtds/struts-2.0.dtd”>
<struts>
<!–定义一个bean:spring,其实现类为StrutsSpringObjectFactory –>
<bean type=”com.opensymphony.xwork2.ObjectFactory” name=”spring”class=
“org.apache.struts2.spring.StrutsSpringObjectFactory” />
<!–使Spring object factory的值为上面定义的bean:spring –>
<constant name=”struts.objectFactory” value=”spring” />
<!–创建spring-default 包,其中包含两个拦截器–>
<package name=”spring-default”>
<interceptors>
<interceptor name=”autowiring”class=”com.opensymphony.xwork2.
spring.interceptor.ActionAutowiringInterceptor”/>
<interceptor name=”sessionAutowiring”class=”org.apache.struts2.
spring.interceptor.SessionContextAutowiringInterceptor”/>
</interceptors>
</package>
</struts>
可以看到,上面代码中用<bean>标签定义了一个name为StrutsSpringObjectFactory的bean对象,用它去替换struts.objectFactory:<constant name=”struts.objectFactory” value=”spring” />。并且定义了一个spring-default包,该包有两个拦截器,如果Action类不是由ObjectFactory创建的话,则这两个插件会自动装配Action类。
23.6.2 整合步骤
Spring和Struts 2的整合其实很简单,下面是整合步骤。
(1)复制jar文件。把struts 2-spring-plugin-2.1.2.jar和spring.jar复制到Web工程的WEB-INF/lib目录下,并且还需要复制commons-logging.jar。
(2)配置struts.objectFactory属性。在文件struts.properties中设置struts.objectFactory属性,使其使用StrutsSpringObjectFactory,代码如下:
struts.objectFactory=spring
当然也可以在struts.xml文件中配置,其中spring就是struts-plugin.xml中定义的bean:spring,代码如下所示。
<struts>
<constant name=”struts.objectFactory” value=”spring”>
</struts>
(3)配置Spring监听器。在web.xml文件中增加如下内容:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</-
listener-class>
</listener>
(4)编写Spring配置文件。默认情况下Spring配置文件的名字为applicationContext.xml,该文件需要保存到Web工程的WEB-INF/目录下。内容实例如下:
<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE beans PUBLIC
“-//SPRING//DTD BEAN//EN”
“http://www.springframework.org/dtd/spring-beans.dtd”>
<beans>
<!–创建一个bean:login,其实现类为LoginAction –>
<bean id=”login”class=”com.examp.ch23.LoginAction”>
<property name=”loginCheck” ref=”loginCheck”/>
</bean>
…
</beans>
在这个文件中定义要加载的类对象。
(5)编写Struts 2配置文件。将Struts 2和Spring集成,其配置文件也有变化,如下所示。
<?xml version=”1.0″ encoding=”UTF-8″ ?>
<!DOCTYPE struts PUBLIC
“-//Apache Software Foundation//DTD Struts Configuration 2.0//EN”
“http://struts.apache.org/dtds/struts-2.0.dtd”>
<struts>
<package name=”ch23″extends=”struts-default” >
<!–class=”login”指向applicationContext.xml文件中定义的bean:login–>
<action name=”LoginAction”class=”login”>
<result name=”input”>/login.jsp</result>
<result name=”success”>/success.jsp</result>
</action>
…
</package>
</struts>
可以看出上面代码中的LoginAction其class属性并没有给出完整路径名,因而objectFactory是找不到该类的,所以就会到applicationContext.xml中去寻找bean的名字为login的类对象。
23.7 一个Spring+Struts 2的开发实例
下面通过一个实例来讲解如何实现Spring和Struts 2的集成使用。
【示例23-12】这个例子通过一个简单的用户登录程序说明如何实现二者的集成。首先创建一个login.jsp用于显示用户登录界面,代码如下:
<%@ page contentType=”text/html;charset=UTF-8″ language=”Java” %>
<%@ taglib prefix=”s” uri=”/struts-tags” %>
<html>
<head>
<title>用户登录界面</title>
<s:head />
</head>
<body>
<table>
<s:form id=”id” action=”login”> <!–将请求提交给login去处理–>
<s:textfield name=”username” key=”username”/>
<s:password name=”password” key=”password1″/>
<s:submit key=”submit”/>
</s:form>
</table>
</body>
</html>
接着,在struts 2.xml文件中定义一个业务控制器loginAction,它用来接收请求并对请求进行处理,配置的代码如下所示。
<action name=”LoginAction”class=”login”>
<result name=”success”>success.jsp</result>
<result name=”error”>login.jsp</result>
</action>
上面的class属性中login并不是一个完整的类名,这个类通过applicationContext.xml的bean标签去配置,代码如下所示。
<bean id=”logincheck”class=”com.examp.ch25.UserCheck”></bean>
<bean id=”login”class=”com.examp.ch25.LoginAction”>
<property name=”ck” ref=” logincheck “></property>
</bean>
可以看出,该文件定义了两个bean,class为实现类,login就是Struts2配置文件中loginAction指向的class属性值,通过property实现名字为check的类:loginCheck的注入。接下来创建一个实现登录检查的接口Check.Java,代码如下所示。
package com.examp.ch25;
publicinterface Check {
boolean checkok(String username,String
password); //声明checkok()方法
}
创建接口的实现类LoginCheck.Java,代码如下所示。
package com.examp.ch25;
publicclass UserCheck implements Check {
publicboolean checkok(String username, String password) {
//重写接口中的checkok()方法
if (username != null && username.equals(“sa”) && password != null
&& password.equals(“sa”)) {
returntrue;
} else {
returnfalse;
}
}
}
下面是业务控制器LoginAction.Java的代码,如下所示。
package com.examp.ch25;
import com.opensymphony.xwork2.ActionSupport;
publicclass LoginAction extends ActionSupport {
private String username; //用于接收表单参数:userName
private String password; /用于/接收表单参数:password
private String msg;
private Check ck; //Check是一个接口类型,属性ck通过Spring的
配置文件注入
publicvoid setCk(Check ck) {
this.ck = ck;
}
public String getUsername() {
return username;
}
publicvoid setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
publicvoid setPassword(String password) {
this.password = password;
}
public String getMsg() {
return msg;
}
publicvoid setMsg(String msg) {
this.msg = msg;
}
public String execute() throws Exception {
if(ck.checkok(username, password)){ //调用ckek的checkok()方法进
行验证
msg=”整合成功,调用Spring容器中的Action”;
return SUCCESS;
}else{
return INPUT;
}
}
}
从上面代码中可以看出,在LoginAction类中并没有用硬编码的形式把属性loginCheck写死,而是定义该属性为Check接口类型,并通过配置文件applicationContext.xml实现LoginCheck的注入。这样可以很方便地实现插拔操作,这也正是Spring AOP思想的灵魂之所在。
运行实例,在浏览器中输入http://localhost:8080/ ch23/login.jsp,用户名和密码都输入sa,显示的结果如图23-6所示。
图23-6 login.jsp运行结果示意图
说明:通过这个示例可以看出,Spring和Struts 2框架的整合主要是使用Struts 2 MVC框架的控制器和视图,使用Spring去定义控制器,并且通过Spring AOP编程的思想进行模型层的优化。在第25章中将会讲解Spring+Struts 2+Hibernate开发,读者将会看到,使用Spring可以很好地优化模型层。
转载于:https://blog.51cto.com/longx/1286713
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/110028.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...