搭建Struts2的开发环境:
a、拷贝jar包到应用的构建路径中
从Struts2的发行包:
apps\struts_blank.war
b、在web.xml中对核心控制器进行配置
c、在应用的构建路径的顶端(WEB-INF\classes),建立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