Struts框架

Struts框架

一、引言

框架 : 代码的半成品 —> 功能的封装(强大)、通用性。

Servlet规范 冗余!! ----> 使用Struts2框架 替换 Servlet技术

1、Servlet的问题

1、 接收用户提交数据 
	String value = request.getParameter(String name);
	1.1 冗余
	1.2 编码格式的设置
	1.3 类型转换
	
2、 跳转路径的硬编码
	2.1错误的提示没有
	2.2都需要修改源文件

2、Struts2开发的思想

在这里插入图片描述

二、开发步骤

1、环境搭建

​ 1.1 导入jar包

​ 核心jar包和三方jar包 9个

​ 1.2 引入配置文件

​ 必须将文件放在src的根目录中!

​ 1.3 初始化配置 、 配置struts2的核心过滤器

​ 使Struts2框架生效

	<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>
2、编码
实现Action接口

    import com.opensymphony.xwork2.Action;

    public class MyAction implements Action{

        @Override
        public String execute() throws Exception {
            System.out.println("-----Action-----Struts2------");
            return "firstAction";
        }

    }

3、配置struts.xml
<struts>	
	<!-- package 和 src中的包没任何关系    name="随便写"  extends="规定" -->
	<package name="day1" extends="struts-default">
		<!-- name="访问路径"   class=""全限定名称-->
		<action name="my" class="com.baizhi.action.MyAction">
			<!-- name="方法中的返回值" -->
			<result name="firstAction">/index.jsp</result>
		</action>
	</package>	
</struts>
补充
1、获取request、response
	//工具类 ServletActionContext
	HttpServletRequest request = ServletActionContext.getRequest();

2、访问路径
	namespace = "/"  默认 /
    访问路径 localhost:8989/项目名/namespace/action name
    
    http://localhost:8989/Struts_Day1/user/my
    http://localhost:8989/Struts_Day1/user/my.action

3、Action是单例还是多例????
	Servlet  单例
	Action	 多例 ---> 可以定义成员变量

三、Struts2的跳转

两大类 : forward : 请求转发 / redirect:重定向

Action ----> Jsp(页面) : dispatcher (默认值) / redirect

Action ----> Action : chain / redirectAction

1、Action跳转至Jsp页面
Struts中进行跳转默认是forward请求转发,地址栏没有发生改变。 

1、 forward : 请求转发

    <action name="my" class="com.baizhi.action.MyAction">
        <!-- name="方法中的返回值" -->
        <result name="firstAction" type="dispatcher">/index.jsp</result>
    </action>

2、 redirect:重定向

	<action name="my" class="com.baizhi.action.MyAction">
        <!-- name="方法中的返回值" -->
        <result name="firstAction" type="redirect">/index.jsp</result>
    </action>
2、Action跳转至Action

在这里插入图片描述

3、package标签

分包:在struts.xml中 跟java的包 没有任何关系。

1.namespace 命名空间

决定了本包中所有action访问的路径标识

2.跨包跳转

针对的是Action到Action的跳转

在这里插入图片描述

3.全局跳转

同包中存在不同action包含了相同的result返回跳转路径,则可以进行冗余配置的提取。

作用范围:仅同包!!!

package中标签存在配置书写顺序。

​ result-types?,interceptors?,default-interceptor-ref?,default-action-ref?,

​ default-class-ref?,global-results?,global-exception-mappings?,action*

在这里插入图片描述

使用Struts2技术+JDBC技术+Jsp技术

登陆 + 展示所有 跨包配置!!!



一、Struts2 使用成员变量接收数据

替换 request.getParameter ()

完成数据的接收 / 编码格式的设置(utf-8) / 数据类型的转换

1.1 接收基本类型数据 八种+String+Date

页面

    Username:	<input type="text" name="username"/></br>
    Age:		<input type="text" name="age"/></br>
    Salary:		<input type="text" name="salary"/></br>
    Date:		<input type="date" name="date"/></br>

Action中

    private String username;
    private int age;
    private double salary;
    private Date date;
	set/get 方法
	
	注意:成员变量名称 与  页面中 input标签的name属性
	
	get : localhost:8989/项目/资源路径?name=value    name就是成员变量名称
1.2对象类型

User对象

页面

    Username:	<input type="text" name="u.username"/></br>
    Age:		<input type="text" name="u.age"/></br>
    Salary:		<input type="text" name="u.salary"/></br>
    Date:		<input type="date" name="u.date"/></br>

Action

    private User u;

    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }

集合类型

User 中属性
	private List<String> hobby;

页面中
	<input type="checkbox" name="user.hobby"  value="1"/>吃饭
   	<input type="checkbox" name="user.hobby"  value="2"/>睡觉
   	<input type="checkbox" name="user.hobby"  value="3"/>烫头
   	
   	
User [username=刘洋, age=123, salary=123.123, 
      date=Fri Dec 06 00:00:00 CST 2019, hobby=[2, 3]]

二、DMI 动态方法调用

Action的开发过程中 一个Action类只有一个execute方法。

问题----> Action类的数量过多不方便管理

1. 继承ActionSupport类
public class MyAction2 extends ActionSupport{
	//继承ActionSupport  开发人员可以自定义方法
	//减少了项目中Action的数量
	
	//规定!!!   无参!!!!!
	//public String  方法名随意()异常随意{}
	public String loginMethod1(){
		System.out.println("-----登陆方法-------");
		return "loginMethod";
	}
	
	
	public String showAllMethod2(){
		System.out.println("-----展示所有方法-------");
		return "showAllMethod";
	}
}
2.struts.xml 配置

配置方式之一

    <package name="day2.am" extends="struts-default" namespace="/">
        <action name="method1" class="com.baizhi.action.MyAction2"
                method="loginMethod1">
            <result name="loginMethod" type="redirect">/login.jsp</result>
        </action>
        <action name="method2" class="com.baizhi.action.MyAction2" 
                method="showAllMethod2">
            <result name="showAllMethod" type="redirect">/login.jsp</result>
        </action>
    </package>

注意: action标签中多了一个属性 method ="同一个类中不同的方法名称” 

配置方式之二

<package name="day2.am" extends="struts-default" namespace="/">
    <!--  method_ 仅仅是为了区分使用 不加也行  -->
    <action name="method_*" class="com.baizhi.action.MyAction2" method="{1}">
        <result name="loginMethod" type="redirect">/login.jsp</result>
        <result name="showAllMethod" type="redirect">/login.jsp</result>
    </action>
</package> 




<!-- 相同Action中不同的方法间的跳转 -->
<result name="loginMethod" type="redirectAction">method_showAllMethod2</result>
<result name="showAllMethod" type="redirect">/login.jsp</result>

在这里插入图片描述

三、使用成员变量替换request作用域

成员变量 没有去替换request作用域本身,而是对作用域进行了封装。

成员变量 = request.setAttribute(String name, Object value);

多个Action中如果有相似应用的需求,成员变量不能重名。

原始方式:
	List<User> users = userService.showAllUsers();
	HttpServletRequest request = ServletActionContext.getRequest();
	request.setAttribute("users", users);


成员变量方式
	private List<User> users;
	set/get方法
		
	users = userService.showAllUsers();


取值:
	和之前一模一样
	${requestScope.key}      key=成员变量的名称

在这里插入图片描述

四、文件上传

在这里插入图片描述

1、页面
    <form action="" method="post" enctype="multipart/form-data">
        <input type="file" name="file"/>
        <input type="submit" value="上传"/>
    </form>
2、Action接收数据
Action中定义成员变量
	private File file;    set/get方法;
3、写入服务器硬盘
        InputStream is = new FileInputStream(file);
        OutputStream os = new FileOutputStream("F:/tomcat7/my.txt");
        byte[] b = new byte[1024];
        int len = 0;  // -1 结束
        while(true){
            len = is.read(b, 0, b.length);
            if(len==-1){
                break;
            }else{
                os.write(b,0,len);
            }
        }
        os.close();
        is.close();
    <package name="upload" extends="struts-default" namespace="/">
        <action name="uploadFile" class="com.baizhi.upload.MyUpload"
                method="uplaodFile">
            <result name="uploadSuccess">/MyJsp.jsp</result>
        </action>
    </package>
4、待解决问题

1.文件名称如何获取

//文件的名称   上传的文件+FileName
	private String fileFileName;
//文件的互联网类型   上传的文件+ContentType   (一般在下载的时候使用)
	private String fileContentType;
	set、get方法

2.上传之后保存的路径写死了

String realPath = ServletActionContext.getServletContext().getRealPath("/file");

获取了:
	服务器中项目的具体路径 --- 绝对路径
	/file  项目中的具体文件夹

3.原始IO效率低下

FileUtils.copyFile(file, new File(realPath+"/"+fileFileName));

4.文件上传的大小限制

默认2M 在struts.xml中可以配置

struts.multipart.maxSize = 2097152	
<constant name="struts.multipart.maxSize" value="20971520000"></constant>
5.成员变量可以获取struts.xml中的配置信息
<action name="uploadFile" class="com.baizhi.upload.MyUpload" method="uplaodFile">
		<param name="saveFile">/file</param>
		<result name="uploadSuccess">/MyJsp.jsp</result>
</action>




java:
	private String saveFile;
	set/get

 String realPath = ServletActionContext.getServletContext().getRealPath(saveFile);


一、配置文件分包

<struts>	
    <!--包含其他配置文件  但是struts.xml只能有一个  最终一定是引入带struts.xml里-->
	<include file="struts_user.xml"></include>
	<package name="user" extends="struts-default" namespace="/user">
		.......
	</package>
</struts>

二、拦截器

减少Action中的冗余代码,提高项目的可维护性。

1、开发 .java
实现interceptor接口

	public String intercept(ActionInvocation ai) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("------intercept------");
		//请求放行    相当于过滤器中   chain.doFilter();
		ai.invoke();
		//跳转   强制登陆 跳转回登陆页面
		return null;
	}
2、配置

在这里插入图片描述

注意:拦截器中的返回值 return 应该如何配置

在这里插入图片描述

建议后续使用全局跳转进行配置!!!!!

3、拦截器栈

多个拦截器的冗余配置提取到拦截器栈中

在这里插入图片描述

4、默认拦截器配置
    <!-- 本包中 所有的action都会被拦截器进行默认拦截 -->
    <default-interceptor-ref name="myStack"></default-interceptor-ref>
5、Struts中的拦截体系

一旦在Struts2中使用用户自定义拦截器,系统拦截器失效!

需要用户在使用拦截器的过程中手动添加系统拦截器。

<interceptors>
    <interceptor name="loginInterceptor" 
                 class="com.baizhi.interceptor.LoginInterceptor"></interceptor>
    <interceptor-stack name="myStack">
        <!-- 系统默认拦截器 -->
        <interceptor-ref name="defaultStack"></interceptor-ref>
        <interceptor-ref name="loginInterceptor"></interceptor-ref>
    </interceptor-stack>
</interceptors>
6、方法拦截器

针对Action中具体的方法名称

继承抽象类!!!
public class MyMethodInterceptor extends MethodFilterInterceptor{
	@Override
	protected String doIntercept(ActionInvocation ai) throws Exception {
		System.out.println("----我是方法拦截器------");
		ai.invoke();
		return null;
	}
}

配置

在这里插入图片描述

开发步骤

1、 实现拦截器

​ 拦截器 实现interceptor接口 / 方法拦截器 继承 MethodFilterInterceptor

2、 配置

​ 2.1 声明拦截器

​ 2.2 配置拦截器栈 (添加系统默认拦截器)

​ 2.3 可以使用全局跳转 以及 默认拦截器配置进行优化

三、文件下载

1、页面
	<a href="${pageContext.request.contextPath}/downloadFile?
             fileName=1.jpg&type=image/jpeg">下载图片</a>
	fileName:需要下载的文件名称
	type:下载的文件类型
2、Action
public class MyDownLoad extends ActionSupport {
    private String fileName;
    private String type;  //类型的动态替换
    private String saveFile;
    //方法返回值???  
    //需要将文件返回给浏览器    通过流输入给浏览器
    public InputStream getInputStream() throws FileNotFoundException{
        String realPath = 
            ServletActionContext.getServletContext().getRealPath(saveFile);
        return new FileInputStream(realPath+"/"+fileName);
    }
}

注意:Struts2成员变量能做什么?

1.接收参数 2.替换request作用域代码简化传递

3.从struts.xml中读取数据 4.向Struts.xml中赋值数据

3、Struts.xml
<package name="download" extends="struts-default" namespace="/">
    <!-- name =  访问路径    action标签中没有method属性 !!!! -->
    <action name="downloadFile" class="com.baizhi.download.MyDownLoad">
        <!--成员变量读取文件夹名称-->
        <param name="saveFile">/file</param>
        <!-- name可以不写 name=success 默认参数 -->
        <!--  type :标识方法的返回值类型   stream: 指向 StreamResult -->
        <result type="stream">
            <!--通过成员变量赋值确定下载的文件类型   ${成员变量名称}-->
            <param name="contentType">${type}</param>
            <!-- contentDisposition 下载的数据保存类型 -->
            <!--attachment 附件    inline 使用浏览器打开 -->
            <param name="contentDisposition">attachment;filename=${fileName}
            </param>
        </result>
    </action>
</package>

周末

登陆 / 注册 + 验证码 强制登陆 + 头像

展示数据,修改,删除

选做 展示时点击图片下载!!

Mvc思想:
在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值