01_Struts2概述作者: 风离紫竹[email protected] |
02_搭建Struts2运行环境作者: 风离紫竹[email protected] |
<
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
>
|
03_Eclipse界面设置作者: 风离紫竹[email protected] |
04_HelloWorld详解作者: 风离紫竹[email protected] |
简化配置方式 |
<
action
name
=
"saveUI"
>
<
result
>
/saveUI.jsp
result
>
action
>
|
完整配置方式 |
<
action
name
=
"saveUI"
class
=
"com.opensymphony.xwork2.ActionSupport"
method
=
"execute"
>
<
result
name
=
"success"
>
/saveUI.jsp
result
>
action
>
|
05_请求和响应来源网址: file:///D:/金山快盘/Struts2/LibrarySupport/struts-2.3.15.3/docs/WW/docs/redirect-action-result.html作者: 风离紫竹[email protected] |
public
String saveBook() {
System.
out
.println(
"saveBook..."
);
return
"saveSuccess"
;
}
|
<
package
name
=
"default"
namespace
=
"/atguigu"
extends
=
"struts-default"
>
|
http://localhost:8989/Struts2_02_HelloWorld/atguigu/saveBook.action |
http://localhost:8989/Struts2_02_HelloWorld/index.jsp | jsp |
http://localhost:8989/Struts2_02_HelloWorld/saveUI.action | action |
http://localhost:8989/Struts2_02_HelloWorld/index.html | html |
struts.action.extension=
action,,
|
<
constant
name
=
"struts.action.extension"
value
=
"action,,atguigu"
/>
|
<
constant
name
=
"struts.enable.DynamicMethodInvocation"
value
=
"true"
/>
|
http://localhost:8989/DynamicMethodInv/saveBook!query.action |
<
action
name
=
"bookAction_*Book"
class
=
"com.atguigu.wildcard.action.BookAction"
method
=
"{1}Book"
>
<
result
name
=
"{1}-success"
>
/result/{1}Success.jsp
result
>
action
>
|
<
result-types
>
<
result-type
name
=
"chain"
class
=
"com.opensymphony.xwork2.ActionChainResult"
/>
<
result-type
name
=
"dispatcher"
class
=
"org.apache.struts2.dispatcher.ServletDispatcherResult"
default
=
"true"
/>
<
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"
/>
<
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"
/>
result-types
>
|
文档中完整的配置方式 |
dashboard
/secure
|
如果namespace保持默认值/,则可以使用下面的简略方式,直接在result的开始和结束标签之间写目标Action的名字 |
|
说明 | 类型 |
封装请求域数据的Map | Map |
封装Session域数据的Map | Map |
封装Application域数据的Map | Map |
封装请求参数数据的Map | Map |
第一步 | ActionContext.getContext()返回ActionContext对象 |
第二步 | actionContext.getXxx();方法 |
SessionMap
sm
= ( SessionMap)
session
;
sm
.invalidate();
|
主动获取
|
被动注入√
|
代码不够优雅 | 代码很优雅 |
Web资源对象的类型不是很贴切 | Web资源对象类型很贴切 |
学习成本较高 | 使用便捷 |
06_2015年12月5日小结作者: 风离紫竹[email protected] |
07_值栈作者: 风离紫竹[email protected] |
public
String getMessage() {
return
"The atguig is very good!"
;
}
|
${requestScope.message }
|
request.getAttribute("message"); |
ActionContext
ctx
= ActionContext. getContext();
ValueStack
stack
=
ctx
.getValueStack();
|
读取对象属性的传统方式 | department.getEmpList().get(5).getAddress().getStreet(); |
OGNL方式 | department.empList[5].address.street |
valueStack
.findString(
"#session['user-name']"
);
|
09_Struts2通用标签作者: 风离紫竹[email protected] |
<%@
taglib
uri
=
"/struts-tags"
prefix
=
"s"
%>
|
<
s:url
action
=
"bookAction"
>
<
s:param
name
=
"paramWords"
value
=
"[0].words"
/>
s:url
>
|
<
s:url
action
=
"bookAction"
>
<
s:param
name
=
"paramWords"
value
=
"'goodMorning'"
/>
s:url
>
|
<
s:a
value
=
"/targetUrl?paramWords=%{[0].words}"
>
To Some Place
s:a
>
|
<
s:iterator
value
=
"#request.map"
>
<
tr
>
<%-- 当前栈顶对象是Entry类型的 --%>
<
td
><
s:property
/>
td
>
<%-- 调用栈顶对象的getKey()方法 --%>
<
td
><
s:property
value
=
"[0].key"
/>
td
>
<%-- 调用栈顶对象的getValue()方法 --%>
<
td
><
s:property
value
=
"[0].value"
/>
td
>
tr
>
s:iterator
>
|
08_2015年12月7日小结作者: 风离紫竹[email protected] |
10_Struts2表单标签来源网址: http://localhost:8989/FormTag/SingleBoolean.jsp作者: 风离紫竹[email protected] |
hidden" name="__checkbox_married" value="true" />
|
11_2015年12月8日小结作者: 风离紫竹[email protected] |
12_404错误产生的原因作者: 风离紫竹[email protected] |
13_Struts2运行流程作者: 风离紫竹[email protected] |
14_模型驱动作者: 风离紫竹[email protected] |
this
.
book
.setBookId(
book
.getBookId());
this
.
book
.setBookName(
book
.getBookName());
this
.
book
.setAuthor(
book
.getAuthor());
this
.
book
.setPrice(
book
.getPrice());
|
目标方法 | saveBook() |
前缀方法 |
prepareSaveBook(){
this.book = new Book();
}
|
<
default-interceptor-ref
name
=
"paramsPrepareParamsStack"
/>
|
<
interceptors
>
<
interceptor-stack
name
=
"atguiguStack"
>
<
interceptor-ref
name
=
"paramsPrepareParamsStack"
>
<
param
name
=
"prepare.alwaysInvokePrepare"
>
false
param
>
interceptor-ref
>
interceptor-stack
>
interceptors
>
<
default-interceptor-ref
name
=
"atguiguStack"
/>
|
15_2015年12月11日复习作者: 风离紫竹[email protected] |
16_声明式异常管理作者: 风离紫竹[email protected] |
try{
//1.开启事务
conn.setAutoCommit(false);
//2.执行请求——包括后续的全部操作:Servlet、Service、Dao
chain.doFilter(req,resp,chain);
//3.提交事务
conn.commit();
}catch(Exception e){
//4.回滚事务
conn.rollBack();
//5.前往用于显示异常信息的页面
request.setAttribute("message","异常信息....");
//转发...
}finally{
//6.关闭数据库连接
JDBCUtils.close(conn);
}
|
<
action
name
=
"daoDanAction"
class
=
"com.atguigu.exception.action.ExceptionAction"
method
=
"daoDanAction"
>
<
exception-mapping
result
=
"exception"
exception
=
"java.lang.ArithmeticException"
/>
<
result
>
/good.jsp
result
>
<
result
name
=
"exception"
>
/makeException.jsp
result
>
action
>
|
<
global-results
>
<
result
name
=
"global_error"
>
/globalMsg.jsp
result
>
global-results
>
<
global-exception-mappings
>
<
exception-mapping
result
=
"global_error"
exception
=
"java.lang.ArithmeticException"
/>
global-exception-mappings
>
|
17_主题作者: 风离紫竹[email protected] |
<
constant
name
=
"struts.ui.theme"
value
=
"simple"
/>
|
<
s:form
action
=
"abc"
theme
=
"xhtml"
>
|
18_类型转换作者: 风离紫竹[email protected] |
目标Action类类名 | Conversion01 |
属性文件文件名 | Conversion01.properties |
格式 |
invalid.fieldvalue.目标字段名=错误消息内容
|
例子 |
invalid.fieldvalue.age=
\u5E74\u9F84\u5FC5\u987B\u662F\u6574\u6570
|
<
s:property
value
=
"[0].fieldErrors.age[0]"
/>
|
<
s:fielderror
name
=
"age"
/>
|
<#if parameters.id?if_exists != "">
id="${parameters.id?
html
}"<#
rt
/>
#if>
<#if parameters.cssClass??>
class="${parameters.cssClass?
html
}"<#
rt
/>
<#else>
class="errorMessage"<#
rt
/>
#if>
<#if parameters.cssStyle??>
style="${parameters.cssStyle?
html
}"<#
rt
/>
#if>
>
|
目标字段名=转换器类全类名 |
address=
com.atguigu.convert.converter.AddressConverter
|
要转换的类型全类名=转换器类全类名 |
com.atguigu.convert.entity.Address=
com.atguigu.convert.converter.AddressConverter
|
<
s:textfield
name
=
"address.country"
label
=
"COUNTRY"
/>
|
19_2015年12月11日小结作者: 风离紫竹[email protected] |
20_国际化作者: 风离紫竹[email protected] |
默认 |
atguiguI18N.properties
|
英语美国 |
atguiguI18N2_en_US.properties
|
中文中国 |
atguiguI18N2_zh_CN.properties
|
< constant name = "struts.custom.i18n.resources" value = "atguiguI18N"/> |
<
s:textfield
name
=
"usreName"
label
=
"%{[0].getText('userName')}"
/>
|
<
s:textfield
name
=
"usreName"
key
=
"userName"
/>
|
<
s:text
name
=
"userName"
/>
|
没有填充的状态:
<
s:text
name
=
"today"
/><
br
/><
br
/>
填充一个普通的字符串:
<
s:text
name
=
"today"
>
<
s:param
value
=
"'mmm'"
/>
s:text
>
<
br
/><
br
/>
<
s:bean
name
=
"java.util.Date"
var
=
"myDate"
/>
填充日期数据:
<
s:text
name
=
"today"
>
<
s:param
value
=
"#attr.myDate"
/>
s:text
>
|
21_声明式输入验证来源网址: file:///D:/%E9%87%91%E5%B1%B1%E5%BF%AB%E7%9B%98/Struts2/LibrarySupport/struts-2.3.15.3/docs/WW/docs/basic-validation.html作者: 风离紫竹[email protected] |
<
field
name
=
"age"
>
<
field-validator
type
=
"int"
>
<
param
name
=
"min"
>
20
param
>
<
param
name
=
"max"
>
50
param
>
<
message
>
您输入的年龄不在${ min}到${max}之间
message
>
field-validator
>
field
>
|
<
validator
name
=
"int"
class
=
"com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator"
/>
|
<
s:actionerror
/>
|
<
field
name
=
"email"
>
<
field-validator
type
=
"stringlength"
short-circuit
=
"true"
>
<
param
name
=
"minLength"
>
5
param
>
<
param
name
=
"maxLength"
>
10
param
>
<
param
name
=
"trim"
>
true
param
>
<
message
>
Email长度要求在${minLength}和${maxLength}之间
message
>
field-validator
>
<
field-validator
type
=
"email"
>
<
message
>
Email格式不正确
message
>
field-validator
>
field
>
|
//目标:如果发生了类型转换错误,则返回"input",执行name=input的result,不执行后续的其他拦截器
//当然也不执行目标Action类的目标方法了
//1.获取目标Action对象
Object action = invocation.getAction();
//2.检测目标Action是否实现了ValidationAware接口
if(action instanceof ValidationAware) {
//3.如果实现了ValidationAware接口,则转换类型
ValidationAware va = (ValidationAware) action;
//4.检测是否包含错误信息
if(va.hasErrors()) {
//5.如果包含了错误信息,则return "input";
return "input";
}
}
|
return
invocation
.invoke()
|
return "指定result的name值"; |
Age
must
between
${ min}
and
${max}
|
Grade
must
between
${ min}
and
${max}
|
atguigu.int.msg=
Integer
value
must
between
${min}
and
${max}
|
atguigu.int.msg=
${fieldName}
must
between
${min}
and
${max}
|
atguigu.int.msg=
${getText(fieldName)}
must
between
${min }
and
${max}
age=
AGE~
grade=
GRADE~
|
/**
* The validation implementation must guarantee that setValidatorContext will
* be called with a non
-
null ValidatorContext before validate is called.
*
*
@param
object the object to be validated.
是执行验证的目标Action类的对象
*
@throws
ValidationException is thrown if there is validation error(s).
*/
void
validate (Object
object
)
throws
ValidationException;
|
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
DOCTYPE
validators
PUBLIC
"-//Apache Struts//XWork Validator Definition 1.0//EN"
"http://struts.apache.org/dtds/xwork-validator-definition-1.0.dtd"
>
<
validators
>
<
validator
name
=
"idCard"
class
=
"com.atguigu.validation.validator.IdCardValidator"
/>
validators
>
|
22_文件上传作者: 风离紫竹[email protected] |
|
private
File
logo
;
private
String
logoContentType
;
private
String
logoFileName
;
|
<
interceptors
>
<
interceptor-stack
name
=
"atguiguStack"
>
<
interceptor-ref
name
=
"paramsPrepareParamsStack"
>
<
param
name
=
"fileUpload.maximumSize"
>
204800
param
>
interceptor-ref
>
interceptor-stack
>
interceptors
>
<
default-interceptor-ref
name
=
"atguiguStack"
/>
|
<
param
name
=
"fileUpload.allowedTypes"
>
image/gif,image/png,image/jpg,image/jpeg,image/bmp
param
>
|
<
constant
name
=
"struts.multipart.maxSize"
value
=
"1048576"
/>
|
struts2-core-2.3.15.3.jar\org.apache.struts2\struts-messages.properties |
23_文件下载来源网址: file:///D:/%E9%87%91%E5%B1%B1%E5%BF%AB%E7%9B%98/Struts2/LibrarySupport/struts-2.3.15.3/docs/WW/docs/stream-result.html作者: 风离紫竹[email protected] |
attachment;filename=document.pdf |
fileName = "=?utf-8?b?"+new BASE64Encoder().encode(fileName.getBytes("utf-8"))+"?="; |
image/jpeg
imageStream
attachment;filename="document.pdf"
1024
|
24_防止表单重复提交作者: 风离紫竹[email protected] |
<
action
name
=
"TokenAction"
class
=
"com.atguigu.token.action.TokenAction"
>
<
interceptor-ref
name
=
"token"
/>
<
interceptor-ref
name
=
"defaultStack"
/>
<
result
>
/result.jsp
result
>
<
result
name
=
"invalid.token"
>
/token.jsp
result
>
action
>
|
25_自定义拦截器作者: 风离紫竹[email protected] |
<
interceptors
>
<
interceptor
name
=
"loginInterceptor"
class
=
"com.atguigu.myinter.inter.LoginInterceptor"
/>
interceptors
>
|
<
interceptors
>
<
interceptor
name
=
"loginInterceptor"
class
=
"com.atguigu.myinter.inter.LoginInterceptor"
/>
<
interceptor-stack
name
=
"atguiguStack"
>
<
interceptor-ref
name
=
"loginInterceptor"
/>
<
interceptor-ref
name
=
"defaultStack"
/>
interceptor-stack
>
interceptors
>
<
default-interceptor-ref
name
=
"atguiguStack"
/>
|
<
action
name
=
"TokenAction"
class
=
"com.atguigu.token.action.TokenAction"
>
<
interceptor-ref
name
=
"token"
/>
<
interceptor-ref
name
=
"defaultStack"
/>
<
result
>
/result.jsp
result
>
<
result
name
=
"invalid.token"
>
/token.jsp
result
>
action
>
|
26_Struts2总结作者: 风离紫竹[email protected] |
|