概述
Struts2
Struts2 简介
Struts2 实战
我们主要的学习资料和代码来自how2java。
Hello world!
对于一个Struts2的web项目,我们首先得配置一个web.xml。
其中,定义了一个filter过滤器,所有的请求都会通过该过滤器的过滤。
<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>
下面是一个简单struct2配置文件:
其中,该文件告诉我们,当我们请求index的时候,给它跳转到index.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="index">
<result>index.jsp</result>
</action>
</package>
</struts>
将model传递给jsp
model层
一个简单的Product类:
package com.how2java.bean;
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;
}
}
Controllor 控制器
一个简单的ProductAction控制类:
package com.how2java.action;
import com.how2java.bean.Product;
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;
}
}
下面是Sturts的配置文件
<?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>
一个简单的网页jsp
<%@page isELIgnored="false"%>
${product.name}
最后,启动服务器,访问网站:
那么这一过程发生了什么呢?
- 用户通过浏览器访问
/showProduct
- 用户访问的方式被过滤器过滤给了
struct
stuct
发现/showProduct
抛给了ProductAction
控制器的show
方法show
方法 为该类设置了Product
的值,然后转到了show.jsp
页面show.jsp
中有${product.name}
于是调用了控制器中的get
方法获取product
,然后获取到其名字,在我们的网页中显示出来了。
数据提交
首先是一个简单的前端表单
<html>
<form action="addProduct">
<input type="text" name="product.name">
<br/>
<input type="submit" value="submit">
</form>
</html>
配置一个URL:addProduct
<action name="addProduct" class="com.how2java.action.ProductAction" method="add">
<result name="show">show.jsp</result>
</action>
为我们的控制器ProductAction,添加一个add()方法:
public String add(){
System.out.println("product.name:"+product.getName());
return "show";
}
总的来说,因为提交的时候,它的提交名为product.name 所以很智能,我们的struts框架,已经调用了setProduct()方法完成了注入。
编码问题
下面以utf-8编码为例
首先是jsp文件:<%@ page language="java" contentType="text/html; charset=UTF-8"
表单使用post方法即可。
其次配置struct的编码:
<struts>
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<struts>
日志输出
有时候,我们遇到问题输出的信息非常有限。可以使用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>
获取request 和response
只需要在ProductAction 的相应处理的函数中添加下面两句即可:
其中request和response都被封装过了。
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
获取session
Map m = ActionContext.getContext().getSession();
往session中添加属性:
Map m = ActionContext.getContext().getSession();
m.put("name", product.getName());
文件上传
首先书写一个简单的前端页面:
其中,enctype="multipart/form-data
指定了上传类型为二进制文件。
<%@ 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>
下面是一个简单的上传控制器:
包含文件、文件名、文件类型三个必备属性和相关的处理方法。
框架会根据doc,匹配到三个名字,直接进行set方法注入。
package com.how2java.action;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
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中配置相应的url配置:
<action name="upload" class="com.how2java.action.UploadAction" method="upload">
<result name="success">success.jsp</result>
</action>
配置上传文件的最大值
struts中默认上传文件的最大值为2m,可以通过下面配置解决:
<constant name="struts.multipart.maxSize" value="10240000"/>
s标签
form标签
如下面表单的代码:
<%@ 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>
然后我们查看到,其中已经被Struts转化为table 表格了。
<form id="addProduct" name="addProduct" action="addProduct.action" method="post">
<table class="wwFormTable">
<tr>
<td class="tdLabel"><label for="addProduct_product_name" class="label">product name:</label></td>
<td
><input type="text" name="product.name" value="" id="addProduct_product_name"/></td>
</tr>
<tr>
<td colspan="2"><div align="right"><input type="submit" id="addProduct_0" value="Submit"/>
</div></td>
</tr>
</table></form>
iterator 标签
首先为我们的ProductAction控制器中添加一个Product的list列表和相应的get、set方法,然后编写下面的前端页面:
相当于for循环,把返回得到的List列表展示出来。
<%@ 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>
check标签
在ProductAction中添加一个int类型的选择List列表,然后在前端中会选择int列表中的id。
下面是一个简单的checklist
展示:
- value:哪些被选中
- name:提交到服务端用的名称
- list:用于遍历的集合
- listValue:显示的checkbox的名称
- listKey:checkbox的value
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%@page isELIgnored="false"%>
<s:checkboxlist value="selectedProducts" name="product.id"
list="products" listValue="name" listKey="id" />
radio 标签
上面实现了一个简单的多选框,下面是一个单选框的实现。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%@page isELIgnored="false"%>
<s:radio name="product.id" value="2" list="products" listValue="name"
listKey="id" />
select 标签
除了radio的简单实现,下面展示一下select的简单实现。
有两个新属性注意一下:
- multiple:true表示可以选中多行
- size="3"表示默认显示3行
<s:select label="products"
name="product.id"
list="products"
listKey="id"
listValue="name"
multiple="true"
size="3"
value="selectedProducts"
/>
多重iterator 遍历
如之前的Category 包含了很多Product,其实应该不难。
<table border="1" cellspacing="0">
<tr>
<td>id</td>
<td>name</td>
<td>products</td>
</tr>
<s:iterator value="categories" var="c">
<tr>
<td>${c.id}</td>
<td>${c.name}</td>
<td>
<s:iterator value="#c.products" var="p">
${p.name}<br/>
</s:iterator>
</td>
</tr>
</s:iterator>
</table>
<s:debug/>
调试
调试页面
需要导入相应的jar包。
登陆http://127.0.0.1:8080/struts/config-browser/actionNames
之类,即可看到我们配置了哪些action。
前端调试
添加<s:debug/>
在末尾,即可看到很多调试信息。
其他
通配符
所有以Prodcut结尾的URL的action都会被匹配,匹配的方法使用{1}
为第一个*
的内容。即如addProduct使用add的方法。
<action name="*Product" class="com.how2java.action.ProductAction" method="{1}">
<result name="show">show.jsp</result>
<result name="list">list.jsp</result>
</action>
拦截器
通过创建一个拦截器,给它拦截下来,然后添加一个日期属性。
package com.how2java.interceptor;
import java.util.Date;
import com.how2java.action.ProductAction;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class DateInterceptor extends AbstractInterceptor {
public String intercept(ActionInvocation invocation) throws Exception {
ProductAction action = (ProductAction)invocation.getAction();
action.setDate(new Date());
return invocation.invoke();
}
}
然后按照下面的配置,配置我们的拦截器给ProductAction即可:
首先是创建一个拦截器。
由于添加了新的拦截器, 默认拦截器失效了,所以给它补充回去。
<?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">
<interceptors>
<interceptor name="dateInterceptor" class="com.how2java.interceptor.DateInterceptor" />
</interceptors>
<action name="*Product*" class="com.how2java.action.ProductAction"
method="{1}">
<interceptor-ref name="dateInterceptor" />
<interceptor-ref name="defaultStack" />
<result name="show">show.jsp</result>
<result name="list">list.jsp</result>
</action>
</package>
</struts>
客户端跳转(重定向)
在控制器中添加:
public String addPage(){
return "addPage";
}
然后在配置文件配置一下即可:
<action name="addPageProduct" class="com.how2java.action.ProductAction" method="addPage">
<result name="addPage" type="redirect">addProduct.jsp</result>
</action>
当我们输入URL:addPageProduct,抛给控制器的addpage函数,addpage返回结果,重定向给addProduct.jsp。
重定向传参
添加一个name属性:
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
重定向的url中传入特定的参数:
<result name="addPage" type="redirect">addProduct.jsp?name=${name}</result>
表单验证
添加一个验证的函数:
public void validate(){
if ( product.getName().length() == 0 ){
addFieldError( "product.name", "name can't be empty" );
}
}
然后添加一个错误返回的网页:
<result name="input">addProduct.jsp</result>
如果,验证失败,那么会直接跳转到input,其中的过程,struts自动生成。
通过xml来实现表单验证
下面是一个表单验证的配置文件:
使用的文件命名方法为:{actionname}-validation.xml
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
<validator type="requiredstring">
<param name="fieldname">product.name</param>
<message>name is required.</message>
</validator>
</validators>
action多实例
在我们每一次访问页面的过程中,struts默认地都会生成不同的对象实例来执行action的功能。
注解
首先将配置文件中的包的内容给注释掉。
示例
@Namespace("/")
:表示URL的根路径。
@ParentPackage("struts-default")
:表示设置一个默认的拦截器。
@Results({@Result(name="show", location="/show.jsp"), @Result(name="home", location="/index.jsp")})
:表示返回值对应的资源路径。
@Action("showProduct")
:action行为showProduct,对应的函数。
package com.how2java.action;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import com.how2java.bean.Product;
@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;
}
}
参考
主要资料和代码来源:
最后
以上就是妩媚指甲油为你收集整理的Java Struts2 学习Struts2参考的全部内容,希望文章能够帮你解决Java Struts2 学习Struts2参考所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复