Struts(四)
1.Struts 2提供了非常强大的类型转换功能,提供了多种内置类型转换器,也支持开发自定义类型转换器
2.Struts 2框架使用OGNL作为默认的表达式语言
==========================================OGNL=================================
OGNL:Object Graph Navigation Language
1.取代页面中Java脚本,简化数据访问
2.和EL一样是表达式语言,功能更强大
功能和特点:
1.能存取对象的属性,也能调用对象的方法
2.能访问静态方法、静态属性
3.能访问值栈及StackContext
4.能操作集合对象
5.支持赋值、运算操作、字段类型转化
语法:
1.导入taglib指令:<%taglib uri="/struts-tags" prefix="s" %>
2.<s:property value="OGNL表达式"/> --> 在JSP中显示OGNL表达式的值
作用:
1.表达式语言
将表单或者Struts2标签与特定的Java数据库绑定起来,用来将数据移入,移除框架
2.类型转换
数据进入和流出框架,在页面数据的字符串类型和Java数据类型之间进行转换
值栈:ValueStack(可理解为存储数据的Map)
1.由Struts2框架创建的存储区域,具有栈的特点
2.Action的实例会被存放到值栈中
【注意:值栈中内容可以直接访问,访问非值栈对象需要添加#前缀】
OGNL访问ValueStack
1.按照从上到下的顺序
2.靠近栈顶的同名属性会被读取
访问Bean的属性
1.Bean的类型必须遵循JavaBean规范--必须具有无参构造
2.setter和getter方法符合JavaBean规范
访问集合对象
1.可以使用属性名[index]的方式访问 如:列表,数值
2.可以使用属性名[key]的方式访问 如:Map对象
3.使用size或者length获取集合长度
==========================================URL标签=================================
使用Struts 2使用URL标签可以构建一个超链接
语法:
<s:url value="url" />
<s:param name="parname" value="parvalue" />
</s:url>
value属性:表示指定生成URL的地址
<s:param />:表示需要传递的参数信息
name属性:表示传递的参数名称
value属性:表示传递参数所具有的值
==========================================日期标签=================================
使用Struts 2日期标签可以实现日期输出的格式化显示
<s:date format="format" nice="true|false" name="name" >
……
</s:date>
format:指定格式进行日期格式化
nice: 指定是否输出指定日期和当前时间的时间差,默认false
name:当前需要格式化的日期
==========================================类型转换=================================
基于HTTP协议的Web应用中:
1.客户端请求的所有内容都以编码方式传输到服务器端
2.服务器端的编程语言有丰富的数据类型
内置类型转换器:自动对客户端传来的数据进行类型转换(除Servlet手动转换外)
内置类型转换器 说 明
String 将int、long、double、boolean、String类型的数组或者java.util.Date类型转换为字符串
boolean/Boolean 在字符串和布尔值之间进行转换
char/Character 在字符串和字符之间进行转换
date 在字符串和日期类型之间进行转换。具体输入输出格式与当前的Locale相关
数组和集合 在字符串数组和数组对象、集合对象间进行转换
创建自定义类型转换器
1.继承StrutsTypeConverter抽象类(org.apache.struts2.util. StrutsTypeConverter)
2.应用于全局范围的类型转换器
在src目录创建xwork-conversion.properties --> 转换类全名=类型转换器类全名
3.应用于特定类的类型转换器
在特定类的相同目录下创建一个名为ClassName-conversion.properties的属性文件 --> 特定类的属性名=类型转换器类全名
处理类型转换错误
1)向用户输出类型转换错误的前提条件
1.启动StrutsConversionErrorInterceptor拦截器
拦截器已经包含在defaultStack拦截器栈中
2.Action要继承ActionSupport类
实现ValidationAware接口
3.配置input结果映射
4.页面使用Struts 2表单标签或<s:fielderror>标签
a.Struts 2表单标签内嵌输出错误信息功能
b.普通HTML标签需使用<s:fielderror>标签输出转换错误
2)修改所有类型的转换错误信息
修改xwork.default.invalid.fieldvalue键的值
步骤:
1.在struts.xml中指定资源文件的基名 -- <constant name="struts.custom.i18n.resources" value="message"/>
2.在src目录下创建资源文件并修改键值 -- xwork.default.invalid.fieldvalue=字段"{0}"的值无效
3)定制特定字段的类型转换错误信息
在Action范围的资源文件中添加I18N消息键invalid.fieldvalue.xxx
在Action包下创建RegisterAction.properties,指定键值 -- invalid.fieldvalue.birthday=生日转换错误
范例:
1.实体类 -- User
1 package com.Elastic.StrutsDemo4.ivy.entity; 2 public class User { 3 private String loginName; 4 private String loginPass; 5 6 public String getLoginName() { 7 return loginName; 8 } 9 public void setLoginName(String loginName) { 10 this.loginName = loginName; 11 } 12 public String getLoginPass() { 13 return loginPass; 14 } 15 public void setLoginPass(String loginPass) { 16 this.loginPass = loginPass; 17 } 18 }
2.test包 -- Test
1 package com.Elastic.StrutsDemo4.ivy.test; 2 3 import com.Elastic.StrutsDemo4.ivy.entity.User; 4 5 import ognl.Ognl; 6 import ognl.OgnlContext; 7 import ognl.OgnlException; 8 9 public class Test { 10 11 public static void main(String[] args) throws OgnlException { 12 User user = new User(); 13 //使用OGNL表达式赋值 14 Ognl.setValue("loginName", user, "张三"); 15 System.out.println(user.getLoginName()); 16 17 User user2 = new User(); 18 //创建上下文环境 19 OgnlContext ognlContext = new OgnlContext(); 20 ognlContext.put("user", user); 21 ognlContext.put("msg", user2); 22 //设置根对象 -- user 23 ognlContext.setRoot(user); 24 25 /*Ognl.setValue("user.loginPass", ognlContext, "abc123"); 26 System.out.println(user.getLoginPass()); 27 System.out.println(user2.getLoginName()); 28 Ognl.setValue("msg.loginName", ognlContext, "admin123"); 29 System.out.println(user2.getLoginName());*/ 30 31 //ActionContext中包含多个对象。如果使用OGNL访问根对象,可直接书写对象的属性,而要使用其他对象必须使用"#key"前缀来访问 32 Ognl.setValue("loginName", ognlContext, ognlContext.getRoot(), "李四"); 33 System.out.println(user.getLoginName()); 34 35 Ognl.setValue("#msg.loginName", ognlContext, ognlContext.getRoot(), "王五"); 36 System.out.println(user2.getLoginName()); 37 } 38 }
3.action包
a.UserAction
1 package com.Elastic.StrutsDemo4.ivy.action; 2 3 import java.util.Date; 4 import java.util.HashMap; 5 import java.util.Map; 6 7 import com.Elastic.StrutsDemo4.ivy.entity.User; 8 import com.opensymphony.xwork2.ActionSupport; 9 public class UserAction extends ActionSupport { 10 11 private User user; 12 private String[] strs; 13 private Map<String, Object> map; 14 private Date regDate; 15 private Integer age; 16 17 public Map<String, Object> getMap() { 18 return map; 19 } 20 21 public void setMap(Map<String, Object> map) { 22 this.map = map; 23 } 24 25 public Date getRegDate() { 26 return regDate; 27 } 28 29 public void setRegDate(Date regDate) { 30 this.regDate = regDate; 31 } 32 33 public Integer getAge() { 34 return age; 35 } 36 37 public void setAge(Integer age) { 38 this.age = age; 39 } 40 41 public String[] getStrs() { 42 return strs; 43 } 44 45 public void setStrs(String[] strs) { 46 this.strs = strs; 47 } 48 49 public User getUser() { 50 return user; 51 } 52 53 public void setUser(User user) { 54 this.user = user; 55 } 56 57 public String regPage() { 58 user = new User(); 59 user.setLoginName("admin"); 60 strs = new String[3]; 61 strs[0] = "test"; 62 strs[1] = "abc"; 63 64 map = new HashMap<String, Object>(); 65 map.put("admin", "123456"); 66 67 return SUCCESS; 68 } 69 70 public String index(){ 71 return SUCCESS; 72 } 73 }
b.UserAction-conversion.properties
1 regDate=com.Elastic.StrutsDemo4.ivy.util.DateConvert
c.UserAction.properties
1 invalid.fieldvalue.regDate=\u65E5\u671F\u683C\u5F0F\u65E0\u6548
4.util包
a.DateConvert
1 package com.Elastic.StrutsDemo4.ivy.util; 2 3 import java.text.ParseException; 4 import java.text.SimpleDateFormat; 5 import java.util.Map; 6 7 import javax.management.RuntimeErrorException; 8 9 import org.apache.struts2.util.StrutsTypeConverter; 10 11 public class DateConvert extends StrutsTypeConverter{ 12 SimpleDateFormat[] formats = new SimpleDateFormat[]{ 13 new SimpleDateFormat("yyyy-MM-dd"), 14 new SimpleDateFormat("yyyy/MM/dd"), 15 new SimpleDateFormat("yyyy年MM月dd日"), 16 new SimpleDateFormat("yyyy.MM.dd") 17 }; 18 19 /** 20 * 将一个或多个字符串值转换为指定的类型 21 */ 22 @Override 23 public Object convertFromString(Map arg0, String[] values, Class arg2) { 24 Object value = null; 25 for (SimpleDateFormat format : formats) { 26 try { 27 value = format.parse(values[0]); 28 } catch (ParseException e) { 29 e.printStackTrace(); 30 } 31 } 32 if (values[0].length() != 0 && value == null) { 33 throw new RuntimeException(""); 34 } 35 return value; 36 } 37 38 /** 39 * 将指定对象转化为字符串 40 */ 41 @Override 42 public String convertToString(Map arg0, Object arg1) { 43 return null; 44 } 45 }
5.Struts配置文件 -- struts.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd" > 3 <struts> 4 <constant name="struts.custom.i18n.resources" value="message"></constant> 5 <package name="default" namespace="/" extends="struts-default"> 6 7 <action name="regPage" class="com.Elastic.StrutsDemo4.ivy.action.UserAction" method="regPage"> 8 <result name="success">/reg.jsp</result> 9 <result name="input">/index.jsp</result> 10 </action> 11 12 <action name="index" class="com.Elastic.StrutsDemo4.ivy.action.UserAction" method="index"> 13 <result name="success">/reg.jsp</result> 14 <result name="input">/index.jsp</result> 15 </action> 16 </package> 17 </struts>
6.xwork-conversion.properties
1 java.util.Date=com.Elastic.StrutsDemo4.ivy.util.DateConvert
7.errormsg.properties
1 xwork.default.invalid.fieldvalue=\u5B57\u6BB5{0}\u683C\u5F0F\u65E0\u6548
8.web.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> 3 <display-name>StrutsDemo4_ivy</display-name> 4 <welcome-file-list> 5 <welcome-file>regPage</welcome-file> 6 </welcome-file-list> 7 8 <filter> 9 <filter-name>Struts2</filter-name> 10 <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> 11 </filter> 12 <filter-mapping> 13 <filter-name>Struts2</filter-name> 14 <url-pattern>/*</url-pattern> 15 </filter-mapping> 16 </web-app>
9.jsp
a.reg.jsp
1 <%-- 引入JSP页面PAGE指令 --%> 2 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> 3 <%-- 引入JSTL标签指令 --%> 4 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 5 <%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> 6 7 <%-- 引入Struts标签指令 --%> 8 <%@ taglib uri="/struts-tags" prefix="s" %> 9 10 <!DOCTYPE html> 11 <html language="zh-CN"> 12 <head> 13 <meta charset="utf-8"> 14 <!-- 设置浏览器渲染的引擎 --> 15 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 16 <!-- 设置支持移动设备 --> 17 <meta name="viewport" content="width=device-width, initial-scale=1"> 18 <title>网页标题</title> 19 <!-- 引用bootstrap样式 --> 20 <link rel="stylesheet" type="text/css" href="<%=request.getContextPath() %>/css/bootstrap.min.css"> 21 </head> 22 <body> 23 <div class="container-fluid"> 24 <s:debug></s:debug> 25 <s:property value="user.loginName" /> 26 <s:property value="strs[1]" /> 27 <s:property value="map['admin']" /> 28 29 <s:property value="{123,44,56,78}[1]"/> 30 <s:property value="#{'name':'admin','pass':'123456' }['pass']"/> 31 32 <s:iterator value="strs" var="s"> 33 <h1><s:property value="s"/></h1> 34 </s:iterator> 35 36 <s:property value="#parameters['test']"/> 37 38 <!-- struts标签显示url地址 --> 39 <a href="<s:url action="regPage"> 40 <s:param name="name" value="admin"></s:param> 41 </s:url>">链接</a> 42 43 <!-- includeParams 包含前一次请求的参数 --> 44 <s:url value="reg.jsp" includeParams="all"> 45 <s:param name="admin">test</s:param> 46 </s:url> 47 <s:url value="login.jsp"> 48 <s:param name="loginName" value="ognl表达式">直接书写值</s:param> 49 <s:param name="loginPass" value="ognl表达式">直接书写值</s:param> 50 </s:url> 51 52 <!-- 显示日期 --> 53 <s:property value="regDate"/> 54 <s:date name="regDate" format="yyyy-MM-dd hh:mm:ss"/> 55 <h1><s:date name="regDate" nice="true"/></h1> 56 <s:fielderror name="regDate"></s:fielderror> 57 58 <fmt:formatDate value="${regDate }" pattern="yyyy年MM月rr日hh时mm分ss秒"/> 59 60 <br><s:property value="age"/> 61 62 63 </div> 64 65 <!-- 引用外部JS文件 --> 66 <script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery-2.2.4.js"></script> 67 <script type="text/javascript" src="<%=request.getContextPath() %>/js/bootstrap.min.js"></script> 68 69 </body> 70 </html>
b.index.jsp
1 <%--引入JSP页面PAGE指令 --%> 2 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> 3 <%-- 引入JSTL标签指令 --%> 4 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 5 <%@ taglib uri="/struts-tags" prefix="s" %> 6 <!DOCTYPE html> 7 <html language="zh-CN"> 8 <head> 9 <meta charset="utf-8"> 10 <!-- 设置浏览器渲染的引擎 --> 11 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 12 <!-- 设置支持移动设备 --> 13 <meta name="viewport" content="width=device-width, initial-scale=1"> 14 <title>首页</title> 15 <!-- 引入bootstrap的样式 --> 16 <link rel="stylesheet" type="text/css" href="<%=request.getContextPath() %>/css/bootstrap.min.css"> 17 </head> 18 <body> 19 <s:debug></s:debug> 20 <div class="container"> 21 <form action="index"> 22 <input name="regDate" type="text"> 23 <s:fielderror name="regDate"></s:fielderror> 24 <input type="submit" value="提交"> 25 </form> 26 </div> 27 28 <!-- 引入JS的样式 --> 29 <script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery-2.2.4.js"></script> 30 <script type="text/javascript" src="<%=request.getContextPath() %>/js/bootstrap.min.js"></script> 31 32 </body> 33 </html>
服务器报错:
1.框架中如果没用用Spring框架,那么一定不要添加Spring的jar包。因为Spring是自动加载,如果没有用Spring,它也会加载Spring的jar包。此时,若没用Spring,那么服务器会报错
2.当服务器报多个cause by 时,从最后一条cause by 开始找原因