Struts2(2)

来源:互联网 发布:java 捕获异常 编辑:程序博客网 时间:2024/06/08 23:59

一、自定义一个结果类型

1.编写一个类,实现com.opensymphony.xwork2.Result接口。


                          例子  :输出验证码在方法中可以通过ServletAPI请求request response完成功能

//自定义的结果视图类型     输出一副验证码图像public class CaptchaResult implements Result {<span style="color:#3366ff;">//图片的宽高  这里给了set方法           在struts.xml配置文件里面就可以注入属性了</span>private int width = 80;private int height = 25;public int getWidth() {return width;}public void setWidth(int width) {this.width = width;}public int getHeight() {return height;}public void setHeight(int height) {this.height = height;}public void execute(ActionInvocation arg0) throws Exception {// 自定义结果需要response 这里通过ServletActionContext获取HttpServletResponse response = ServletActionContext.getResponse();// 产生由4位数字构成的验证码int length = 4;String valcode = "";Random rd = new Random();for (int i = 0; i < length; i++)valcode += rd.nextInt(10);BufferedImage img = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);// 获取一个GraphicsGraphics g = img.getGraphics();// 填充背景色g.setColor(Color.WHITE);g.fillRect(1000, 1000, width, height);// 填充干扰线200for (int i = 0; i < 5000; i++) {g.setColor(new Color(rd.nextInt(100) + 155, rd.nextInt(100) + 155,rd.nextInt(100) + 155));g.drawLine(rd.nextInt(width), rd.nextInt(height),rd.nextInt(width), rd.nextInt(height));}// 绘制边框g.setColor(Color.GRAY);g.drawRect(0, 0, width - 1, height - 1);// 绘制验证码Font[] fonts = { new Font("隶书", Font.BOLD, 18),new Font("楷体", Font.BOLD, 18), new Font("宋体", Font.BOLD, 18),new Font("幼圆", Font.BOLD, 18) };for (int i = 0; i < length; i++) {g.setColor(new Color(rd.nextInt(150), rd.nextInt(150), rd.nextInt(150)));g.setFont(fonts[rd.nextInt(fonts.length)]);g.drawString(valcode.charAt(i) + "", width / valcode.length() * i+ 2, 18);}// 输出图像g.dispose();ImageIO.write(img, "jpeg", response.getOutputStream());}
                2.在struts.xml中声明自定义结果类型

<package name="<span style="color:#3333ff;">mystruts-default</span>" extends="struts-default"><!-- 声明结果类型 --><result-types><result-type name="captcha" class="com.test.result.CaptchaResult"></result-type></result-types></package>
                3.使用        如果自定义结果视图大家都要用时 就可以这样  继承的是声明的包  

<package name="p1" extends="<span style="color:#3333ff;">mystruts-default</span>">   <action name="captcha">    <result name="success" type="captcha">   <span style="color:#ff0000;">  <!-- 注入参数  验证动作里面已有宽高的set方法 -- captcharesult.setheight() 这样></span>  <span style="color:#3333ff;">  <param name="height">100</param>    <param name="width">100</param></span>        </result>   </action></package>
 

二、Action接收请求参数 

作为MVC框架  必须要负责解析HTTP请求的参数  然后封装到javaBean   Struts2提供了非常强大的类型转换机制用于请求数据到model对象的封装

       (一)封装请求参数有三种方式   常用第二或三种          

     1.方式一、用动作类作为模型对象  直接封装请求的参数     

注:静态参数注入是由一个名字为staticParams拦截器完成的。

a. 首先一个模型    set   get略了   请求来的参数可以在execute里处理  

public class Person extends ActionSupport {private String username;private String password;private String nickname;public String execute() throws Exception {System.out.println("username:"+username+"password:"+password+"nickname:"+nickname);return SUCCESS;}}
              b、注入动态(用户输入)参数

                             jsp:

编写原则:表单的输入域的名称和动作类中的属性名(gettersetter)保持一致。

  <form action="${pageContext.request.contextPath}/act1" method="post">    用户名:<input type="text" name="username"/><br/>    密码:<input type="password" name="password"/><br/>    呢称:<input type="text" name="nickname"/><br/>    <input type="submit" value="注册">   </form>
c、注入静态参数   如果用户没有输入呢称的值    就是自己静态注入的游客

 <action name="act1" class="com.test.action.Person">      <span style="color:#3333ff;"> <!-- 这里注入参数  相当于Person.setNickname("游客") --></span>          <param name="nickname">游客</param>      </action>

  2、方式二 动作类和模型对象分离

a. Student模型

public class Student extends ActionSupport {private String username;private String password;private String nickname;

   b.动作

public class StudentAction {private Student student=new Student();public Student getStudent() {return student;}public void setStudent(Student student) {this.student = student;}public String save() {<span style="color:#3333ff;">//在实际操作中这里就可以实现以下功能// 把表单数据封装到模型对象中// 调用Service把Student的数据保存到数据库中</span>System.out.println(student.getUsername() + student.getPassword()+ student.getNickname());return "none";}}

  c、struts.xml的配置

<action name="act2" class="com.test.action.StudentAction" method="save"></action>
d、jsp重要的是name名 是模型的属性 相当于 student.setusername

<span style="color:#3333ff;"> </span><form action="${pageContext.request.contextPath}/act2" method="post">    用户名:<input type="text" name="<span style="color:#ff0000;">student.username</span>"/><br/>    密码:<input type="text"  name="student.password"/><br/>    呢称:<input type="text"  name="student.nickname"/><br/>    <input type="submit" value="注册"/>    </form>
总结:框架会探测student这个模型是否为空 如果为空 注入他的实例 分别调用对象的属性 注入值 会调用3次getStudent 来分别注入值 


3、(模型和动作分开) 模型驱动 动作类要实现 ModelDriven

a.模型

public class Customer {private String username;private String password;private String nickname;
b、动作类

public class CustmomerAction implements ModelDriven<Customer> {private Customer customer = new Customer();// 模型一定要new出来public Customer getCustomer() {return customer;}public void setCustomer(Customer customer) {this.customer = customer;}public String save() {System.out.println(customer);return "success";}// 调用动作方法前,框架会先调用这个方法// 这个方法不会实例化customerpublic Customer getModel() {return customer;}

c、jsp

 <form action="${pageContext.request.contextPath}/act3" method="post">   用户名:<input type="text" name="username"/><br/>   密码:<input type="password" name="password"/><br/>   呢称:<input type="text" name="nickname"/>   <input type="submit" value="注册"/>

注:实际上是一个名字为modelDriven拦截器完成的。该拦截器会在调用动作方法前,调用getModel(),得到模型对象,他接着把该模型对象压到了值栈的栈顶。表单的username的值,框架就会调用栈顶对象的setUsername方法。

关键点:实现ModelDriven接口;模型对象要自己实例化;


(二)封装集合或者map(实际开发很少用的)

封装list

name的[]就是代表存在一个集合里

封装map


三、类型转换(开发中几乎不用的 struts自带有 需要理解)

两种情况 1.用户输入的都是字符串 2.显示出的都是字符串 

类型转换一般用于 String转换其他类型(用于存储) 其他类型转换String(用于显示)


Struts2类型转换的继承体系


1.自定义类型转换器

a、编写一个类 继承strutsTypeConverter

//自定义类型转换器://String--->java.util.Date   MM/dd/yyyy//java.util.Date----->StringMM/dd/yyyypublic class MyConvertor extends StrutsTypeConverter {// 自己定义date格式private DateFormat df = new SimpleDateFormat("MM/dd/yyyy");// string----------------------->java.util.Date MM/dd/yyyy 字符串转date// values:用户输入的值// toClass:目标类型public Object convertFromString(Map context, String[] values, Class toClass) {if (toClass == Date.class) {//判断请求的值是否dateif (values != null && values.length > 0) {String sdate = values[0];try {return df.parse(sdate);} catch (ParseException e) {throw new RuntimeException(e);}}}return null;}// java.util.Date--------------->Stringpublic String convertToString(Map context, Object o) {if(o instanceof Date){Date d =(Date)o;return df.format(d);}return null;}<span style="color:#3333ff;"></span>

b、注册类型转换器 类型转换器分2种

b1、局部转换器 给某个动作用的

在动作类所在包下 创建一个 动作类名-conversion-properties的配置文件

指定birthday这个属性转换

b2、全局类型转换器:给所有动作用 在构建路径 src目录下建立名称为xwork-conversion.properties的配置文件,按照自己的目标类型进行转换器的配置

2、转换失败的时的回显和错误提示

前提是 动作类需要继承ActionSupport类

出现转换失败时,由一个名字为conversionError拦截器负责处理的。会把错误信息封装起来,并且转向一个叫做input的逻辑视图(用于回显数据)。

更改默认的提示错误

a、在动作类中建立一个 动作类名-properties的配置文件内容如下



四、数据校验(开发经常写)

校验分种 客户端校验:javaScript完成

服务器端校验:代码

实际开发 是2种校验都需要写

前提:动作类需要继承ActionSupport 验证是由Validation(声明式校验)、workflow(错误提示)完成的

a、编程式校验:动作类中写代码

a.1针对动作类中的所有动作方法进行校验 在动作类中,覆盖掉validate方法

a.2针对动作类中的指定方法进行校验 有2种方式

方式一:比较麻烦

方式二:使用注解,简单

b、声明式校验(推荐):写配置文件

把校验规则和消息提示放到配置文件中。

b.1针对动作类所有方法进行校验

在动作列类所在的包中,建立名字为 动作类名-validation.xml配置文件 内容如下

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE validators PUBLIC  "-//Apache Struts//XWork Validator 1.0.3//EN"  "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"><validators><!--   方式一: 给一个字段指定多个验证器  type是框架提供的验证器<field name="name"><field-validator type="requiredstring">   <message>名字不能为空</message></field-validator></field>  -->   <!-- 方式二   验证器验证字段 还可以验证非字段的验证 -->  <validator type="requiredstring">    <param name="fieldName">age</param>    <message>年龄不能为空</message>  </validator></validators>

b2、针对指定方法进行效验 

方式一 用 @skipValidation 注解 

方式二 比较麻烦

在动作类的包下新建 动作类名-动作别名(就是struts.xml配置文件 Action动作给方法配的name名-validation.xml 写法跟针对所有方法一样

Struts2框架提供的内置验证器 可以参考Struts2解压出来的xwork.jar包下的

xwork-core-2.3.15.3.jar\com\opensymphony\xwork2\validator\validators\default.xml

例子 验证信息记住:不是字段验证 比如 验证2次密码是否一样 这种需要使用 struts标签 的 actionError

配置文件

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE validators PUBLIC  "-//Apache Struts//XWork Validator 1.0.3//EN"  "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"><validators><field name="username"><field-validator type="requiredstring"><message>名字不能为空</message></field-validator><field-validator type="regex"><param name="regex"><![CDATA[[a-zA-Z]{3,8}]]></param><message>名字必须由3~8位字母组成</message></field-validator></field><field name="password"><field-validator type="requiredstring"><message>密码不能为空</message></field-validator><field-validator type="strong"><message>密码必须由至少一个大写和小写和数字组成</message></field-validator></field><!-- 非字段验证:要使用s:actionError显示错误 --><validator type="expression"><param name="expression">repassword==password</param><message>两次密码必须一致</message></validator><field name="email"><field-validator type="email"><message>输入正确的邮箱</message></field-validator></field><field name="birthday"><field-validator type="date"><param name="min">2000-01-01</param><param name="max">2010-12-31</param><message>请输入正确的日期</message></field-validator></field><field name="netaddress"><field-validator type="url"><message>请输入正确的地址:协议_主机_资源地址</message></field-validator></field></validators>

jsp:

<!-- 非字段验证:要使用s:actionError显示错误 -->     <s:actionerror/><s:form action="act3"><s:textfield name="username" label="用户名"></s:textfield><s:textfield name="password" label="密码"></s:textfield><s:textfield name="repassword" label="重复密码"></s:textfield><s:textfield name="email" label="邮箱"></s:textfield><s:textfield name="birthday" label="出生日期(MM/dd/yyyy)"></s:textfield><s:textfield name="netaddress" label="地址"></s:textfield><s:submit value="注册"></s:submit></s:form>

自定义声明式校验

a.编写一个类,继承FieldValidatorSupport 定义一个基于字段的验证器

import org.apache.commons.lang3.StringUtils;import com.opensymphony.xwork2.validator.ValidationException;import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport;//验证密码强度public class StrongPasswordValidator extends FieldValidatorSupport {// object:实际上就是动作类public void validate(Object object) throws ValidationException {String fieldName = getFieldName();// 得到要验证的字段名String fieldValue = (String) getFieldValue(fieldName, object);if (StringUtils.isNotEmpty(fieldValue)) {// 有值时再做强度验证if (!isPasswordStrong(fieldValue)) {// 不满足条件就添加回显信息addFieldError(fieldName, object);}}}private static final String GROUP1 = "abcdefghijklmnopqrstuvwxyz";private static final String GROUP2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";private static final String GROUP3 = "0123456789";protected boolean isPasswordStrong(String password) {boolean ok1 = false;// 有一个小写字母就为trueboolean ok2 = false;// 有一个大写字母就为trueboolean ok3 = false;// 有一个数字就为trueint length = password.length();for (int i = 0; i < length; i++) {if (ok1 && ok2 && ok3)break;String character = password.substring(i, i + 1);if (GROUP1.contains(character)) {ok1 = true;continue;}if (GROUP2.contains(character)) {ok2 = true;continue;}if (GROUP3.contains(character)) {ok3 = true;continue;}}return ok1 && ok2 && ok3;}}
在src下建立一个validation.xml的配置文件 写法可以参考Struts2解压出来的xwork.jar包下的

xwork-core-2.3.15.3.jar\com\opensymphony\xwork2\validator\validators\default.xml

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE validators PUBLIC        "-//Apache Struts//XWork Validator Definition 1.0//EN"        "http://struts.apache.org/dtds/xwork-validator-definition-1.0.dtd"><validators>  <validator name="strong" class="com.test.validation.StrongPasswordValidator"></validator></validators>
然后就可以直接在验证中使用了


0 0
原创粉丝点击