Struts2笔记

时间:2022-07-24
本文章向大家介绍Struts2笔记,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

搭建Struts2的开发环境:

a、拷贝jar包到应用的构建路径中

从Struts2的发行包:

appsstruts_blank.war

b、在web.xml中对核心控制器进行配置

c、在应用的构建路径的顶端(WEB-INFclasses),建立struts2的配置文件。默认文件名struts.xml

第一个Struts2的入门案例

a、建立一个hello.jsp的页面

b、修改struts2的默认配置文件:struts.xml,增加以下内容

c、建立动作类和动作方法

d、定义结果页面

执行原理:

配置文件struts.xml没有提示

a、方案一:联网

b、方案二:进行本地配置

Struts2的配置文件的位置和加载顺序

一、default.properties:在struts2-core-**.jar包中的org.pache.struts2.default.properties中(框架本身用的)

二、struts-default.xml:在struts2-core-**.jar包中(框架本身用的)

三、struts-plugin.xml:在struts2-**-plugin.jar包中(插件中,给插件用的)

四、struts.xml:在你应用的构建路径中(程序员进行配置的地方。推荐)

五、struts.properties:在你应用的构建路径中(程序员进行配置的地方)

六、web.xml:此处也可以对struts2框架进行配置(不建议。只建议配置过滤器)

重点:后面配置文件中的配置会覆盖掉前面的配置。

struts.xml中的package的namespace细节

struts.xml中的action的配置

struts.xml中的常量配置

<constant name="struts.devMode" value="true" />

name:常量的名称。

(struts2-core-**.jar org.apache.struts.default.properties)文件中

常用的常量:

struts.action.extension=action,, 框架要处理的后缀名称。

struts.devMode = true 开发着模式。实际运行时建议为false

struts.i18n.encoding=UTF-8 框架默认使用的编码。请求参数和输入响应

struts.serve.static.browserCache=true 静态资源要不要缓存。(response.setHeader():Expires;Cache-Control;Progma)

struts.ui.theme=xhtml 和显示结果有关,显示用的主题。simple等

struts.objectFactory = spring 指定实例化动作类的工厂(和Spring集成时用)

struts.enable.DynamicMethodInvocation = false 是否允许动态方法调用

struts.multipart.maxSize=2097152 文件上传时的大小限制

Struts.xml可以有多个

主配置文件叫struts.xml,假设单独模块配置文件叫struts-login.xml

struts.xml 包含 struts-login.xml: <include file="com/china/action/struts-login.xml"/>

实现了模块化开发。

动作类

动作类的定义:

方式一:就是一个普通的POJO。不需要继承或实现任何的类或接口。

方式二:实现com.opensymphony.xwork2.Action

该接口中定义了几个常量:

String SUCCESS = "success";//执行成功时用

String NONE = "none";//执行成功后,不转向任何的视图。比如文件下载。

String ERROR = "error";//执行失败,遇到错误。

String INPUT = "input";//输入验证失败或转换失败,转向输入原有页面。

String LOGIN = "login";//没有登录时,转向的页面。

public String execute() throws Exception;

优点:可以使用常量,编码可以做到尽量统一。

方式三:(推荐)

继承com.opensymphony.xwork2.ActionSupport(默认的动作类)。实现了com.opensymphony.xwork2.Action

定义了 表单域校验、错误信息设置和获得国际化信息相关一些方法

动作类的生命周期

动作类每次访问都会重新被实例化,是线程安全的。

动作方法:动作类中的定义的处理业务有关的方法

特点(重要):public

返回值类型是String

方法没有任何的参数

动作方法通配符的匹配

动作方法的动态调用

指定默认的动作类和动作方法

获取内置对象request,session.application

1)解耦:

ActionContext cont = ActionContext.getContext();
//request
Map<String,Object> request = (Map<String,Object>)cont.get("request");
request.put("key", "value");

//session
Map<String,Object> session = cont.getSession();
session.put("key", "value");

//application
Map<String,Object> application = cont.getApplication();
application.put("key", "value");

2)耦合:

//request
HttpServletRequest request = ServletActionContext.getRequest();
request.setAttribute("name", "value");

//session
HttpSession session = request.getSession();
session.setAttribute("name", "value");

//application == ServletContext
ServletContext cont = session.getServletContext();
cont.setAttribute("name","value");

局部和全局结果视图

常用的结果视图类型(共10个)

<result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>  从一个动作转发到另外一个JSP
<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>   从一个动作转发到另外一个动作
<result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
<result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
<result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>  从一个动作重定向到一个JSP
<result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>  从一个动作重定向到另外一个动作
<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>  文件下载
<result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
<result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
<result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />  以纯文本的形式显示JSP

文件下载

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import javax.servlet.ServletContext;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
//文件下载;结果类型stream的使用
public class DownLoadAction extends ActionSupport {
    
    private InputStream imageInputStream;
    
    public InputStream getImageInputStream() {
        return imageInputStream;
    }

    public void setImageInputStream(InputStream imageInputStream) {
        this.imageInputStream = imageInputStream;
    }

    public String download() throws Exception{
        //得到文件的真实路径
        ServletContext sc = ServletActionContext.getServletContext();
        String filePath = sc.getRealPath("/WEB-INF/classes/26.jpg");
        //构建输入流
        imageInputStream = new FileInputStream(filePath);
        //用stream结果视图输出
        //返回逻辑视图
        return SUCCESS;
    }
}
    <package name="p5" extends="struts-default">
        <action name="download" class="com.itheima.actions.DownLoadAction" method="download">
            <result name="success" type="stream">
                <!-- 配置输入流 -->
                <param name="inputName">imageInputStream</param>
                <!-- 告知浏览器响应正文的MIME类型 -->
                <param name="contentType">application/octet-stream</param>
                <!-- 告知浏览器用下载的方式打开 -->
                <param name="contentDisposition">attachment;filename=26.jpg</param>
                <!-- 下载时使用的缓存大小 -->
                <param name="bufferSize">1024</param>
            </result>
        </action>
    </package>

Action中接收请求参数

1)ActionSupport

JSP提交页面:

<form action="zheng/getUserAction" method="post">
用户名:
<input type="text" name="user.username">
<br />
密码:
<input type="password" name="user.pwd">
<br />
<input type="submit" value="提交">

</form>

User 类:

public class User{ 
private String username; 
private String pwd; 
public String getUsername() { 
return username; 
} 
public void setUsername(String username) { 
this.username = username; 
} 
public String getPwd() { 
return pwd; 
} 
public void setPwd(String pwd) { 
this.pwd = pwd;    }
}

Action:

public class 类名 extends 
ActionSupport{

private User user;

public User getUser() {
return user;
}

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


public String execute(){

String name = user.getUsername();
System.out.println(name);

return "success";
}

}

JSP显示值页面:

<body>
<%=request.getParameter("user.username")%> 
EL表过式: ${user.username}
${requestScope.user.uname}
</body>

===============================================================================================================

2)ModelDriven

JSP提交页面:

<form action="zheng/getUserAction" method="post">
用户名:
<input type="text" name="username">
<br />
密码:
<input type="password" name="pwd">
<br />
<input type="submit" value="提交">

</form>

User 类:

public class User{ 
private String username; 
private String pwd; 
public String getUsername() { 
return username; 
} 
public void setUsername(String username) { 
this.username = username; 
} 
public String getPwd() { 
return pwd; 
} 
public void setPwd(String pwd) { 
this.pwd = pwd;    }
}

Action:

public class GetUserAction implements ModelDriven<User>{//注意:这里的参数是User

private User user = new User();

public User getModel() {

return user; //注意:这里返回的是User 对象
}

public String execute(){


String username = getModel().getUsername();
System.out.println(username);

return "success";
}
}

JSP显示值页面:

<body>
<%=request.getParameter("username")%>
EL表过式: ${username}/
${param.uname}/ ${requestScope.uname} 
</body>

========================================================================================================== 3)在action中定义属性

JSP提交页面:

<form action="zheng/getUserAction" method="post">
用户名:
<input type="text" name="username">
<br />
密码:
<input type="password" name="pwd">
<br />
<input type="submit" value="提交">

</form>

Action:

public class GetUserAction{

private String username;
private String pwd;

public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}

public String execute(){

System.out.println("name= "+getUsername());

return "success";
}

}

JSP显示值页面:

<body>
<%=request.getParameter("username")%>
EL表过式: ${username}
</body>

还可以结合起来:

原理:实际上由一个拦截器来完成的modelDriven

该拦截器会在执行动作方法前,把模型对象压到ValueStack值栈的栈顶。

上传附件

重要:如果因为文件大小不能上传可以在struts.xml中配置<constant name="struts.multipart.maxSize" value="100000000"/> 1)单个附件上传,上传到服务器的硬盘上,用的是struts2提供的二个包 ( commons-io-1.3.2.jar commons-fileupload-1.2.1.jar)

private File uploadImage; //得到上传的文件 注和JSP页上的 text=file 的名称(name)是一样的 private String uploadImageContentType; //得到文件的类型 private String uploadImageFileName; //得到文件的名称 struts2 提供方法 FileUtils.copyFile()

     String realPath=ServletActionContext.getServletContext().getRealPath("/upload");
        File file=new File(realPath);
        if(!file.exists()){
            file.mkdirs();
        }
        FileUtils.copyFile(uploadImage, new File(file, uploadImageFileName));

2)多个附件上传,上传到服务器的硬盘上,用的是struts2提供的二个包 private File[] image; // 上传的文件 private String[] imageFileName; // 文件名称 private String[] imageContentType; // 文件类型 FileUtils.copyFile(,)

使用struts标签在页面上显示多个图片的jsp代码:

<%@ taglib  prefix="s" uri="/struts-tags" %>

<body>
   上传成功
    <s:iterator id="img" value="#session.name" status="st">
       第<s:property value="#st.getIndex()+1" />个图片<br>
        <img src="upload/<s:property value='#img'/>" width="300">
        <br>
    </s:iterator>
</body>

3) 单个附件上传,上传到服务器的硬盘上,用的是IO private File uploadImage; //得到上传的文件 注和JSP页上的 text=file 的名称是一样的 private String uploadImageContentType; //得到文件的类型 private String uploadImageFileName; //得到文件的名称 + IO

     BufferedInputStream bis=null;
        BufferedOutputStream bos=null;
        
        bis=new BufferedInputStream(new FileInputStream(user.getUploadImage()));
        bos=new BufferedOutputStream(new FileOutputStream(new File(file, newFileName)));
        byte []buf=new byte[4096];
        int len=-1;
        while((len=bis.read(buf))!=-1){
            bos.write(buf, 0, len);
        }
        bos.flush();
        bos.close();
        bis.close();

4) 多个附件上传,上传到服务器的硬盘上,用的是IO private File[] image; //上传的文件 private String[] imageFileName; //文件名称 private String[] imageContentType; //文件类型

或 private List<File> image; // 上传的文件 private List<String> imageFileName; // 文件名称 private List<String> imageContentType; // 文件类型 + IO