一、Action動作類(一般用**Action結尾)
struts2 的Action可以是POJO(Plain Old Java Object)
爲了讓用戶開發的Action更加規範struts2提供了一個Action接口
通過method屬性指定Action執行方法
沒有指定method屬性,默認執行execute方法
<action name="addCustomer" class="xgp.struts.actions.CustomerAction" />
- 1
- 1
通過method屬性,指定調用Action相應方法處理請求
<action name="addCustomer" class="xgp.struts.actions.CustomerAction" method="add">
- 1
- 1
因爲指定了method=”add”,所以HelloAction的ass方法會被調用.
1、編寫動作類的三種方式
a、第一種方法是,動作類不實現、也不繼承任何的接口和類。即動作類是一個非常普通的JavaBean。
public class HelloAction {
public String sayHello(){
System.out.println("動作類執行了,訪問成功!");
return "success";
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
b、動作類實現com.opensymphony.xwork2.
Action接口。可以使用常量
Action接口:
public static final String SUCCESS = "success"; //成功時轉向的視圖
public static final String NONE = "none";//執行成功後,不轉向的任何視圖。比如下載任務
public static final String ERROR = "error";//轉向錯誤視圖
public static final String INPUT = "input";//轉向輸入視圖。(回顯:驗證與轉換失敗,轉向原有頁面)
public static final String LOGIN = "login";//登錄視圖(用戶沒有登錄)
public String execute() throws Exception;// public 修飾符,String 返回值,無參數
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
c、繼承com.opensymphony.xwork2.
ActionSupport(開發中建議)
Struts2爲Action接口提供了一個實現類 ActionSupport,定義了 表單域校驗、錯誤信息設置和獲得國際化信息相關一些方法
public class ActionSupport implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable {
protected static Logger LOG = LoggerFactory.getLogger(ActionSupport.class);
private final ValidationAwareSupport validationAware = new ValidationAwareSupport();
private transient TextProvider textProvider;
private Container container;
public void setActionErrors(Collection<String> errorMessages) {
validationAware.setActionErrors(errorMessages);
}
public Collection<String> getActionErrors() {
return validationAware.getActionErrors();
}
public void setActionMessages(Collection<String> messages) {
validationAware.setActionMessages(messages);
}
public Collection<String> getActionMessages() {
return validationAware.getActionMessages();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
2、動作類中的動作方法
要求:
a、必須是public的
b、必須返回String類型的
c、必須沒有參數
3.動作類的生命週期
動作類每次訪問都會重新被實例化,是線程安全的。
public class HelloAction {
public HelloAction() {
System.out.println("執行構造函數HelloAction,實例化對象。");
}
public String sayHello(){
System.out.println("動作方法sayHello執行了,訪問成功!");
return "success";
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
測試結果:
二、動作類中動作方法的調用
動作方法:動作類中的定義的處理業務有關的方法
實例:模擬一個curd的動作類
工程目錄如下:
1、新建一個 curd.jsp
<body>
<a href="${pageContext.request.contextPath}/customer/addCustomer.action">增加用戶</a>
<a href="${pageContext.request.contextPath}/customer/editCustomer.action">修改用戶</a>
<a href="${pageContext.request.contextPath}/customer/findCustomer.action">查詢用戶</a>
<a href="${pageContext.request.contextPath}/customer/delCustomer.action">刪除用戶</a>
</body>
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
2、在struts.xml中配置
如下圖所示:
<struts>
<constant name="struts.devMode" value="true" />
<package name="p1" extends="struts-default" namespace="/customer">
<action name="addCustomer" class="xgp.struts.actions.CustomerAction" method="add">
<result name="success" type="dispatcher">/addCustomer.jsp</result>
<result name="error" type="dispatcher">/error.jsp</result>
</action>
<action name="editCustomer" class="xgp.struts.actions.CustomerAction" method="edit">
<result name="success" type="dispatcher">/editCustomer.jsp</result>
</action>
<action name="findCustomer" class="xgp.struts.actions.CustomerAction" method="find">
<result name="success" type="dispatcher">/findCustomer.jsp</result>
</action>
<action name="delCustomer" class="xgp.struts.actions.CustomerAction" method="del">
<result name="success" type="dispatcher">/delCustomer.jsp</result>
</action>
</package>
</struts>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
3、建立動作處理類CustomerAction
package xgp.struts.actions;
import xgp.struts.service.BusinessService;
import xgp.struts.serviceImpl.BusinessServiceImpl;
import com.opensymphony.xwork2.ActionSupport;
public class CustomerAction extends ActionSupport{
private BusinessService bs = new BusinessServiceImpl();
public String add(){
//調用Service添加方法
try {
bs.add();
return SUCCESS;
} catch (Exception e) {
return ERROR;
}
}
public String edit(){
bs.edit();
return SUCCESS;
}
public String find(){
bs.find();
return SUCCESS;
}
public String del(){
bs.del();
return SUCCESS;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
4、建立相應的業務接口BusinessService和實現類BusinessServiceImpl
BusinessService
package xgp.struts.service;
public interface BusinessService {
public void add();
public void edit();
public void del();
public Object find();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
BusinessServiceImpl
package xgp.struts.serviceImpl;
import xgp.struts.service.BusinessService;
public class BusinessServiceImpl implements BusinessService{
@Override
public void add() {
System.out.println("Serviece的add方法執行成功!");
}
@Override
public void edit() {
System.out.println("Serviece的edit方法執行成功!");
}
@Override
public void del() {
System.out.println("Serviece的del方法執行成功!");
}
@Override
public Object find() {
System.out.println("Serviece的find方法執行成功!");
return null;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
結果如下:
1、使用通配符配置Action
在配置<action...>
元素時,允許在指定name屬性時,使用模式字符串(用"*"
代表一個或多個任意字符)
在class、method屬性及<result>
子元素中通過 {N} 形式代表前面地N個*
匹配子串
例如上面的案例中struts.xml我們可以改寫如下:
<!-- 使用通配符:*
{2}:匹配第2個星花的內容
-->
<!-- http://localhost:8080/xgp.struts/customer/add_Customer.action
第一個*: add
第二個*:Customer
-->
<action name="*_*" class="xgp.struts.actions.{2}Action" method="{1}">
<result name="success" type="dispatcher">/{1}{2}.jsp</result>
</action>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
2、使用Action的動態方法調用(官方不建議使用)
動態方法調用:DMI
http://localhost:8080/xgp.struts/customer/add_Customer!add
希望執行CustomerAction的add動作方法(動態方法調用)
動態方法調用:Struts2框架默認是禁止的。可以通過配置一個常量打開它:
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
- 1
- 1
通過url動態指定調用Action哪個方法而無需配置<action>
的method屬性, 通過 !方法名 指定調用Action哪個方法
<a href="${pageContext.request.contextPath}/customer/customer!add.action">添加用戶</a><br/>
<a href="${pageContext.request.contextPath}/customer/customer!edit.action">修改用戶</a><br/>
<a href="${pageContext.request.contextPath}/customer/customer!del.action">刪除用戶</a><br/>
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
3、配置默認Action和 配置Action默認處理類
用戶可以爲每個package定義一個默認的Action,如果訪問路徑在package沒有匹配<action>
就會執行默認action
<default-action-ref name="defaultAction"></default-action-ref>
<action name="defaultAction">
<result name="success" type="dispatcher">/whatareuwant.jsp</result>
</action>
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
如果配置<action>
沒有指定class屬性,就會執行Action的默認處理類,在struts-default.xml中.
指定默認的動作處理類
<!-- 指定默認的動作:當用戶訪問的動作在本包中沒有找到時執行的動作 -->
<default-action-ref name="defaultAction"></default-action-ref>
<!-- 指定默認的動作處理類 -->
<default-class-ref class="xgp.struts.actions.DefaultAction"></default-class-ref>
<action name="customer" class="xgp.struts.actions.CustomerAction">
<result name="success" type="dispatcher">/success.jsp</result>
</action>
<action name="defaultAction">
<result name="success" type="dispatcher">/whatareuwant.jsp</result>
</action>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
三、在動作類中訪問ServletAPI
Struts2的Action沒有與任何Servlet API耦合,便於測試.這是他的優點之一.
1、三大實現方法
1、ActionContext
- getContext() 返回ActionContext實例對象
- get(key) 相當於 HttpServletRequest的getAttribute(String name)方法
- put(String,Object) 相當於HttpServletRequest的setAttribute方法
- getApplication() 返回一個Map對象,存取ServletContext屬性
- getSession() 返回一個Map對象,存取HttpSession屬性
- getParameters() 類似調用HttpServletRequest的getParameterMap()方法
- setApplication(Map) 將該Map實例裏key-value保存爲ServletContext的屬性名、屬性值
- setSession(Map) 將該Map實例裏key-value保持爲HttpSession的屬性名、屬性值
2、方式二:(簡單,推薦使用)使用ServletActionContext
static PageContext getPageContext()
static HttpServletRequest getRequest()
static HttpServletResponse getResponse()
static ServletContext getServletContext()
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
該方案可避免Action類實現XxxAware接口,但Action依然與Servlet API直接耦合
開發中優先使用ActionContext 這樣可以避免耦合
package com.itheima.actions;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.PageContext;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;
public class ServletAPIAction1 extends ActionSupport{
//打印當前應用名稱到控制檯上
//獲取ServletAPI有關類的實例
//方式一:
public String execute() throws Exception {
//實際上利用ThreadLocal這個類
//ServletActionContext:記住
HttpServletRequest request = ServletActionContext.getRequest();
System.out.println(request.getContextPath());
PageContext pc = ServletActionContext.getPageContext();
HttpServletResponse response = ServletActionContext.getResponse();
response.getWriter().write(request.getContextPath());//自己輸出
ServletContext sc = ServletActionContext.getServletContext();
System.out.println(sc.getRealPath("/"));
return NONE;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
3、方式三:(麻煩)實現接口,訪問Action時完成注入
ServletContextAware
void setServletContext(javax.servlet.ServletContext context)
ServletRequestAware
void setServletRequest(javax.servlet.http.HttpServletRequest request)
ServletResponseAware
void setServletResponse(javax.servlet.http.HttpServletResponse response)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
動作類實現特定的接口。就必須實現特定的方法,調用動作方法前,框架會把響應的對象給注入進來。
package com.itheima.actions;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import com.opensymphony.xwork2.ActionSupport;
//獲取ServletAPI有關類實例的方式二
public class ServletAPIAction2 extends ActionSupport implements ServletRequestAware,ServletResponseAware{
private HttpServletRequest request;
private HttpServletResponse response;
//該方法會在調用動作方法之前先執行:把當前的HttpServletRequest對象給你注入進來
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public void setServletResponse(HttpServletResponse response) {
this.response = response;
}
@Override
public String execute() throws Exception{
//要使用HttpServletRequest對象
//System.out.println(request.getContextPath());
response.getWriter().write(request.getContextPath());
return NONE;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
原理:是一個攔截器給你注入進來的。struts-default.xml
<interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
- 1
- 1
一看源碼便知。
配置struts.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<package name="p1" extends="struts-default">
<!-- 因爲包繼承了struts-default,默認使用struts-default.xml中定義的那個默認的攔截器棧:defaultStack
在執行動作方法之前:defaultStack中的組員都會攔截你的動作調用
包含:一個叫做servletConfig的攔截器。
-->
<!-- 演示在動作類中獲取Servlet有關的類的實例:HttpServletRequest HttpServletResponse HttpSession ServletContext等
Struts2已經將ServletAPI和動作類進行解耦,這是他的優點之一
-->
<action name="showContextPath1" class="com.itheima.actions.ServletAPIAction1">
<result name="success" type="dispatcher">/success.jsp</result>
</action>
<action name="showContextPath2" class="com.itheima.actions.ServletAPIAction2" method="execute">
<result name="success" type="dispatcher">/success.jsp</result>
</action>
</package>
</struts>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
2、局部和全局結果視圖
result元素:指定動作類的動作方法執行完後的結果視圖.
屬性:
- name:字符串,與動作方法返回的值一致。默認是success
- type:指定處理結果的結果類型的別名。(struts-default.xml有定義,共10個)。默認值是dispatcher
Action處理完用戶請求後,將返回一個普通字符串整個普通字符串就是一個邏輯視圖名,Struts2 根據邏輯視圖名,決定響應哪個結果。
Struts2處理結果使用<result>
元素配置
- 局部結果:將
<result>
作爲<action>
子元素配置 - 全局結果:將
<result>
作爲<global-results>
元素的子元素配置
配置<result>
元素通常需要指定兩個屬性
- name 該屬性指定配置邏輯視圖名
- type 該屬性指定結果類型
當多個action中都使用到了相同result,這時我們應該把result定義爲全局結果。struts1中提供了全局forward,struts2中也提供了相似功能:
<package ....>
<global-results>
<result name="message">/message.jsp</result>
</global-results>
</package>
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
注:局部的會覆蓋全局
Struts1中應用範圍內action的實例 action是單實例(執行時,現在緩存中查找實例,有用,沒有創建新的實例)Struts2中 應用範圍內action的實例,每個請求都會創建一個action實例Servlet屬於單實例多線程的應用,實例只在初始化時被加載多實例比單實例的優點,不會產生併發問題,但執行速度不如單實例。
如下:
<struts>
<constant name="struts.devMode" value="true" />
<package name="mydefault" extends="struts-default" abstract="ture">
<global-results>
<result name="success" type="dispatcher">/success.jsp</result>
</global-results>
</package>
<package name="p1" extends="mydefault">
<action name="action1" class="xgp.struts.actions.Demo1Action">
<!-- <result name="success" type="dispatcher">/success.jsp</result> -->
</action>
<action name="action2" class="xgp.struts.actions.Demo2Action">
<!-- <result name="success" type="dispatcher">/success.jsp</result> -->
</action>
</package>
<package name="p2" extends="mydefault">
<action name="action3" class="xgp.struts.actions.Demo3Action">
<!-- <result name="success" type="dispatcher">/success.jsp</result> -->
</action>
</package>
</struts>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
3、Struts2提供的結果視圖 (共10個)
<result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
<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"/>
<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" />
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
1. chain:從一個動作轉發到另外一個動作
同一個包內的動作轉發
<package name="p3" namespace="/result" extends="struts-default">
<!-- action1的結果是另外一個Action的請求:一個動作轉發到了另外一個動作
演示:同包內的動作轉發-->
<action name="action1">
<result name="success" type="chain">action2</result>
</action>
<action name="action2">
<result>/success.jsp</result>
</action>
</package>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
不同包之間的動作轉發
<package name="p3" namespace="/result" extends="struts-default">
<action name="action1">
<result name="success" type="chain">
<param name="namespace">/user</param> 給chain的實際處理類注入參數
<param name="actionName">action2</param>
</result>
</action>
</package>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
2. dispatcher:從一個動作轉發到另外一個JSP
dispatcher 結果類型是最常用的結果類型, 也是 struts 框架默認的結果類型
該結果類型有一個 location 參數, 它是一個默認參數
dispatcher 結果類型將把控制權轉發給應用程序裏的某個資源
3. redirect:從一個動作重定向到一個JSP
最明顯的是地址欄發生變化。
<action name="action2">
<result type="redirect">/success.jsp</result>
</action>
- 1
- 2
- 3
- 1
- 2
- 3
4. redirectAction:從一個動作重定向到另外一個動作
action1先將動作重定向到action2,然後action2在轉發到success.jsp,地址欄應該顯示的是action2.
<action name="action1">
<result name="success" type="redirectAction">action2</result>
</action>
<action name="action2">
<result>/success.jsp</result>
</action>
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
5. plainText:以純文本的形式顯示JSP
<package name="p4" namespace="/user" extends="struts-default">
<action name="action2">
<result type="plainText">/success.jsp</result>
</action>
</package>
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
6. stream:文件下載
<package name="p5" extends="struts-default">
<action name="download" class="xgp.struts.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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
DownLoadAction類
package com.itheima.actions;
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;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
結果顯示
4、自定義結果視圖
目標:用一個叫做image的視圖,輸入隨機驗證碼圖片 CAPTCHA,我們首先可以看dispatcher的聲明;
public class org.apache.struts2.dispatcher.ServletDispatcherResult extends org.apache.struts2.dispatcher.StrutsResultSupport
public abstract class org.apache.struts2.dispatcher.StrutsResultSupport implements com.opensymphony.xwork2.Result
可以看到dispatch的實現類是繼承StrutsResultSupport,而StrutsResultSupport又實現了Resul接口。多以我麼可以
1、編寫一個類實現com.opensymphony.xwork2.Result,或者繼承org.apache.struts2.dispatcher.StrutsResultSupport,這裏定義一個類,實現com.opensymphony.xwork2.Result接口
package xgp.struts.actions;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.Result;
public class CaptchaResult implements Result {
private int width;
private int height;
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public void execute(ActionInvocation arg0) throws Exception {
/*int width=120,height=25;*/
//1.在內存生成一個圖片
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//2.得到畫筆
Graphics g = img.getGraphics();
//3.畫一個矩形框
g.setColor(Color.BLUE);
g.drawRect(0, 0, width, height);
//4.填充背景
g.setColor(Color.YELLOW);
g.fillRect(1, 1, width-1, height-1);
//5.畫一些干擾線條
g.setColor(Color.GRAY);
Random random = new Random();
for(int i=1;i<=20;i++)
g.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height));
//6.畫字符串隨機的
g.setColor(Color.RED);
//設置字體
g.setFont(new Font("宋體",Font.BOLD|Font.ITALIC,20));
for(int i=1;i<=4;i++)
g.drawString(random.nextInt(10)+"", i*20,20);
//7.輸出
HttpServletResponse response = ServletActionContext.getResponse();
response.setContentType("image/jpeg");
ImageIO.write(img, "jpg", response.getOutputStream());
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
2、自定義的結果視圖,(必須先聲明後才能使用)
<package name="p6" extends="struts-default">
<result-types>
<result-type name="captcha" class="xgp.struts.actions.CaptchaResult"></result-type>
</result-types>
<action name="genCaptcha">
<result name="success" type="captcha">
<param name="width">300</param>
<param name="height">400</param>
</result>
</action>
</package>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
3、就可以使用了,編寫視圖頁面login.jsp
<body>
<form action="">
用戶名:<input type="text" name="username"/><br />
驗證碼:<input type="text" name="code" /><img alt="驗證碼" src="${pageContext.request.contextPath}/genCaptcha.action">
</form>
</body>
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
運行結果
如果想在多個包中用,可以將package聲明爲abstract ,然後別的包繼承自這個包即可。
階段性小結