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:
编写原则:表单的输入域的名称和动作类中的属性名(getter和setter)保持一致。
<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>然后就可以直接在验证中使用了
- Struts2-2
- Struts2 (2)
- struts2---2
- Struts2(2)
- struts2(2)
- struts2--2
- Struts2-2
- Struts2(2)
- struts2 (2) struts2.xml配置文件
- Struts2使用2-- Struts2的概述
- [struts2]Struts2.2 Annotation 注解配置Action
- 研磨Struts2 第一章 Struts2概述-2
- JAVA_WEB Struts2学习:Struts2标签学习2
- struts2.3与struts2.2的不同之处
- Struts2-----2、Struts2的下载和安装
- Struts2系统学习(2)Struts2-HelloWorld
- struts2(2)------struts2开发环境搭建
- 【Struts2学习】 (2) Struts2开发HelloWorld实例
- 开发环境简介合集
- nyoj拦截导弹
- [刷题]Find Minimum in Rotated Sorted Array II
- HttpClient使用Post和Get提交参数
- 12569 - Planning mobile robot on Tree (EASY Version)
- Struts2(2)
- C++ 简单读写文本文件、统计文件的行数、读取文件数据到数组
- Expression : invalid operator < 解决方法
- 关于block使用需要注意的地方
- 步步为营(三)贪心(2)选择不相交区间
- MAC搜索不到蓝牙设备解决方案
- SSH框架中经典错误:java.lang.NoSuchMethodError: antlr.collections.AST.getLine()解决方案
- 豆瓣API在python中的使用
- C++ HOJ 约瑟夫问题 之 神牛代码