HelloWorld环境搭建
- 在eclipse中创建Web动态项目struts
- 导入jar包
-
- WEB-INF目录下新建web.xml
<web-app> <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> <dispatcher>FORWARD</dispatcher> <dispatcher>REQUEST</dispatcher> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
- 在src目录下创建一个struts.xml文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="basicstruts" extends="struts-default"> <action name="index"> <result>index.jsp</result> </action> </package> </struts>
- web目录下创建index.jsp
总结流程原理:
显示数据到jsp
- Product.java 用于存放数据
public class Product {
int id;
String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Product { int id; String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
- ProductAction用于控制
-
public class ProductAction { private Product product; public String show() { product = new Product(); product.setName("iphone7"); return "show"; } public Product getProduct() { return product; } public void setProduct(Product product) { this.product = product; } }
- 在struts.xml中配置跳转
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="basicstruts" extends="struts-default"> <action name="showProduct" class="com.how2java.action.ProductAction" method="show"> <result name="show">show.jsp</result> </action> </package> </struts>
- 在web目录下创建show.jsp文件。通过EL表达式,取出product的name。${product}会访问对应的Action的 getProduct()方法
<%@page isELIgnored="false"%> ${product.name}
- 原理流程如下:
中文乱码问题:
Struts的中文问题,由3部分组成
1. jsp提交数据的时候,必须是UTF-8编码的 (提交数据指定编码方式UTF-8,POST方式提交)
1. jsp提交数据的时候,必须是UTF-8编码的 (提交数据指定编码方式UTF-8,POST方式提交)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false"%> <html> <form action="addProduct" method="post"> <input type="text" name="product.name"> <br/> <input type="submit" value="submit"> </form> </html>2. struts拿到数据后进行UTF-8解码
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.i18n.encoding" value="UTF-8"></constant> <package name="basicstruts" extends="struts-default"> <action name="showProduct" class="com.how2java.action.ProductAction" method="show"> <result name="show">show.jsp</result> </action> <action name="addProduct" class="com.how2java.action.ProductAction" method="add"> <result name="show">show.jsp</result> </action> </package> </struts>3. 服务端跳转到jsp进行显示的时候,要指定浏览器使用UTF-8进行显示
UTF-8可以换成GBK或者GB2312,但是必须统一,不能混用
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false"%> <%@page isELIgnored="false"%> ${product.name}
为了便于调试,在src下增加log4j配置文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration PUBLIC "-//log4j/log4j Configuration//EN" "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d %-5p %c.%M:%L - %m%n"/> </layout> </appender> <!-- specify the logging level for loggers from other libraries --> <logger name="com.opensymphony"> <level value="DEBUG" /> </logger> <logger name="org.apache.struts2"> <level value="DEBUG" /> </logger> <!-- for all other loggers log only debug and above log messages --> <root> <priority value="INFO"/> <appender-ref ref="STDOUT" /> </root> </log4j:configuration>
在struts中也可以获取servlet包中的request和response对象
public class ProductAction extends ActionSupport { private Product product; public String show() { HttpServletRequest request = ServletActionContext.getRequest(); HttpServletResponse response = ServletActionContext.getResponse(); System.out.println("request:\t" + request); System.out.println("response:\t" + response); product = new Product(); product.setName("iphone7"); return "show"; } public String add() { Map m = ActionContext.getContext().getSession(); m.put("name", product.getName()); return "show"; } // public void validate(){ // if ( product.getName().length() == 0 ){ // addFieldError( "product.name", "name can't be empty" ); // } // } public Product getProduct() { return product; } public void setProduct(Product product) { this.product = product; } }struts中的Session有两个
一个是传统的servlet包下的HttpSession
另一个是Struts中自己定义的Session
传统的servlet包下的session的获取办法是:
ServletActionContext.getRequest().getSession();
使用该方法,需要在eclipse的项目中导入servlet-api.jar,可以在右边下载
新的Session的获取办法是
Map m = ActionContext.getContext().getSession();
这个session以Map类的形式出现,其中的值和HttpSession中的值是同步的
在Action类中放入值
public class ProductAction extends ActionSupport { private Product product; public String show() { product = new Product(); product.setName("iphone7"); return "show"; } public String add() { Map m = ActionContext.getContext().getSession(); m.put("name", product.getName()); return "show"; } public Product getProduct() { return product; } public void setProduct(Product product) { this.product = product; } }通过jsp的EL表达式获取值
<%@page isELIgnored="false"%> ${product.name} ${name}
使用struts进行文件的上传
form表单加上enctype="multipart/form-data"表示表示提交的数据是二进制的
method方法为method="post"
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false"%> <%@page isELIgnored="false" %> <%@ taglib prefix="s" uri="/struts-tags" %> <html> <body> <form action="upload" method="post" enctype="multipart/form-data"> 上传文件 : <input type="file" name="doc" /> <br> <input type="submit" value="上传"> </form> </body> </html>UploadAction的类:
File doc; 属性名字必须与表单的name一致。
String docFileName;
String docContentType;
String docFileName;
String docContentType;
public class UploadAction { File doc; String docFileName; String docContentType; public File getDoc() { return doc; } public void setDoc(File doc) { this.doc = doc; } public String getDocFileName() { return docFileName; } public void setDocFileName(String docFileName) { this.docFileName = docFileName; } public String getDocContentType() { return docContentType; } public void setDocContentType(String docContentType) { this.docContentType = docContentType; } public String upload() { System.out.println(doc); System.out.println(docFileName); System.out.println(docContentType); return "success"; } }struts.xml
为upload路径配置UploadAction,并返回success.jsp
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="basicstruts" extends="struts-default"> <action name="showProduct" class="com.how2java.action.ProductAction" method="show"> <result name="show">show.jsp</result> </action> <action name="addProduct" class="com.how2java.action.ProductAction" method="add"> <result name="input">addProduct.jsp</result> <result name="show">show.jsp</result> </action> <action name="upload" class="com.how2java.action.UploadAction" method="upload"> <result name="success">success.jsp</result> </action> </package> </struts>success.jsp
分别显示doc,docFileName,docContentType
<%@page isELIgnored="false"%> uploaded success ${doc} <br/> ${docFileName} <br/> ${docContentType} <br/>struts上传文件的大小默认是比较小的只有2M,可以进行设置
在struts.xml中<constant name="struts.multipart.maxSize" value="10240000"/>
struts有专属标签库
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.multipart.maxSize" value="10240000"/> <package name="basicstruts" extends="struts-default"> <action name="showProduct" class="com.how2java.action.ProductAction" method="show"> <result name="show">show.jsp</result> </action> <action name="addProduct" class="com.how2java.action.ProductAction" method="add"> <result name="input">addProduct.jsp</result> <result name="show">show.jsp</result> </action> <action name="upload" class="com.how2java.action.UploadAction" method="upload"> <result name="success">success.jsp</result> </action> </package> </struts>
struts有专属标签库
<%@ taglib prefix="s" uri="/struts-tags" %> <html> <body> <s:form action="addProduct"> <s:textfield name="product.name" label="product name" /> <s:submit value="Submit" /> </s:form> </body> </html>
jsp结果遍历标签
使用s:iterator标签进行遍历
value 表示集合
var 表示遍历出来的元素
st 表示遍历出来的元素状态
st.index 当前行号 基0
st.count 当前行号 基1
st.first 是否是第一个元素
st.last 是否是最后一个元素
st.odd 是否是奇数
st.even 是否是偶数
value 表示集合
var 表示遍历出来的元素
st 表示遍历出来的元素状态
st.index 当前行号 基0
st.count 当前行号 基1
st.first 是否是第一个元素
st.last 是否是最后一个元素
st.odd 是否是奇数
st.even 是否是偶数
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false"%> <%@ taglib prefix="s" uri="/struts-tags"%> <style> table { border-collapse: collapse; } td { border: 1px solid gray; } </style> <table align="center"> <tr> <td>id</td> <td>name</td> <td>st.index</td> <td>st.count</td> <td>st.first</td> <td>st.last</td> <td>st.odd</td> <td>st.even</td> </tr> <s:iterator value="products" var="p" status="st"> <tr> <td>${p.id}</td> <td>${p.name}</td> <td>${st.index}</td> <td>${st.count}</td> <td>${st.first}</td> <td>${st.last}</td> <td>${st.odd}</td> <td>${st.even}</td> </tr> </s:iterator> </table>
基于注解方式的struts
1. 为了使struts支持注解,需要用到struts2-convention-plugin-x.x.x.jar 这个jar包
2. 下载好了之后,放在WEB-INF/lib 下
3. 不仅如此,还要在项目导入jar,以使得eclipse能够编译通过
4.注释掉xml配置文件中的<action><result>
2. 下载好了之后,放在WEB-INF/lib 下
3. 不仅如此,还要在项目导入jar,以使得eclipse能够编译通过
4.注释掉xml配置文件中的<action><result>
5.添加注解到action类中
@Namespace("/")表示访问路径,如果是@Namespace("/test"),那么访问的时候,就需要写成http://127.0.0.1:8080/struts/test/showProduct
@ParentPackage("struts-default")与配置文件中的struts-default相同,表示使用默认的一套***
@Results({@Result(name="show", location="/show.jsp") 预先定义多个results, "show" 返回"/show.jsp" , "home" 返回 "/index.jsp".
@Result(name="home", location="/index.jsp")}) 注: 这里并没有用到"home",写出来的目的是为了演示这种定义多个result 的代码风格。
@Action("showProduct") 表示当访问路径是showProduct的时候,就会调用show方法@Namespace("/") @ParentPackage("struts-default") @Results({@Result(name="show", location="/show.jsp"), @Result(name="home", location="/index.jsp")}) public class ProductAction { private Product product; @Action("showProduct") public String show() { product = new Product(); product.setName("iphone7"); return "show"; } public Product getProduct() { return product; } public void setProduct(Product product) { this.product = product; } }
那么到底应该用注解还是配置呢?从个人经验来讲,小项目适合用注解,大项目因为其复杂性,采用注解会导致配置信息难以维护和查询,更适合采用xml配置方式。