Struts2 入门学习笔记详解:
Struts2起源与背景:
学习一个技术就要了解它的历史, 知道它的背景 出现的因素… 这是我学习的习惯
在以前很久一段时间曾经出现过一种框架Struts1
Struts1
在很长一段时间, 在MVC框架中处于绝对的统治地位…大概04年吧… 我才上幼稚园…
Struts1:可以很好的实现 控制与业务逻辑的分离…
但自身也存在一些缺陷:
表现层单一: 只支持表现层使用, 限制了Struts1 的发展;
对Servlet APl 的依赖: Struts1 框架基于 Model2 模式开发, 因此其中需要涉及大量的Servlet APl 进一步对Web容器产生了依赖;
不利于代码重用::在代码开发中除了自己定义了类外 还必须使用Struts1 中的类; 类型之间的耦合严重!
WebWork
为了解决此类问题, 又出现了一种新的技术WebWork;
它更加强调 系统之间的松耦合:使用拦截器来实现控制, 由此不在依赖于web容器
松耦,表现层支持更多的视图,使开发更加灵活; 但由于宣传不高 使用率并不多…名气并不大!! 为了提高访问度 改了个名字 Struts2 出现了;
Struts2
以WebWork框架的设计思想为核心,吸收了Struts 1的部分优点;
WebWork + Struts1 = Sturts2
Struts 2的获取
Struts 2官方地址:http://struts.apache.org
本次选取Struts 2.3.16.3进行讲解
Struts2 应用:
引入Struts2 Jar
新建Java Web项目, 引入Jar文件添加至项目中lib
Struts2项目基础jar文件:
文件明 | 说明 |
---|---|
struts2-core-xxx.jar | Struts 2框架的核心类库 |
xwork-core-xxx.jar | XWork类库,Struts 2的构建基础 |
ognl-xxx.jar | Struts 2使用的一种表达式语言类库 |
freemarker-xxx.jar | Struts 2的标签模板使用类库 |
javassist-xxx.GA.jar | 对字节码进行处理 |
commons-fileupload-xxx.jar | 文件上传时需要使用 |
commons-io-xxx.jar | Java IO扩展 |
commons-lang-xxx.jar | 包含了一些数据类型的工具类 |
…jar | 这里仅是一些基础的Jar 随着程序扩展还有很多个jar 要不停学习哦~ |
开始第一个Struts2 项目:
配置web.xml
编写web项目, Struts2框架所需要的过滤器:web.xml (个人喜欢先弄配置, 一般都是cope)
注意:
目前由于开发工具的进步, 可能有些web项目默认不会在显示 web.xml文件但一定不是手创的!可以设置工具项目版本——myelicpse
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<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_2_5.xsd" id="WebApp_ID" version="2.5">
<!-- 项目名 -->
<display-name>Struts2</display-name>
<!-- web文件指定的默认访问页面.. -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- Struts2过滤器 -->
<!-- 作用:启动加载struts.xml文件-->
<filter>
<filter-name>struts</filter-name>
<!-- Struts2核心控制器类:
早期还是:org.apache.struts2.dispatcher.FilterDispatcher
-->
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> <!-- 现在! -->
</filter>
<filter-mapping>
<filter-name>struts</filter-name>
<url-pattern>/*</url-pattern> <!-- /*: 任何请求都要经过.. -->
</filter-mapping>
</web-app>
编写页面 :
这里只是先单纯的学习Struts 并不会与数据库打交道访问数据库啥的…
Struts 就像之前学习SpringMVC一样, 相当于一个控制器 Servlet一样 接收页面请求响应结果数据
(一般搭配Hibernate 进行数据库交互这里暂时不讲解 欢迎可以观赏以下我之前的博客有详细讲解… );
这里页面使用: JSP
HelloWord.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %> <!-- 引入Struts2标签库 -->
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<p>${msg }</p> <!-- 单纯直接使用EL是获取不到滴...EL是获取作用域中的数据都没有存哦~ -->
<h1>
<s:property value="msg"/> <!-- 使用Struts2标签库,可以直接获取到响应action的全局变量的数据; -->
</h1>
<!-- 表单: name="name" 可以用于传递参数.. -->
<form action="hello" method="post">
名字: <input type="text" name="name"> <input type="submit"value="提交">
</form>
</body>
</html>
编写Action Java类;(相当于控制器的操作)
个人喜欢在编写时, 专门建一个包 action包 用于专门存在 action类;
这里先介绍一下最基础的实现Action接口方式来实现,重写 execute();
根据返回值String 找到对应的响应页面…
仔细一看有点像Servlet了,对于多种不同请求如果采用该方式不是很方便, 多重判断执行 返回不同结果页面…
后面会深入扩展多种的Action实现方式…
HelloWordAction.java
package com.wsm.action;
//注意别倒错包了
import com.opensymphony.xwork2.Action;
/*Action:
* Struts中用于接收响应,请求的Java类,相当于 "控制器"
*
* 全局变量:
* Struts中用于 "接收"或"显示" 数据;
* 需要给其提供给get/set();
* 接收页面信息: 变量名要和表单name名相同;
* 向页面输出: 页面可以通过: Struts2表达式/或存在作用域中通过EL表达式取出进性数据展示;
*/
public class HelloWordAction implements Action {
//获取页面表单名字;
private String name;
//等会向页面输出的变量...
private String msg;
//Struts2 还支持使用复杂的数据类型: 集合 数组 对象...
//实现方法
@Override
public String execute() throws Exception {
System.out.println(name);
msg="hello:"+name; //拼接向页面输出的信息;
return "hello"; //返回 "逻辑视图名",struts.xml根据:<result name="返回的逻辑视图名" >找到最后的响应页面</result>
}
/*
对于return "逻辑视图名"; Action接口中还提供了5个字符串类型静态常量:
用于更加规范的,指定对应的 "逻辑视图";
其实也就是普通的字符串,并无特殊机制.. 逻辑视图指定的页面也还是要自己定义的,只是Struts2的一种完善机制吧;
*/
//get/set
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
Action接口常量字符串逻辑含义
常量 | 值 | 逻辑含义 |
---|---|---|
SUCCESS | “success” | 表示程序处理正常, 并返回给用户成功的结果; |
NONE | “none” | 表示程序处理正常,但不返回给用户任何显示… |
ERROR | “error” | 返回处理结果失败… |
INPUT | “input” | 表示需要更多用户输入才能顺利执行 |
LOGIN | “login” | 表示用户需要正确登录后才能顺利执行 |
创建Struts2 配置文件:
页面发送请求——经过web,xml过滤——Struts2配置文件: 处理——
找到对应的xxaction类 一系列操作后返回一个"逻辑视图名"——至Struts2配置文件根据result 找到对应响应页面…;
注意: 该文件必须建在 项目的Src文件下,部署服务器时候才会在: WEB-INF/classes 目录下的,才可以正确获取执行…
一般取名:struts.xml
struts.xml
在 src 目录下新建一个名称为 struts.xml 的文件
<?xml version="1.0" encoding="UTF-8"?>
<!-- struts.xml声明部分,工具没有配置的DTD文件,可以直接cope下面的... -->
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<!-- struts.xml根节点 -->
<struts>
<!-- 创建: 一个default包名, namespace命名空间 "/"表示寻找根目录下请求action.., 继承struts-default(Struts2底层的...) 后面详细讲解...-->
<package name="default" namespace="/" extends="struts-default" >
<!-- action:用于接收页面的请求,指定对应的action类中执行...(package中可以配置多个)
name:根据页面请求根据name找到指定的action class:指定对于action java类进行执行;
-->
<action name="hello" class="com.wsm.action.HelloWordAction" >
<result name="hello" >/HelloWord.jsp</result> <!-- 根据 xxxaction类,返回的逻辑视图名指定对于的响应页面... -->
<!-- 如果没有指定 name默认值就是success,所以action returu "success"; 可以不指定name -->
</action>
</package>
</struts>
Struts2使用对象接收用户输入数据 / 访问Servlet Apl
使用Struts2实现登录功能:
在上一项目基础上扩展…
扩展一个实体类(对象数据传输);
User .Java
package com.wsm.entity;
public class User {
//属性
private String userName;
private String userPwd;
//无参构造
public User(){};
//带参构造
public User(String userName, String userPwd) {
super();
this.userName = userName;
this.userPwd = userPwd;
}
//get/set
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
}
登录所需的login 页面;
login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<form action="login" method="post">
<!-- 对于对象类型的,读取通过action类中: 对象名.属性 进行赋值读取-->
名字<input type="text" name="user.userName"> <!-- 对于属性名要和Java类一致 且区分大小写-->
密码<input type="text" name="user.userPwd" >
<input type="submit" value="提交">
</form>
<!-- 因为控制器request中存储了登录失败信息,EL表达式查看~ -->
<p>${shibai }</p>
</body>
</html>
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<p>登录成功!${user.userName }</p>
</body>
</html>
登录的action 及struts2访问ServletApl对象;
struts2 访问ServletApl对象
在Struts2 概述中介绍过, Struts2的Action 没有与ServletApl 发送耦合;从而可以轻松实现Action 的测试;
但是在web 开发过程中, 无法避免需要使用 ServletApl中的对象;
Struts2提供了多种方式实现ServletApl的访问:(两大类)
解耦方式操作ServletAPl 对象 两种实现 (下面实例就是一种解耦形式) ;
- 使用ActionContext 类获取ServletApl对象 (Map对象)
Struts2 框架使用普通的Map对象替代了:HttpServletRequest HttpSession ServletContext …
Action类中 ,可以轻易的获取对应的Map类型的替代对象, 实现了解耦的形式…
解耦方式获得作用域对象,如下代码案例- Action类实现特定接口来实现 ServletApl 对象; (即采用注入方式实现)
好处: 这种方式有利于单元测试, 因为ActionContext需要借助框架进行初始化, 而这种方式无须初始化直接获取使用…
如下实例
Action类实现特定接口来实现 ServletApl 对象ServletAction.java
package com.wsm.action;
//注意导入对应的包~
import java.util.Map;
import org.apache.struts2.interceptor.ApplicationAware;
import org.apache.struts2.interceptor.RequestAware;
import org.apache.struts2.interceptor.SessionAware;
import com.opensymphony.xwork2.Action;
public class ServletAction implements Action, RequestAware,SessionAware,ApplicationAware {
//注意这里定义的也是一个 Action;
//只不过本次只是为了让你们知道,可以通过实现对应接口,解耦获得对应的 Servlet对象,所以没有什么特定的实现功能...别搞混~
//自定义解耦的作用域对象;
Map request;
Map session;
Map application;
//action:实现的方法..这里没有使用不详细介绍了...
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
return null;
}
//实现对应的方法,每一个接口都只有一个实现方法(); 用户返回对应的Map类型,模拟作用域对象;
@Override
public void setApplication(Map<String, Object> appliction) {
this.application = appliction;
}
@Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
@Override
public void setRequest(Map<String, Object> request) {
this.request = request;
}
}
耦合方式操作ServletAPl 对象;
直接访问 Servlet API将使Action类与Servlet API耦合在一起;
Servlet API对象均由Servlet容器来构造,与这些对象绑定在一起,测试过程中就必须有Servlet容器,这样不便于Action类的测试
但有时候,确实需要访问这些对象,Struts2同样提供了直接访问ServletAPI对象的方式。
要直接获取Servlet API对象可以使用org.apache.struts2.ServletActionContext类,该类是ActionContext类的子类。
//导包
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
HttpServletRequest request=ServletActionContext.getRequest(); //获取requset
ServletContext application=ServletActionContext.getServletContext(); //获取appliction
HttpSession session=request.getSession(); //根据requset 获取session;
除了直接使用 ServletActionContext 来直接获取Servlet Apl对象; 还可以通过实现接口注入ServletApl对象...省略了;
LoginAction.java
package com.wsm.action;
//注意别倒错包了
import java.util.Map;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionContext;
import com.wsm.entity.User;
public class LoginAction implements Action {
//全局变量
public User user; //对象类型,页面通过 对象名.属性名 可进行读取操作...
//解耦方式获得作用域对象
ActionContext ac = ActionContext.getContext();
Map<String,Object> request = (Map<String,Object>)ac.get("request"); //获取request
Map<String,Object> session = ac.getSession(); //获取session
Map<String,Object> appliction = ac.getApplication(); //获取appliction
@Override
public String execute() throws Exception {
//验证登录成功/失败! admin 123
if("admin".equals(user.getUserName()) && "123".equals(user.getUserPwd()) ){
//登录成功!用户存session
session.put("user",user);
return "index";
}
//往request 存储失败信息;
request.put("shibai","登录失败");
return "login"; //失败回到登录页面~
}
//get/set
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
action都写好,最后一定不要忘记 struts2的配置文件!
就不写全了…直接在 package 中加一组 action 即可~
struts.xml
<action name="login" class="com.wsm.action.LoginAction" >
<result name="index" >/index.jsp</result>
<result name="login" >/login.jsp</result>
</action>
Struts2 数据校验:
对于一个web 应用而言, 所有的用户数据都是通过浏览器, 收集的;
用户的输入信息非常复杂多变,如果过程中 : 硬件设备/网络/用户恶意破坏…输入的信息可能导致程序异常…
对于这种问题应用程序需要能够在控制层, 处理异常的输入…
通常的做法是, 控制层发现异常, 直接返回回浏览器, 提示异常用户必须重新输入合法的…
对于这种操作,可以通过Struts2数据效验机制,进行完善…
使用Struts2的数据校验,action类将不再通过实现Action接口来实现..而是通过继承 ActionSupport类来完善数据校验操作
ActionSupport类
是一个默认的 Action接口的实现类。
这个类提供了很多默认的方法 :国际化信息 数据校验 默认处理用户请求…等方法;
因为ActionSupport类 是Struts2的默认实现类. 所以Struts.xml 中 < action > 可以不指定 class属性
ActionSupport类中的 validate() 实现数据校验, 所以需要重写…
给用户登录操作加非空验证:
需要修改LoginAction
LoginAction.java
package com.wsm.action;
//注意别倒错包了
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.wsm.entity.User;
public class LoginAction extends ActionSupport { //继承ActionSupport
//全局变量
public User user; //对象类型
//解耦方式获得作用域对象
ActionContext ac = ActionContext.getContext();
Map<String,Object> request = (Map<String,Object>)ac.get("request"); //获取request
Map<String,Object> session = ac.getSession(); //获取session
Map<String,Object> appliction = ac.getApplication(); //获取appliction
@Override
public String execute() throws Exception {
//验证登录成功/失败! admin 123
if("admin".equals(user.getUserName()) && "123".equals(user.getUserPwd()) ){
//登录成功!用户存session
session.put("user",user);
return "index";
}
//往request 存储失败信息;
request.put("shibai","登录失败");
return "login"; //失败回到登录页面~
}
//重写 validate(); 数据效验的方法;
@Override
public void validate() {
if(user.getUserName().length()==0){
super.addFieldError("username", "用户名不能为空");
}
if(user.getUserPwd().length()==0){
super.addFieldError("userpwd", "密码不能为空");
}
}
/*
当页面,发送一个请求,找对对应的action 时,最先进入就是 validate();方法中进行数据校验..
如果在验证过程中 addFieldError(); 添加了验证信息,那么就不会在进入execute(); 方法;
而是直接返回一个 "input"逻辑视图名,去struts.xml 找到指定的一个页面...
所以一定要在 struts.xml对应action标签中配置一个: <result name="input" >响应页面</result>
页面上可以通过:Struts2标签来讲校验异常信息展示..
*/
//get/set
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
struts.xml
<action name="login" class="com.wsm.action.LoginAction" >
<result name="index" >/index.jsp</result>
<result name="login" >/login.jsp</result>
<result name="input" >/login.jsp</result> <!-- input:表示数据异常返回回登录页面; -->
</action>
修改页面展示校验结果:login.jsp
注意:别忘了导入 <%@ taglib prefix=“s” uri="/struts-tags" %> < !-- Struts2标签库 -->
可以通过 <s:fielderror></s:fielderror> 进行数据异常信息展示…
%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %> <!-- Struts2标签库 -->
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<!-- 数据效验异常信息输出展示.. -->
<div>
<s:fielderror></s:fielderror>
</div>
<form action="login" method="post">
<!-- 对于对象类型的,读取通过action类中: 对象名.属性 进行赋值读取-->
<!-- 对于属性名要和Java类一致 且区分大小写-->
名字<input type="text" name="user.userName"> <s:fielderror fieldName="username" ></s:fielderror> <!-- 根据fieldName指定显示异常的信息.. -->
<hr/>
密码<input type="text" name="user.userPwd" > <s:fielderror fieldName="userpwd" ></s:fielderror>
<input type="submit" value="提交">
</form>
<!-- 因为控制器request中存储了登录失败信息,EL表达式查看~ -->
<p>${shibai }</p>
</body>
</html>
Struts2标签:
Struts2 中提供了很多功能强大的标签库, 并且远远超出了传统的标签库的基本功能:(上面校验信息就是一种…)
主要分为两大类:UI标签 通用标签
使用前需要导入 Struts2标签库: <%@ taglib prefix=“s” uri="/struts-tags" %>
UI标签
UI标签可以分为三大类:表单标签 非表单标签 Ajax标签
Struts2常用表单标签:
标签 | 说明 |
---|---|
<s:form>…</s:form> | 表单标签 |
<s:textfield>…</s: textfield> | 文本输入框 |
<s:password>…</s: password> | 密码输入框 |
<s:textarea>…</s: textarea> | 文本域输入框 |
<s:radio>…</s: radio> | 单选按钮 |
<s:checkbox>…</s: checkbox> | 多选框 |
<s:submit/> | 提交标签 |
<s:reset/> | 重置标签 |
<s:hidden/> | 隐藏域标签 |
<s:actionerror/> | 显示Action错误 |
<s:actionmessage/> | 显示Action消息 |
<s:fielderror/> | 显示字段错误,输出addFieldError("",""); 存储的信息… 一般用于 数据校验! |
这些标签会被浏览器, 翻译加载运行, 可能会以一种 <table/><tr/><td/>
形式包装输出…
这是Struts2的默认格式:可以在struts.xml 对其默认风格进行修改:
<struts>
<!-- 设置用户界面默认XHTML风格:value="值可选.." -->
<constant name="struts.ui.thems" value="simple" />
</struts>
通用标签
Struts2 UI标签主要用于视图的设计,在视图的设计过程中还往往伴随着一些业务控制行为;
eg:
判断Action中读取的集合是否为空,对集合进行 遍历!
Struts2常用的通用标签:
if/else if/else标签
三个都是条件判断 分支控制标签,几乎于Java类似:
三个标签中只有
<s:if />
可以单独使用
<s:elseif />
<s:else />
可以和<s:if />
搭配使用,但不能单独使用!
iterator迭代标签
实例Demo
登录成功, 查询所有用户信息遍历,并且隔行变色
修改LoginAction.java
//修改execute();
@Override
public String execute() throws Exception {
//验证登录成功/失败! admin 123
if("admin".equals(user.getUserName()) && "123".equals(user.getUserPwd()) ){
//登录成功!用户存session
session.put("user",user);
//存储几个用户,模拟查询,页面测试 struts2标签库,别忘了给实体类加一个带参构造函数(name,pwd);
List<User> users = new ArrayList<User>();
users.add(new User("张三1", "123"));
users.add(new User("张三2", "123"));
users.add(new User("张三3", "123"));
users.add(new User("张三4", "123"));
request.put("users",users);
return "index";
}
//往request 存储失败信息;
request.put("shibai","登录失败");
return "login"; //失败回到登录页面~
}
index.jsp
页面输出:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<p>登录成功!${user.userName }</p>
<!-- s:iterator:迭代遍历,获取request中数据!都已经requset了其实也可以直接使用JSTL了..感觉鸡肋了... -->
<s:iterator var="user" value="#request.users" status="status">
<!-- 判断元素下标隔行变色 -->
<s:if test="#status.index % 2==0">
<div style="background-color: red">
<s:property value="#user.userName"/>---<s:property value="#user.userPwd"/>
</div>
</s:if>
<s:else>
<div style="background-color: blue;">
<s:property value="#user.userName"/>---<s:property value="#user.userPwd"/>
</div>
</s:else>
</s:iterator>
</body>
</html>
URL标签和日期标签:
URL标签:
类似于HTML < a ></ a >,就可以知道这个标签的作用是构建一个URL地址
URL标签的语法如下:
<s:url value="ur1">
<s:param name="parname" value="parvalue">
</s:url>
<!--
≤s.param/>标签是需要传递的的参数信息.
其中,name 属性表示传递的参数名称,value 属性表示传值;
就相当于提交带的参数...
-->
日期标签:
日期标签用于格式化输出一个日期。
除此之外,该标签还可以计算指定日期和当前日期时刻之间的时差。
日期标签的语法法如下:
<s:date format="format" nice="truelfalse" name="name" id="1d" />
format属性:表示按照指定的格式进行日期格式化。
nice属性:该属性只有true 和false两个值,用于指定是否输出指定日期与当前时间的时差 ,默认是false
name属性:表示当前需要格式化的日期。
id属性:表示引用该元素的id值。
终于写完了,感谢观看,最后实例的隔行颜色有点丑,别建议~