Struts2

Struts2简介
1.什么是Struts2
.Struts2
是轻量级的MVC框架,主要解决了请求分发的问题,重心在控制层和表现层

.轻量级
低侵入性,与业务代码耦合度很低,即业务代码中基本不用import它的包

.MVC框架
Struts2实现了MVC,并提供了一些API,采用模式化方式简化逻辑业务开发过程.

什么是MVC 
.M-Model模型
模型(model)的职责是负责业务逻辑(service).
包含两层:业务逻辑和业务处理逻辑.比如:实体类,DAO,service都属于模型层
     
.V-View视图
视图(View)的职责是负责显示界面和用户交互(收集用户信息).属于视图的组件是应该
包括业务逻辑和控制逻辑的jsp.

C-Controller控制器
控制台是模型层M和视图层V之间的桥梁,用于控制流程.
比如:在servlet项目中单一控制器ActionServer.

Struts2和servlet对比.
.优点:
业务代码解耦,适合团队开发
将请求分发给不同的处理类,从而降低了业务代码耦合度

--提升开发效率
提供一系列的API,可以大大的提升项目的开发项目,比如:使用拦截器可以自动给参数转型.

.缺点:
1.执行效率偏低
需要使用大量的反射,解析XML等技术手段会降低执行效率

-结构复杂,有学习成本
需要花一定时间学习struts2的API以及使用步骤.

struts2的发展历史


使用Struts2
servlet如何实现MVC

浏览器---->request---->servlet(Controller)---->JavaBean(Model)<---->DB---->转发--->浏览器

Struts2如何实现MVC
浏览器--->request---->Filter(web.xml)--->分发到指定的Action(控制器)----
--->JavaBean(model)<---->DB--->Filter--->转发到指定页面

1.创建一个web项目
2.导入Struts2核心包(8个)
将这些包复制到新建项目/WEB-INF/lib目录下
3.配置前端控制器
.Struts2使用Filter来充当前端控制器,因此在web.xml配置一个Filter即可
.Strurs2预置了该Filter的实现类:
名为:org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
指定该Filter处理所有的请求.
4.创建一个struts.xml文件
.在src下,创建名为struts.xml的配置文件
-Struts2配置文件默认要放在src下
-Struts配置文件默认名称为struts.xml(不要轻易该名字)
-struts.xml的格式
-可以参考默认配置文件struts-default.xml(在struts2-core-2.3.15.3.jar下的)--设置版本信息以及DTD的引用
-可以参考DTD(版本定义声明)文件.
5.编写业务控制Action
创建业务控制器组件,通常命名为XxxxxAction,该组件是一个满足JavaBean规范的类.
.在Action中要定义业务方法,要满足下列条件.
-方法一定是public的
-返回值一定要是String类型
-参数列表为空

编写业务方法
-方法内部编写业务逻辑代码
-返回的字符串要与struts.xml->action->result的name匹配,即根据此返回值可以找到对应的result.

6.创建jsp页面

7.配置struts.xml
.在struts.xml中配置请求与Action的关系
.在Action下,通过result设置转发的页面.

----------------------------------------------------------------

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_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>Struts2</display-name>
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

----------------------------------------------

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<!-- 
package:包,用于对Action进行封装
1.name:包名,根据元素下可以有多个包,彼此之间不能重名
2.extends:继承,用于指定继承的包,相当于将继承包下的配置信息复制到了当前包下.
3.namespace:命名空间,用于规定Action的访问路径,必须以"/"开头
4.请求Action时,按照如下格式拼写url:
http://localhost:8080/Sc1807-2Struts2/demo/hello.action
http://ID:PORL/APPNAME/NAMESPACE/ACTIONNAME.action
action为固定后缀,可以省略.
 -->
<struts>
<package name="day01" namespace="/demo" extends="struts-default">

<action name="hello" class="com.sicheng.action.HelloAction" method="sayHello">
<!-- 
action:业务控制器,用于注册业务控制器主键(类)
1.name:action名称,用于规定Action的访问路径,一个包下可以有多个Action,但是彼此之间不能重名
2.class属性:业务控制器组件,用于指定业务控制器对应的类
3.method:方法,用于指定访问当前action时要调用的方法.
 -->
        <result name="success">
<!-- 
result:输出组件,用于转发,重定向,直接输出
1.name:名称,一个action下可以有多个result,彼此之间不能重名
2.默认做转发,标记内容设置成转发的页面
 -->
        /hello.jsp
        </result>
</action>

</package>
</struts> 

  -----------------------------------------

index.jsp

<body>
<form action="/Sc1807-2Struts2/demo/hello.action" method="post">
<!-- 演示基本属性注入 -->
姓名:<input type="text" name="user.userName"><br>
密码:<input type="password" name="user.passworld"><br>
工资:<input type="text" name="user.salary"><br>
<input type="submit" value="提交">
</form>
</body>

---------------------------------------------------------

public class HelloAction {
    public HelloAction(){
        System.out.println("实例化");
    }

    //定义基本类型属性,接收表单参数:姓名
    private String realName;
    public void setRealName(String realName) {
        System.out.println("注入参数realName");
        this.realName = realName;
    }
    //定义实体对象属性,接收表单参数:用户名,密码,工资.
    private User user;
    
    public void setUser(User user) {
        System.out.println("注入对象user....");
        this.user = user;
    }
    public User getUser() {
        
        return user;
    }

    public String sayHello(){
        //学会在struts创建session对象
        
        
        System.out.println(realName);
        
        //输出域模型方式注入的
        System.out.println("用户名:"+user.getUserName());
        System.out.println("密码:"+user.getPassworld());
        System.out.println("工资:"+user.getSalary());
        return "success";
    }    

-----------------------------------------------------------

hello.jsp

<body>
<h1>hello,Struts2</h1>
${user.userName},
${user.salary},
${user.passworld},

</body>

3.参数传递
页面向Action传参
基本属性注入
<input type="text" name="name"/>--->提交-->Filter--->
Action---->String API--->注入--->Action中的成员变量中

--在Action中接收基本属性
1.在Action中定义变量接收属性
2.Struts2会自动实例化该属性
3.Struts2会自动调用set方法为该属性设置值
4.上述行为发生在action实例化后,业务方法调用之前

--表单中文本指定表达式"属性名"
1.name中的表达式直接写action中的属性名
2.Struts2自动回根据名称调用action中对应的set方法为属性赋值.

--练习:在struts2框架下,将表单中数据传递给业务控制器action

域模型注入:
1.在Action中定义实体对象属性,并提供set,get方法
2.表单中文本框指定表达式"对象名.属性名".

--练习:在struts2框架下,将表单中数据传递给业务控制器action(域模型方式)
1.修改上一个案例的form表单,添加文本框
2.新建User类,添加form表单中对应的属性
3.修改HelloAction,接收表单中传入的参数

页面Action中取值
使用EL表达式取出Action的值
.取基本属性值
${属性名}
.取与模型对象值
${对象名.属性名}

结论:
取值时EL表达式的写法,与注入时表达式的写法一致.

Struts2会自动将Action的数据传递给JSP,并且对传递方式进行封装
只要我们在Action中定义属性并为其提供get方法,那么从Action跳转到JSP
时Struts2会自动通过get方法将这些属性值传递给JSP.

--
ognl标签,以及如何创建session.

资费列表
需求描述
.资费管理块:维护的是电信业务中资费的标准,类似于手机号时选择的套餐
.查询功能:是使用列表的方式将维护好的资源数据进行展示

查询功能要求
.按列表形式展示数据,只显示一部分列
.状态字段数据库中存放的是char(1),即0(开通),1(暂停),页面上需要显示中文含义.
.具有分页功能,该功能视具体情况添加

开发思路:
.在浏览器地址栏输入url可以查询资费.
.点击页码也可以查询资费
.上述方式都是针对资费的查询,只是条件发生了变化,因此可以使用一种请求来处理查询功能.

开发步骤
1.entity
.根据资费表COST,创建与其对应的实体类Cost.

2.DAO
.创建资费模块DAO接口ICostDao.java
.声明查询资费方法
-List<Cost> findAll();
.创建DAO实现类CostDaoImpl,实现ICostDao接口
-目前阶段的重点在于struts2的使用,Dao采用模拟的方式简化实现即可.

3.Action
创建处理查询请求的Action,即findAction
.定义输入属性
-action需要JSP传入的参数,称为输入属性
-当前案例中不需要输入属性
.定义输出属性

-Action需要传出给JSP的参数,称为输出属性.
-当前案例中输出属性为List<Cost> costs;

.根据输入算输出
-Action是业务控制器,其本质就是根据输入算输出
-当前案例中,只需要调用Dao查询出资费数据,并且赋值给输出属性即可

4.struts.xml
.在struts.xml文件中配置一个新的package,专门用于封装资费模块中的action
.在当前包下,注册查询的action

5.JSP
使用jstl循环标签,循环输出内容.

OGNL
什么是OGNL
Object Graph Navigation Language,是一门功能强大的表达式语言,类似于EL

为什么要用OGNL
.OGNL表达式功能强大
.Struts2默认采用OGNL表达式访问Action的数据,实际上是通过ValueStack对象来访问的Action

OGNL
.OGNL是独立的开源组件
.Struts2对其进行了改造和封装,可以参数ValueStack

OGNL用法
.Struts2中,OGNL表达式要结合Struts2来访问数据.

8种OGNL的使用方法.
<%@taglib uri="/struts-tags" prefix="s" %>

1.访问基本属性
1.1在action中追加基本属性并初始化,同时提供get和set方法
ID:<s:property value="id"/>

2.访问实体对象
<s:property value="user.userName"/>

3.访问数组/集合
4.访问Map

5.运算


6.调用方法
可以在OGNL中调用返回值所具备的方法

7.创建集合
使用OGNL表达式创建一个临时集合并输出
8.创建Map

如何获取session
.获取session的方式
.ActionContext
-ActionContext.getContext().getSession
-返回类型为Map<String,Object>

.ServletActionContext
ServletActionContext.getRequest.getSession();
-返回类型为HttpSession

.SessionAware
-让Action实现SessionAware接口
-实现void  setSession(Map<String,Object> session)方法
Struts2会在实例化Action后调用该方法,通过方法参数将Session对象注入进来
-定义成员变量,接收注入进来的Session

各种方式对比
-返回类型对比
-第一和第三种方式,获取的session是Map<String,Object>类型
Struts2采用该类型的目的是简化session,session本身的存储结构和Map是一致的.
-第二种方式获取的是HttpSession,为了保持兼容性.
.获取方式对比
-第一和第二种是我妈妈主动获取session
-第三种方式是采用注入的方式注入session,这种方式被动的

.推荐使用第三种
-采用注入思想,更为灵活
-面向接口编程符合时代潮流.

常用类型的result
result标签type属性的诺干值如下:
dispatcher:用于转发的result,可以将请求转发给jsp
在这之前我们使用的result都是这种默认的result.
该默认行为是定义result,通过default="true"指定的.

redirectAction
.用于将请求重定向给另外一个Action.

登入的需求:

1.创建admin管理员实体类
id,name,pwd,tel.
2.创建登入模块Dao,工厂模式
3.创建Action完成验证,验证通过则将用户信息

当使用type=“redirectAction” 或type=“redirect”提交到一个action并且需要传递一个参数时。这里是有区别的: 

a.使用type=“redirect”时,结果应是action配置名+后缀名 
Java代码 
 
<action name="Login" class="steven.actions.LoginAction"> 
<result name="success" type="redirect">User.action?u_id=${loginBean.u_id}</result> 
</action> 

b.使用type=“redirectAction”时,结果就只能写Action的配置名,不能带有后缀:“.action” 
Java代码

<action name="Login" class="steven.actions.LoginAction">
<result name="success" type="redirectAction">User?u_id=${loginBean.u_id}</result>
</action>

拦截器
1.1作用:
拦截器的用途:拦截器适合封装一些通用处理,例如请求参数传递给action的属性
日志的记录,权限检查,事务处理等等,拦截器是通过配置方式调用的,因此使用方法比较灵活,便于维护和扩展.

Struts2框架下如何创建拦截器
1.创建拦截器组价
.创建一个类,实现Interceptor接口,实现intercept方法
public String intercept(ActionInvocation invocation) throws Exception {
            //拦截器--前部分处理
           invocation.invoke();
            //拦截器--后部分处理
        return null;
    }
    
2.注册拦截器
在struts.xml中,注册拦截器
<interceptors>
            <interceptor name="别名" class="实现类"/>
</interceptors>

3.引用拦截器
如果哪个action希望被拦截器扩展,需要在此action配置下引用拦截器
<action>
<interceptor-ref name="拦截器"/>
...可以引用多个
</action>

--练习:拦截器的helloWorld

-----------------------------------------------------------

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<!-- 
package:包,用于对Action进行封装
1.name:包名,根据元素下可以有多个包,彼此之间不能重名
2.extends:继承,用于指定继承的包,相当于将继承包下的配置信息复制到了当前包下.
3.namespace:命名空间,用于规定Action的访问路径,必须以"/"开头
4.请求Action时,按照如下格式拼写url:
http://localhost:8080/Sc1807-2Struts2/demo/hello.action
http://ID:PORL/APPNAME/NAMESPACE/ACTIONNAME.action
action为固定后缀,可以省略.
 -->
<struts>
<package name="day01" namespace="/demo" extends="struts-default">

<action name="hello" class="com.sicheng.action.HelloAction" method="sayHello">
<!-- 
action:业务控制器,用于注册业务控制器主键(类)
1.name:action名称,用于规定Action的访问路径,一个包下可以有多个Action,但是彼此之间不能重名
2.class属性:业务控制器组件,用于指定业务控制器对应的类
3.method:方法,用于指定访问当前action时要调用的方法.
 -->
        <result name="success">
<!-- 
result:输出组件,用于转发,重定向,直接输出
1.name:名称,一个action下可以有多个result,彼此之间不能重名
2.默认做转发,标记内容设置成转发的页面
 -->
        /hello.jsp
        </result>
</action>

</package>
</struts>    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值