老司机夜插-理伦理片-理伦片免费-理伦片免费观看-理伦片免费看-理伦日韩-理论福利片-理论片第一页-理论片电影-理论片理论

金喜正规买球

Result機(jī)制——豐富您的視圖

轉(zhuǎn)帖|其它|編輯:郝浩|2009-02-09 10:59:33.000|閱讀 1237 次

概述:Result機(jī)制——豐富您的視圖

# 界面/圖表報(bào)表/文檔/IDE等千款熱門(mén)軟控件火熱銷(xiāo)售中 >>

  Struts2將Result列為一個(gè)獨(dú)立的層次,可以說(shuō)是整個(gè)Struts2的Action層架構(gòu)設(shè)計(jì)中的另外一個(gè)精華所在。Result之所以成為一個(gè)層次,其實(shí)是為了解決MVC框架中,如何從Control層轉(zhuǎn)向View層這樣一個(gè)問(wèn)題而存在的。所以,接下來(lái)我們?cè)敿?xì)討論一下Result的方方面面。

  Result的職責(zé) 

  Result作為一個(gè)獨(dú)立的層次存在,必然有其存在的價(jià)值,它也必須完成它所在的層次的職責(zé)。Result是為了解決如何從Control層轉(zhuǎn)向View層這樣一個(gè)問(wèn)題而存在的,那么Result最大的職責(zé),就是架起Action到View的橋梁。具體來(lái)說(shuō),我把這些職責(zé)大概分成以下幾個(gè)方面:

  封裝跳轉(zhuǎn)邏輯

  Result的首要職責(zé),是封裝Action層到View層的跳轉(zhuǎn)邏輯。之前我們已經(jīng)反復(fù)提到,Struts2的Action是一個(gè)與Web容器無(wú)關(guān)的POJO。所以,在Action執(zhí)行完畢之后,框架需要把代碼的執(zhí)行權(quán)重新交還給Web容器,并轉(zhuǎn)向到相應(yīng)的頁(yè)面或者其他類(lèi)型的View層。而這個(gè)跳轉(zhuǎn)邏輯,就由Result來(lái)完成。這樣,好處也是顯而易見(jiàn)的,對(duì)Action屏蔽任何Web容器的相關(guān)信息,使得每個(gè)層次更加清晰。

  View層的顯示類(lèi)型非常多,有最常見(jiàn)的JSP、當(dāng)下非常流行的Freemarker/Velocity模板、Redirect到一個(gè)新的地址、文本流、圖片流、甚至是JSON對(duì)象等等。所以Result層的獨(dú)立存在,就能夠?qū)@些顯示類(lèi)型進(jìn)行區(qū)分,并封裝合理的跳轉(zhuǎn)邏輯。

  以JSP轉(zhuǎn)向?yàn)槔赟truts2自帶的ServletDispatcherResult中就存在著核心的JSP跳轉(zhuǎn)邏輯:

Java代碼
HttpServletRequest request = ServletActionContext.getRequest();  
RequestDispatcher dispatcher = request.getRequestDispatcher(finalLocation);  
 
....  
 
dispatcher.forward(request, response); 

HttpServletRequest request = ServletActionContext.getRequest();
RequestDispatcher dispatcher = request.getRequestDispatcher(finalLocation);

....

dispatcher.forward(request, response);

  再以Redirect重定向?yàn)槔赟truts2自帶的ServletRedirectResult中,也同樣存在著重定向的核心代碼:

Java代碼
HttpServletResponse response = (HttpServletResponse) ctx.get(ServletActionContext.HTTP_RESPONSE);  
 
....  
 
response.sendRedirect(finalLocation); 

HttpServletResponse response = (HttpServletResponse) ctx.get(ServletActionContext.HTTP_RESPONSE);

....

response.sendRedirect(finalLocation);

  由此可見(jiàn),絕大多數(shù)的Result,都封裝了與Web容器相關(guān)的跳轉(zhuǎn)邏輯,由于這些邏輯往往需要和Servlet對(duì)象打交道,所以,遵循Struts2的基本原則,將它作為一個(gè)獨(dú)立的層次,從而將Action從Web容器中解放出來(lái)。

  準(zhǔn)備顯示數(shù)據(jù)

  之前提到,View層的展現(xiàn)方式很多,除了傳統(tǒng)的JSP以外,還有類(lèi)似Freemarker/Velocity這樣的模板。根據(jù)模板顯示的基本原理,需要將預(yù)先定義好的模板(Template)和需要展示的數(shù)據(jù)(Model)組織起來(lái),交給模板引擎,才能夠正確顯示。而這部分工作,就由Result層來(lái)完成。

  以Struts2自帶的FreemarkerResult為例,在Result中,就存在著為模板準(zhǔn)備數(shù)據(jù)的邏輯代碼:

Java代碼
protected TemplateModel createModel() throws TemplateModelException {  
    ServletContext servletContext = ServletActionContext.getServletContext();  
    HttpServletRequest request = ServletActionContext.getRequest();  
    HttpServletResponse response = ServletActionContext.getResponse();  
    ValueStack stack = ServletActionContext.getContext().getValueStack();  
 
    Object action = null;  
    if(invocation!= null ) action = invocation.getAction(); //Added for NullPointException  
    return freemarkerManager.buildTemplateModel(stack, action, servletContext, request, response, wrapper);  

protected TemplateModel createModel() throws TemplateModelException {
    ServletContext servletContext = ServletActionContext.getServletContext();
    HttpServletRequest request = ServletActionContext.getRequest();
    HttpServletResponse response = ServletActionContext.getResponse();
    ValueStack stack = ServletActionContext.getContext().getValueStack();

    Object action = null;
    if(invocation!= null ) action = invocation.getAction(); //Added for NullPointException
    return freemarkerManager.buildTemplateModel(stack, action, servletContext, request, response, wrapper);
}

  有興趣的讀者可以順著思路去看源碼,看看這些Result到底是如何獲取各種對(duì)象的值的。

  控制輸出行為

  有的時(shí)候,針對(duì)同一種類(lèi)型的View展示,我們可能會(huì)有不同的輸出行為。具體來(lái)說(shuō),可能有時(shí)候,我們需要對(duì)輸出流指定特定的BufferSize、Encoding等等。Result層,作為一個(gè)獨(dú)立的層次,可以提供極大的擴(kuò)展性,從而保證我們能夠定義自己期望的輸出類(lèi)型。

  以Struts2自帶的HttpHeaderResult為例:

Java代碼
public void execute(ActionInvocation invocation) throws Exception {  
    HttpServletResponse response = ServletActionContext.getResponse();  
 
    if (status != -1) {  
        response.setStatus(status);  
    }  
 
    if (headers != null) {  
        ValueStack stack = ActionContext.getContext().getValueStack();  
 
        for (Iterator iterator = headers.entrySet().iterator();  
             iterator.hasNext();) {  
            Map.Entry entry = (Map.Entry) iterator.next();  
            String value = (String) entry.getValue();  
            String finalValue = parse ? TextParseUtil.translateVariables(value, stack) : value;  
            response.addHeader((String) entry.getKey(), finalValue);  
        }  
    }  

public void execute(ActionInvocation invocation) throws Exception {
    HttpServletResponse response = ServletActionContext.getResponse();

    if (status != -1) {
        response.setStatus(status);
    }

    if (headers != null) {
        ValueStack stack = ActionContext.getContext().getValueStack();

        for (Iterator iterator = headers.entrySet().iterator();
             iterator.hasNext();) {
            Map.Entry entry = (Map.Entry) iterator.next();
            String value = (String) entry.getValue();
            String finalValue = parse ? TextParseUtil.translateVariables(value, stack) : value;
            response.addHeader((String) entry.getKey(), finalValue);
        }
    }
}

  我們可以在這里添加我們自定義的內(nèi)容到HttpHeader中去,從而控制Http的輸出。 [SPAN]

  Result的定義 

  讓我們來(lái)看看Result的接口定義:

Java代碼
public interface Result extends Serializable {  
 
    /** 
     * Represents a generic interface for all action execution results, whether that be displaying a webpage, generating 
     * an email, sending a JMS message, etc. 
     */ 
    public void execute(ActionInvocation invocation) throws Exception;  

public interface Result extends Serializable {

    /**
     * Represents a generic interface for all action execution results, whether that be displaying a webpage, generating
     * an email, sending a JMS message, etc.
     */
    public void execute(ActionInvocation invocation) throws Exception;
}

  這個(gè)接口定義非常簡(jiǎn)單,通過(guò)傳入ActionInvocation,執(zhí)行一段邏輯。我們來(lái)看看Struts2針對(duì)這個(gè)接口實(shí)現(xiàn)的一個(gè)抽象類(lèi),它規(guī)定了許多默認(rèn)實(shí)現(xiàn):

Java代碼
public abstract class StrutsResultSupport implements Result, StrutsStatics {  
 
    private static final Log _log = LogFactory.getLog(StrutsResultSupport.class);  
 
    /** The default parameter */ 
    public static final String DEFAULT_PARAM = "location";  
 
    private boolean parse;  
    private boolean encode;  
    private String location;  
    private String lastFinalLocation;  
 
    public StrutsResultSupport() {  
        this(null, true, false);  
    }  
 
    public StrutsResultSupport(String location) {  
        this(location, true, false);  
    }  
 
    public StrutsResultSupport(String location, boolean parse, boolean encode) {  
        this.location = location;  
        this.parse = parse;  
        this.encode = encode;  
    }  
 
    // setter method 省略  
   
    /** 
     * Implementation of the <tt>execute</tt> method from the <tt>Result</tt> interface. This will call 
     * the abstract method {@link #doExecute(String, ActionInvocation)} after optionally evaluating the 
     * location as an OGNL evaluation. 
     * 
     * @param invocation the execution state of the action. 
     * @throws Exception if an error occurs while executing the result. 
     */ 
    public void execute(ActionInvocation invocation) throws Exception {  
        lastFinalLocation = conditionalParse(location, invocation);  
        doExecute(lastFinalLocation, invocation);  
    }  
 
    /** 
     * Parses the parameter for OGNL expressions against the valuestack 
     * 
     * @param param The parameter value 
     * @param invocation The action invocation instance 
     * @return The resulting string 
     */ 
    protected String conditionalParse(String param, ActionInvocation invocation) {  
        if (parse && param != null && invocation != null) {  
            return TextParseUtil.translateVariables(param, invocation.getStack(),  
                    new TextParseUtil.ParsedValueEvaluator() {  
                        public Object evaluate(Object parsedValue) {  
                            if (encode) {  
                                if (parsedValue != null) {  
                                    try {  
                                        // use UTF-8 as this is the recommended encoding by W3C to  
                                        // avoid incompatibilities.  
                                        return URLEncoder.encode(parsedValue.toString(), "UTF-8");  
                                    }  
                                    catch(UnsupportedEncodingException e) {  
                                        _log.warn("error while trying to encode ["+parsedValue+"]", e);  
                                    }  
                                }  
                            }  
                            return parsedValue;  
                        }  
            });  
        } else {  
            return param;  
        }  
    }  
 
    /** 
     * Executes the result given a final location (jsp page, action, etc) and the action invocation 
     * (the state in which the action was executed). Subclasses must implement this class to handle 
     * custom logic for result handling. 
     * 
     * @param finalLocation the location (jsp page, action, etc) to go to. 
     * @param invocation    the execution state of the action. 
     * @throws Exception if an error occurs while executing the result. 
     */ 
    protected abstract void doExecute(String finalLocation, ActionInvocation invocation) throws Exception;  

public abstract class StrutsResultSupport implements Result, StrutsStatics {

    private static final Log _log = LogFactory.getLog(StrutsResultSupport.class);

    /** The default parameter */
    public static final String DEFAULT_PARAM = "location";

    private boolean parse;
    private boolean encode;
    private String location;
    private String lastFinalLocation;

    public StrutsResultSupport() {
        this(null, true, false);
    }

    public StrutsResultSupport(String location) {
        this(location, true, false);
    }

    public StrutsResultSupport(String location, boolean parse, boolean encode) {
        this.location = location;
        this.parse = parse;
        this.encode = encode;
    }

    // setter method 省略
 
    /**
     * Implementation of the <tt>execute</tt> method from the <tt>Result</tt> interface. This will call
     * the abstract method {@link #doExecute(String, ActionInvocation)} after optionally evaluating the
     * location as an OGNL evaluation.
     *
     * @param invocation the execution state of the action.
     * @throws Exception if an error occurs while executing the result.
     */
    public void execute(ActionInvocation invocation) throws Exception {
        lastFinalLocation = conditionalParse(location, invocation);
        doExecute(lastFinalLocation, invocation);
    }

    /**
     * Parses the parameter for OGNL expressions against the valuestack
     *
     * @param param The parameter value
     * @param invocation The action invocation instance
     * @return The resulting string
     */
    protected String conditionalParse(String param, ActionInvocation invocation) {
        if (parse && param != null && invocation != null) {
            return TextParseUtil.translateVariables(param, invocation.getStack(),
                    new TextParseUtil.ParsedValueEvaluator() {
                        public Object evaluate(Object parsedValue) {
                            if (encode) {
                                if (parsedValue != null) {
                                    try {
                                        // use UTF-8 as this is the recommended encoding by W3C to
                                        // avoid incompatibilities.
                                        return URLEncoder.encode(parsedValue.toString(), "UTF-8");
                                    }
                                    catch(UnsupportedEncodingException e) {
                                        _log.warn("error while trying to encode ["+parsedValue+"]", e);
                                    }
                                }
                            }
                            return parsedValue;
                        }
            });
        } else {
            return param;
        }
    }

    /**
     * Executes the result given a final location (jsp page, action, etc) and the action invocation
     * (the state in which the action was executed). Subclasses must implement this class to handle
     * custom logic for result handling.
     *
     * @param finalLocation the location (jsp page, action, etc) to go to.
     * @param invocation    the execution state of the action.
     * @throws Exception if an error occurs while executing the result.
     */
    protected abstract void doExecute(String finalLocation, ActionInvocation invocation) throws Exception;
}

  很顯然,這個(gè)默認(rèn)實(shí)現(xiàn)是為那些類(lèi)似JSP,F(xiàn)reemarker或者Redirect這樣的頁(yè)面跳轉(zhuǎn)的Result而準(zhǔn)備的一個(gè)基類(lèi),它規(guī)定了Result將要跳轉(zhuǎn)到的具體頁(yè)面的位置、是否需要解析參數(shù),等等。 [SPAN]

  如果我們?cè)噲D編寫(xiě)自定義的Result,我們可以實(shí)現(xiàn)Result接口,并在struts.xml中進(jìn)行聲明:

Java代碼
public class CustomerResult implements Result {  
 
    public void execute(ActionInvocation invocation) throws Exception {  
    // write your code here  
}  

public class CustomerResult implements Result {

    public void execute(ActionInvocation invocation) throws Exception {
    // write your code here
}
}

Xml代碼
<result-type name="customerResult" class="com.javaeye.struts2.CustomerResult"/> 

<result-type name="customerResult" class="com.javaeye.struts2.CustomerResult"/>


  常用的Result 

  接下來(lái),大致介紹一下Struts2內(nèi)部已經(jīng)實(shí)現(xiàn)的Result,并看看他們是如何工作的。

  dispatcher

Xml代碼
<result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/> 

<result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default=&quot;true"/>

  dispatcher主要用于返回JSP,HTML等以頁(yè)面為基礎(chǔ)View視圖,這個(gè)也是Struts2默認(rèn)的Result類(lèi)型。在使用dispatcher時(shí),唯一需要指定的,是JSP或者HTML頁(yè)面的位置,這個(gè)位置將被用于定位返回的頁(yè)面:

Xml代碼
<result name="success"&gt;/index.jsp</result> 

<result name="success">/index.jsp</result>

  而Struts2本身也沒(méi)有對(duì)dispatcher做出什么特殊的處理,只是簡(jiǎn)單的使用Servlet API進(jìn)行forward。

  freemarker / velocity

Xml代碼
<result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/> 
<result-type name="velocity&quot; class="org.apache.struts2.dispatcher.VelocityResult"/> 

<result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
<result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>

  隨著模板技術(shù)的越來(lái)越流行,使用Freemarker或者Velocity模板進(jìn)行View層展示的開(kāi)發(fā)者越來(lái)越多。Struts2同樣為模板作為Result做出了支持。由于模板的顯示需要模板(Template)與數(shù)據(jù)(Model)的緊密配合,所以在Struts2中,這兩個(gè)Result的主要工作是為模板準(zhǔn)備數(shù)據(jù)。

  以Freemarker為例,我們來(lái)看看它是如何為模板準(zhǔn)備數(shù)據(jù)的:

Java代碼
public void doExecute(String location, ActionInvocation invocation) throws IOException, TemplateException {  
    this.location = location;  
    this.invocation = invocation;  
    this.configuration = getConfiguration();  
    this.wrapper = getObjectWrapper();  
 
    // 獲取模板的位置  
    if (!location.startsWith("/")) {  
        ActionContext ctx = invocation.getInvocationContext();  
        HttpServletRequest req = (HttpServletRequest) ctx.get(ServletActionContext.HTTP_REQUEST);  
        String base = ResourceUtil.getResourceBase(req);  
        location = base + "/" + location;  
    }  
 
    // 得到模板  
    Template template = configuration.getTemplate(location, deduceLocale());  
    // 為模板準(zhǔn)備數(shù)據(jù)  
    TemplateModel model = createModel();  
 
    // 根據(jù)模板和數(shù)據(jù)進(jìn)行輸出  
    // Give subclasses a chance to hook into preprocessing  
    if (preTemplateProcess(template, model)) {  
        try {  
            // Process the template  
            template.process(model, getWriter());  
        } finally {  
            // Give subclasses a chance to hook into postprocessing  
            postTemplateProcess(template, model);  
        }  
    }  

public void doExecute(String location, ActionInvocation invocation) throws IOException, TemplateException {
    this.location = location;
    this.invocation = invocation;
    this.configuration = getConfiguration();
    this.wrapper = getObjectWrapper();

    // 獲取模板的位置
    if (!location.startsWith("/")) {
        ActionContext ctx = invocation.getInvocationContext();
        HttpServletRequest req = (HttpServletRequest) ctx.get(ServletActionContext.HTTP_REQUEST);
        String base = ResourceUtil.getResourceBase(req);
        location = base + "/" + location;
    }

    // 得到模板
    Template template = configuration.getTemplate(location, deduceLocale());
    // 為模板準(zhǔn)備數(shù)據(jù)
     TemplateModel model = createModel();

    // 根據(jù)模板和數(shù)據(jù)進(jìn)行輸出
    // Give subclasses a chance to hook into preprocessing
    if (preTemplateProcess(template, model)) {
        try {
            // Process the template
            template.process(model, getWriter());
        } finally {
            // Give subclasses a chance to hook into postprocessing
            postTemplateProcess(template, model);
        }
    }
}

  從源碼中,我們可以看到,createModel()方法真正為模板準(zhǔn)備需要顯示的數(shù)據(jù)。而之前,我們已經(jīng)看到過(guò)這個(gè)方法的源碼,這個(gè)方法所準(zhǔn)備的數(shù)據(jù)不僅包含ValueStack中的數(shù)據(jù),還包含了被封裝過(guò)的HttpServletRequest,HttpSession等對(duì)象的數(shù)據(jù)。從而使得模板能夠以它特定的語(yǔ)法輸出這些數(shù)據(jù)。 [SPAN]

  Velocity的Result也是類(lèi)似,有興趣的讀者可以順著思路繼續(xù)深究源碼。

  redirect

Xml代碼
<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/> 
<result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/> 
<result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/> 

<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
<result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
<result-type name=&quot;redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult&quot;/>

  如果你在Action執(zhí)行完畢后,希望執(zhí)行另一個(gè)Action,有2種方式可供選擇。一種是forward,另外一種是redirect。有關(guān)forward和redirect的區(qū)別,這里我就不再展開(kāi),這應(yīng)該屬于Java程序員的基本知識(shí)。在Struts2中,分別對(duì)應(yīng)這兩種方式的Result,就是chain和redirect。

  先來(lái)談?wù)剅edirect,既然是重定向,那么源地址與目標(biāo)地址之間是2個(gè)不同的HttpServletRequest。所以目標(biāo)地址將無(wú)法通過(guò)ValueStack等Struts2的特性來(lái)獲取源Action中的數(shù)據(jù)。如果你需要對(duì)目標(biāo)地址傳遞參數(shù),那么需要在目標(biāo)地址url或者配置文件中指出:

Xml代碼
<!--  
   The redirect-action url generated will be :  
   /genReport/generateReport.jsp?reportType=pie&width=100&height=100 
   --> 
   <action name="gatherReportInfo" class="..."> 
      <result name="showReportResult" type="redirect"> 
         <param name="location">generateReport.jsp</param> 
         <param name="namespace">/genReport</param> 
         <param name="reportType">pie</param> 
         <param name="width">${width}</param> 
         <param name="height">${height}</param> 
      </result> 
   </action> 

<!--
   The redirect-action url generated will be :
   /genReport/generateReport.jsp?reportType=pie&width=100&height=100
   -->
   <action name="gatherReportInfo" class="...">
      <result name="showReportResult" type="redirect">
         <param name="location">generateReport.jsp</param>
         <param name="namespace">/genReport</param>
         <param name="reportType">pie</param>
         <param name="width">${width}</param>
         <param name="height">${height}</param>
      </result>
   </action>

  同時(shí),Redirect的Result支持在配置文件中,讀取并解析源Action中ValueStack的值,并成為參數(shù)傳遞到Redirect的地址中。上面給出的例子中,width和height就是ValueStack中的值。

  chain

Xml代碼
<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/> 

<result-type name="chain" class=&quot;com.opensymphony.xwork2.ActionChainResult"/>

  再來(lái)談?wù)刢hain,之前提到,chain其實(shí)只是在一個(gè)action執(zhí)行完畢之后,forward到另外一個(gè)action,所以他們之間是共享HttpServletRequest的。在使用chain作為Result時(shí),往往會(huì)配合使用ChainingInterceptor。有關(guān)ChainingInterceptor,Struts2的Reference說(shuō)明了其作用:

  Struts2 Reference 寫(xiě)道:If you need to copy the properties from your previous Actions in the chain to the current action, you should apply the ChainingInterceptor. The Interceptor will copy the original parameters from the request, and the ValueStack is passed in to the target Action. The source Action is remembered by the ValueStack, allowing the target Action to access the properties of the preceding Action(s) using the ValueStack, and also makes these properties available to the final result of the chain, such as the JSP or Velocity page.

  也就是說(shuō),ChainingInterceptor的作用是在Action直接傳遞數(shù)據(jù)。事實(shí)上,源Action中ValueStack的數(shù)據(jù)會(huì)被做一次Copy,這樣,2個(gè)Action中的數(shù)據(jù)都在ValueStack中,使得對(duì)于前臺(tái)來(lái)說(shuō),通過(guò)ValueStack來(lái)取數(shù)據(jù),是透明而共享的。chain這個(gè)Result有一些常用的使用情景,這點(diǎn)在Struts2的Reference中也有說(shuō)明:

  Struts2 Reference 寫(xiě)道:One common use of Action chaining is to provide lookup lists (like for a dropdown list of states). Since these Actions get put on the ValueStack, their properties will be available in the view. This functionality can also be done using the ActionTag to execute an Action from the display page.

  比如說(shuō),一張頁(yè)面中,你可能有許多數(shù)據(jù)要顯示,而某些數(shù)據(jù)的獲取方式可能被很多不同的頁(yè)面共享(典型來(lái)說(shuō),“推薦文章”這個(gè)小欄目的數(shù)據(jù)獲取,可能會(huì)被很多頁(yè)面所共享)。這種情況下,可以把這部分邏輯抽取到一個(gè)獨(dú)立Action中,并使用chain,將這個(gè)Action與主Action串聯(lián)起來(lái)。這樣,最后到達(dá)頁(yè)面的時(shí)候,頁(yè)面始終可以得到每個(gè)Action中的數(shù)據(jù)。

  不過(guò)chain這種Result,是在使用時(shí)需要慎重考慮的一種Result:

  Struts2 Reference 寫(xiě)道:As a rule, Action Chaining is not recommended. First explore other options, such as the Redirect After Post technique.

  而Struts2也做出了理由上的說(shuō)明:

  Struts2 Reference 寫(xiě)道:Experience shows that chaining should be used with care. If chaining is overused, an application can turn into "spaghetti code". Actions should be treated as a Transaction Script, rather than as methods in a Business Facade. Be sure to ask yourself why you need to chain from one Action to another. Is a navigational issue, or could the logic in Action2 be pushed back to a support class or business facade so that Action1 can call it too?

Ideally, Action classes should be as short as possible. All the core logic should be pushed back to a support class or a business facade, so that Actions only call methods. Actions are best used as adapters, rather than as a class where coding logic is defined.

  從實(shí)戰(zhàn)上將,使用chain作為Result也的確存在著上面所說(shuō)的許多問(wèn)題,我個(gè)人也是非常不推崇濫用這種Result。尤其是,對(duì)于使用Spring和Hibernate的朋友來(lái)說(shuō),如果你開(kāi)啟OpenSessionInView模式,那么Hibernate的session是跟隨HttpServletRequest的,所以session在整個(gè)action鏈中共享。這會(huì)為我們的編程帶來(lái)極大的麻煩。因?yàn)槲覀冎繦ibernate的session會(huì)保留一份一級(jí)緩存,在action鏈中,共享一級(jí)緩存無(wú)疑會(huì)為你的調(diào)試工作帶來(lái)很大的不方便。

  所以,謹(jǐn)慎使用chain作為你的Result,應(yīng)該成為一條最佳實(shí)踐。

  stream

Xml代碼
<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/> 

<result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>

  StreamResult等價(jià)于在Servlet中直接輸出Stream流。這種Result被經(jīng)常使用于輸出圖片、文檔等二進(jìn)制流到客戶(hù)端。通過(guò)使用StreamResult,我們只需要在Action中準(zhǔn)備好需要輸出的InputStream即可。

Xml代碼
<result name="success" type="stream"> 
  <param name="contentType">image/jpeg</param> 
  <param name="inputName">imageStream</param> 
  <param name="contentDisposition">filename="document.pdf"</param> 
  <param name="bufferSize">1024</param> 
</result> 

<result name="success" type="stream">
  <param name="contentType">image/jpeg</param>
  <param name="inputName">imageStream</param>
  <param name="contentDisposition">filename="document.pdf"</param>
  <param name="bufferSize">1024</param>
</result>

  同時(shí),StreamResult支持許多參數(shù),對(duì)輸出的Stream流進(jìn)行參數(shù)控制。具體每個(gè)參數(shù)的作用,可以參考://struts.apache.org/2.0.14/docs/stream-result.html

  其他

  Struts2的高度可擴(kuò)展性保證了許多自定義的Result可以通過(guò)插件的形式發(fā)布出來(lái)。比較著名的有JSONResult,JFreeChartResult等等。有興趣的讀者可以在Struts2的官方網(wǎng)站上找到它們,并選擇合適的加入到你的項(xiàng)目中去。

  關(guān)于Result配置簡(jiǎn)化的思考 

  Struts2的Result,解決了“如何從Control層轉(zhuǎn)向View層”的問(wèn)題。不過(guò)看了上面介紹的這些由框架本身實(shí)現(xiàn)的Result,我們可以發(fā)現(xiàn)Result所涉及到的,基本上還停留在為Control層到View層搭建橋梁。

  傳統(tǒng)的,我們需要通過(guò)配置文件,來(lái)指定Action執(zhí)行完畢之后,到底執(zhí)行什么樣的Result。不過(guò)在這樣一個(gè)到處呼吁簡(jiǎn)化配置的年代,存在著許多方式,可以省略配置:

  1. 使用Annotation

  Struts2的一些插件提供了@Result和@Results的Annotation,可以通過(guò)Annotation來(lái)省略XML配置。具體請(qǐng)參考相關(guān)的文檔。

  2. Codebehind插件

  Struts2自帶了一個(gè)Codebehind插件(Struts2.1以后被合并到了其他的插件中)。Codebehind的基本思想是通過(guò)CoC的方式,使用命名約定來(lái)確定JSP等資源文件的位置。它通過(guò)實(shí)現(xiàn)了XWork的UnknownHandler接口,來(lái)實(shí)現(xiàn)當(dāng)Struts2框架無(wú)法找到相應(yīng)的Result時(shí),如何進(jìn)行處理的邏輯。具體文檔可以參考://struts.apache.org/2.0.14/docs/codebehind-plugin.html

  大家可以在上面這兩種方式中任意選擇,國(guó)內(nèi)著名的開(kāi)源倡導(dǎo)者Springside也是采用了上述2種方法。在多數(shù)情況下,使用Codebehind,針對(duì)其他的一些Result使用Annotation進(jìn)行配置,這樣可以在一定程度上簡(jiǎn)化配置。

  不過(guò)我本人對(duì)使用Annotation簡(jiǎn)化配置的評(píng)價(jià)不高。因?yàn)閷?shí)際上使用Annotation,只是將原本就非常簡(jiǎn)單的配置,從xml文件中移動(dòng)到j(luò)ava代碼中而已。就代碼量而言,本身并沒(méi)有減少。

  在這里,我也在經(jīng)常在思考,如何進(jìn)行配置簡(jiǎn)化,可以不寫(xiě)Annotation,完全使用CoC的方式來(lái)指定Result。Codebehind在CoC方面已經(jīng)做出了榜樣,只是Codebehind無(wú)法判別Result的類(lèi)型,所以它只能支持dispatcher / freemarker / velocity這三種Result。所以Result的類(lèi)型的判別,成為了阻礙簡(jiǎn)化其配置CoC化的攔路虎。

  前一段時(shí)間,曾經(jīng)熱播一部電視劇《暗算》,其中的《看風(fēng)》篇中數(shù)學(xué)家黃依依的一段話給了我靈感:

  黃依依 寫(xiě)道:開(kāi)啟密鎖鑰匙的復(fù)雜化,是現(xiàn)代密碼發(fā)展的趨勢(shì)。但這種復(fù)雜化卻受到無(wú)線通訊本身的限制,尤其是距離遠(yuǎn)、布點(diǎn)多的呈放射性的無(wú)線通訊,一般的密鑰總是要藏在報(bào)文中。

  密鑰既然可以藏在報(bào)文中,那么Result的類(lèi)型當(dāng)然也能夠藏在ResultCode中。

Java代碼
return "success"; 

return "success";

  這樣一個(gè)簡(jiǎn)單的success作為ResultCode,是無(wú)法識(shí)別成復(fù)雜的Result類(lèi)型的,我們需要設(shè)計(jì)一套更加有效的ResultCode,同時(shí),Struts2能夠識(shí)別這些ResultCode,并得到相應(yīng)的Result類(lèi)型和Result實(shí)例。這樣,我們就可以借用Codebehind的實(shí)現(xiàn)方式,實(shí)現(xiàn)XWork的UnknownHandler接口,從而達(dá)到我們的目的。例如,我們規(guī)定ResultCode的解析規(guī)則:

  success —— 使用codebehind的規(guī)則進(jìn)行JSP,F(xiàn)reemarker模板的尋址

  r:/user/list  —— 返回一個(gè)redirect的Result,地址為/user/list

  c:/user/list —— 返回一個(gè)chain的Result,地址為/user/list

  j:user —— 返回一個(gè)JSON的Result,JSONResult的Root對(duì)象為user

  s:inputStream-text/html —— 返回一個(gè)StreamResult,使用inputStream,并將contentType設(shè)置成text/html

  以此類(lèi)推,大家可以定義自己喜歡的ResultCode的格式,從而簡(jiǎn)化配置。有了這樣的規(guī)則,也就有了后來(lái)的實(shí)現(xiàn)。具體解析這些ResultCode,并為他們構(gòu)建Result實(shí)例的源碼,大家可以參考我的一個(gè)插件項(xiàng)目LightURL。


標(biāo)簽:

本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn

文章轉(zhuǎn)載自:JavaEye

為你推薦

掃碼咨詢(xún)


添加微信 立即咨詢(xún)

電話咨詢(xún)

客服熱線
023-68661681

TOP
国产精品久久丫毛片A片软件 | 亚洲视频日本有码中文 | 在线观看成人片韩剧 | 最好看的2018国语在线 | 日本乱妇18日本乱妇18p | 91啦国产| 色多多APP福引导入口 | 国产一区二区三区国产精品 | 成年人黄色免费网站 | 欧洲不卡一卡2卡三卡4卡网站 | 无码日本邻居大乳人妻在线看 | 欧美午夜视频在线观看 | 卡一卡二卡三专区免费 | 九九精品成人免费国产片 | 婷婷丁香五月激情综合站 | 国产精品乱码一区二区三 | 制服丝袜中文在线 | 欧美激情视频二区三区 | 国产日日操 | 久久久久99 | 精品在线播放视频 | 色久久好 | 精品夜夜澡人妻无码AV | 泷泽萝拉qvod快播 | 免费无毒a网站在线观看 | 风韵丰满熟妇啪啪区老熟熟女 | 久久视频这有精品63在线国产 | 久久综合给合久久狠狠狠97色69 | 亚洲精品午夜一区二区电影院 | 亚 洲 视 频 高 清 无 码 | 午夜精品久久久久久久2023 | 免费无码又爽又刺激A片软软件 | 手机av在线播放 | 国色天香日本免费观看 | 欧美久久网 | 麻豆一卡2卡三卡4卡网站 | 精品久久日产国产一二三区 | 日本成人一区二区三区 | 国产女精品 | 久久精品中文騷妇女内射 | 国产乱老熟妇吃嫩草 | 欧美黑人乱大交 | 国产精品久久久久久久久久妇女 | 琪琪午夜伦伦A片 | 日韩小视频在线 | 在线视频播放免费网站视频在线 | 午夜性做爰A片免费看 | 久久久精品免费 | 黄色片a| 国产亚洲精品久久久久久老妇 | 国产高清精品入口91 | 麻花传媒沈芯语老师视频 | 办公室挺进美妇李婷 | 激情6月丁香婷婷色综合 | 欧美三区在线观看 | 爱的色放mp4下载 | 国产九精品国产动漫人物 | 日本午夜精品理论片A级APP发布 | 国产精品女上位在线观看 | 亚洲va视频 | 在线播放波多野结衣 | WWW午夜调情 | 日本三级一区 | 一区两区三不卡 | 在线中文天堂最新版官网 | AV夜夜躁狠狠躁日日躁 | 免费国产成人高清在线网站东京 | 九九免费久久这里有精品23 | 精品四虎国产在免费观看 | 91精品综合 | 99视频免费看 | 无码精品一区二区三区视频色欲网 | 性生交大全免费看 | 国产精品186在线观看在线播放 | 日韩免费视频播播 | 日韩内射美女片在线观看网站 | 影音先锋资av男人撸 | 成人A片免费看男人社区 | 男女羞羞下面好湿视频 | 久久永久视频 | 少妇做爰高潮呻吟A片免费 少妇做爰又色又紧夜视频 谁有三级网站 | 乱肉合集乱500篇小说书架下载TXT | 国产精品主播在线高清不卡 | 国产a网 | 欧美激情久久久久久久大片 | 欧日韩美香蕉在线观看 | 男人天堂网2022 | 亚洲精品字幕 | 国产精品免费一区二区三区四区 | 乱码视频午夜间在线观看 | 香蕉成熟时 | 一区二区视频在线观看高清视频在线 | 影音先锋av不撸 | 国产欧美日韩网站 | 日韩有码在线视频 | 艳妇臀荡乳欲伦交换在线播放 | 最好看的韩国日本免费 | 亚洲国产欧美日本视频 | 国产一二三四区在线观看 | a色网站| 国产精品香蕉视频在线 | 亚洲欧洲无码AV在线观看你懂的 | 国产乱码日产精品BD | 免费国产黄网在线观看 | 老司机午夜精品视频播放 | 国产精品中文字幕在线 | 久久综合久色欧美综合狠狠 | 欧美成人精品第一区二区三区 | 狠狠色丁香婷婷综合久久来 | 五月天黄色网址 | 日本中文字字幕乱码电影直播 | 夜夜操狠狠干 | 少妇高潮A片特黄久久精品网 | 内射丰满高大五十五岁熟女 | 日韩一卡2卡3卡4卡无卡免费视频 | 无码人妻中文在线佐佐木明希 | 18禁无遮挡羞羞动漫视频免费 | 黄色免费看网站 | 亚洲午夜精品A片久久W | 黄色成人在线视频 | 亚洲高清在线不卡中文字幕网 | 美女下面揉出水免费视频 | 亚欧有色在线观看免费版高清 | 日本美女性生活 | 开心成人 | 国产69精品久久久久乱码免费 | 伊人久久综合成人亚洲 | 狠狠色噜噜狠狠狠狠奇米777 | 狠狠久久免费视频在线 | 日本综合在线 | 久久成人国产精品免费 | aaaaaa级特色特黄的毛片 | 久久人人玩人妻潮喷内射人人 | 国产WW高清大片免费看 | 无码内射成人免费喷射 | 久久精品韩国三级 | 国产伊人影院 | 亚洲AV无码乱码A片无码蜜桃 | 亚洲AV成人片色在线观看高潮 | 亚洲国产熟妇无码一区二区三区H | 丁香婷婷色综合 | se94se最新网站 | 日本不卡一区二区三区 | 激情小说在线播放 | 久久精品视在线观看2 | 黄色网址分享 | 欧美午夜网站 | 久久不卡精品 | 狠狠色噜噜狠狠狠狠 | 国产精品人妻无码免费久久一 | 人妻少妇被粗大爽.9797PW | 国产夜夜春 | 国产亚洲精品久久无码98 | 国产精品萌白酱在线观看 | 青草韩国| 好爽插到我子宫了高清在线 | 免费网站在线观看人数在哪里看的 | 一个人免费完整在线观看日本 | 无码又黄又爽又舒服的A片 无人区AV在线观看 无人区乱码区1卡2卡三卡在线 | 免费看的一级毛片 | 狠狠色伊人亚洲综合网站l 狠狠色伊人亚洲综合第8页 | 日日噜噜噜夜夜爽爽狠狠视频 | 午夜爱爱免费视频体验区 | 毛片在线播放网址 | 成人午夜在线视频 | 欧美日韩影视 | 国产剧情www.yw193.com | 国产午夜精品理论片 | 国产男女猛烈无遮挡A片小说 | 久久三级网站 | 伦理网 | 日韩成人免费在线 | 日韩精品一卡2卡3卡4卡5卡 | 日韩一区二区三区免费体验 | 揉胸吸奶动态GIF图 肉多NP 巨H公交车情欲 | 色狠狠AV老熟女 | 东北老女人大叫爽死啦 | 一本大道香蕉在线资源 | 亚洲va久久久噜噜噜久久天堂 | 国产下药迷倒白嫩美女在线观看 | 手机看片欧美 | 欧美多毛的大隂道 | 国产一起色一起爱 | 欧美香蕉大胸在线视频观看 | 亚洲一卡2卡3卡4卡乱码 在线 | 日本不卡高清中文字幕免费 | 中文字幕免费在线视频 | 色网址在线观看 | 中文字幕三级在线不卡 | 欧美亚洲日本一区二区三区浪人 | 快穿之情欲尺度H | 热99re久久国超精品首页 | 国产色婷婷亚洲99精品 | 麻豆文化传媒一区二区 | 色鬼综合 | 日韩欧美视频一区二区在线观看 | 日本一区二区不卡视频 | 看亚洲人配人配人种jizz | 麻豆视传媒官方网站入口 | 日本无码特黄午夜视频在线观看 | 中文 在线 日韩 亚洲 欧美 | 免费在线观看h片 | 老司机午夜视频在线观看 | 夜夜躁日日躁狠狠久久 | 四虎影在线在永久观看 | 成人高清 | 中文字幕理伦午夜福利片 | 成人AV无码一二二区视频免费看 | 2022麻豆福利午夜久久 | 最近最新中文字幕高清免费 | 91精品国产综合久久精品 | 国产精品久久久久久久久久直 | 噜噜AV亚洲一区二区 | 国色天香精品一卡二卡三卡四卡 | 男人的天堂av2024在线 | 亚洲AV久久无码 | 国产AV99激情久久无码天堂 | 亚洲色综合中文字幕在线 | 久久精品国产久精国产 | 国产三级精品久久三级国专区 | 欧美精品网 | 五月色婷婷亚洲男人的天堂 | 高黄H文各种姿势PLAY道具1V1 | 精品蜜臀AV在线天堂 | 四房色播电影 | 最新在线观看精品国产福利片 | 精品久久综合1区2区3区激情 | 性久久久久久久久 | 色噜噜狠狠色综无码久久合欧美 | 日韩视频网址 | 日韩电影免费在线观看中文字幕 | 糖心vlog国产剧免费观看 | 国产乱码卡二卡三卡43 | 国产精品视频免费视频 | 亚洲AV久久无码精品夜夜挺 | 国产特黄特色的大片观看免费视频 | 波多野结衣久久一区二区 | 人人舔人人爱 | 国产又粗又深又猛又爽又黄A片 | 在线综合 亚洲 欧美 日韩 | 久久亚洲精品高潮综合色A片小说 | 久久这里只精品热在线99 | 色视频线观看在线播放 | 91传媒制片厂果冻有限公司 | 免费观看日本视频 | 久久综合给合久久狠狠狠97色 | 国产精品刺激好大好爽视频 | 嫩草院一区二区乱码 | 免费又黄又硬又爽大片 | 中文字幕精品在线 | 香港三级日本三级韩国三级 | 国产精品久久久久久无码人妻 | 日本无码H纯肉黄动漫A红桃 | 欧美国产伦久久久久 | 又硬又粗进去爽A片免费无码 | 中国白毛老头性xxxxx | 天堂欧美 | 天天干夜夜艹 | 国产色秀视频 | 欧美一区二区三区性 | 天天操夜夜爽 | 再插深点嗯好大好爽 | 电影 国产 偷窥 亚洲 欧美 | 黑人粗长大战亚洲女 | 国产一级一级毛片 | 日本高清在线视频无码 | 国产成a人亚洲精v品久久网 | 亚洲第一黄色网址 | 精品久久久久久无码中文字幕 | 777精品出轨人妻国产 | 苍井空电影去哪儿看网址 | 一级毛片一级毛片一级毛片一级毛片 | 久久中文字幕人妻AV熟女 | 真人作爱视频免费网站 | 欧美色欧美亚洲高清图片 | 国产激情无码激情A片免费软件 | 91香蕉嫩草 | 在线二区 | 亚洲一区二区三区视频 | 福利视频欧美一区二区三区 | 最近中文字幕手机大全 | 潮吹美人鱼 | 免费毛片网站在线观看 | 国产精品XXXXX免费A片 | 亚洲伊人久久综合影院2021 | 色男人网站| 精品久久久久成人码免费动漫 | 亚洲一区二区三区秋霞秋理 | 免费大片在线观看视频网站 | 欧美成人日韩 | 福利视频欧美一区二区三区 | 日本老太做爰XX0LD | 国产九九精品 | 又黄又刺激好看的小说 | 在线免费观看波多野结衣 | 最近更新2019中文字幕 | 国产成人精品久久免费动漫 | 黄色激情网址 | 好久被狂躁A片视频无码免费视频 | 久久久亚洲天堂 | 欧美性猛片AAAAAAA | 亚洲精品久久区二区三区蜜桃臀 | 国产九九精品视频 | 蜜柚AV久久久久久久 | 永久品色堂 | 欧美一区二区激情视频 | 国产中文字幕一区 | 久久久这里只有精品加勒比 | 操 美女视频 免费网站 | 天天干天天干天天干天天干 | 中国孕妇XXXXXXXXX孕交 | 奇米777视频国产 | 国产成人免费网站 | 亚洲国内精品自在线影院牛牛 | 亚洲中字慕日产2024 | 午夜毛片在线观看 | 91热久久免费频精品动漫99 | 老司机深夜福利影院 | 色搜成人搜索 | 苍井空无码播放电车 | 久操视频在线免费观看 | 亚洲一区二区免费视频 | 一个人看的片在线WWW免费中文 | 久久五月丁香激情综合 | 国产人妖在线观看 | 91亚洲影院 | 亚洲精品拍拍央视网出文 | 亚洲一级毛片免费在线观看 | 成人免费看AA片 | 四个人弄我一个要坏掉的 | 忘忧草社区在线日本韩国电影 | 国产乱码一二三区精品 | 国产AV寂寞骚妇 | 男人天堂网2024最新地址 | 精品国产免费观看久久久 | 欧美最猛性xxxxx喷水 | 99久久国产综合精品网成人影院 | 国产成人性毛片 | 97国产揄拍国产精品人妻 | 搡女人真爽免费视频网站 | 麻豆免费版 | 久操资源在线 | 青草热久精品视频在线观看 | 亚洲爱v | AV午夜午夜快憣免费观看 | 岛国黄色 | 国产麻豆老师在线观看 | 麻豆妓女爽爽一区二区三 | 深夜福利一区二区 | 欧美在线高清 | 啊好湿双性(h)生子 啊灬啊别停灬用力啊免费视频 | 国产精品久久久久久亚洲色 | 国产一区二区自拍视频 | 国产又色又爽又刺激的A片 国产又色又爽又黄的A片 | 一级做a爰片久久毛片武则天 | 国产精品综合色区 | 亚洲高清国产拍精品动图 | 国产精品夜夜春夜夜爽久久小说 | 片成年免费观看网站黄 | 久久久久免费精品国产 | 欧美无修正 | 中文字幕欧美日韩在线不卡 | 久久这里只有精品1 | 丁香综合网 | 日本iphone69| 农村熟妇高潮精品A片 | 五月激激激综合网色播胖胖 | 亚洲午夜久久影院 | 制服a片| 亚洲人成网亚洲欧洲无码 | 日本a视频在线观看 | 午夜性做爰A片免费看 | 无码国产一区二区三区四区 | 亚洲精品色播一区二区 | 色综合精品久久久久久久 | 簧片电影大全网站 | 99re8在线精品免费观看 | 亚洲一区AV在线观看无码漫画 | 亚洲b | 久久鲁鲁 | 日韩精品视频美在线精品视频 | 麻豆最新国产剧情AV原创免费 | 999精品国产人妻无码系列 | 涩涩视频下载 | 精品人妻无码一区二区三区手机版 | 草草视频在线播放 | 色综合成人网 | 2021日日摸夜夜添夜夜添影院 | 荡公乱妇第1章方情公憩系列大 | 灌饱娇嫩H将军公主最新章节 | 中文幕无线码中文字蜜桃 | 欧日韩美香蕉在线观看 | 欧美成人精品一区二区免费 | 色人阁久久| 人妻不敢呻吟被中出A片视频 | 影音先锋中文AV资源网 | 91三级在线 | 久久国产精品久久久久久久久久 | 少妇性夜夜春夜夜爽A片 | 精品一区二区三区免费毛片 | 日韩色中色 | 精品亚洲卡一卡2卡三卡乱码 | 日本黄色高清 | 欧美特级限制片高清 | 亚洲精品国产v片在线观看 亚洲精品高清国产一线久久97 | 欧美乱码卡一卡二卡四卡免费 | 伊人手机在线视频 | 黄色三级视频在线观看 | 欧美又大粗又黄又爽无码 | 成年ssswww中国女人 | 日本大片免a费观看视频 | 日韩欧美国产免费看清风阁 | 日本亚洲精品无码区国产电影 | 欧美肥婆videos另类 | 欲妇荡岳丰满少妇岳A片 | 忘忧草在线影院日本图片 | 亚洲精品深夜AV无码一区二区 | 免费一级毛片能看的 | 国产色情乱码久久久久一区二区 | 伊人久久中文字幕 | 无码高潮少妇毛多水多水免费 | 2020国产成人久久精品 | 色戒汤唯梁朝伟七分频视频 | 狠狠的撸2016最新版 | 色爱区综合激情五月综合色 | 夜夜操夜夜爱 | 青草视频在线观看免费 | 房奴电视剧| 夜夜躁狠狠躁日日躁2024 | 黄色一级欧美 | 五月婷婷六月丁香综合 | yy直播不雅视频完整版 | 女人被老外躁得好爽 | 欧美又粗又大XXXX无码 | 四虎影视免费观看高清视频 | 在线日韩视频 | 日韩视频精品 | 在线毛片一区二区不卡视频 | 亚洲国产精品高清在线一区 | 欧美乱妇日本无乱码特黄大片 | 婷婷在线视频国产综合 | 国产色情无码网站视频APP | 性欧美video另类hd亚洲人 | 欧美人与禽ZOZO性伦交视频 | 国产午夜精品美女视频露脸 | 97资源共享在线视频 | 性一交一乱一伦一A片 | 精品一卡2卡三卡4卡乱码理论 | 国产综合在线播放 | 国产综合欧美日韩在线 | 小辣椒导航精品福利视频 | 91在线一区二区 | 国产女人水真多18毛片18精品 | 戳女人屁股流水羞羞漫画 | 久久丁香视频 | 久久久午夜视频 | 99re6国产精品免费播放 | 最近最新中文字幕2018中文字幕mv | 日日摸夜夜添夜夜添高潮免费A片 | 亚洲狠狠色丁香婷婷综合 | 麻豆最新国产剧情AV原创免费 | 8x在线观看免费视频 | 午夜看片在线 | 扒开粉嫩小泬舌头伸进去视频 | 亚洲 欧美 制服 校园 动漫 | 黑人与牛交ZOZOZO | 色宅男午夜电影网站 | 国产成人综合亚洲亚洲欧美 | 99视频精品国产免费观看 | 久久精品久久精品久久精品 | 黑人vs亚洲人在线播放 | 蜜桃传媒一区二区亚洲AV | 欧洲不卡一卡2卡三卡4卡网站 | 日本大片高清免费视频日本 | 中文天堂www资源 | 国产色情18一20岁片A片 | 免费无码又爽又刺激A片涩涩在线 | 亚洲国产精品色情20242024 | 天天射天天操天天 | 亚州少妇无套内射激情视频 | 8x国产精品视频 | 亚洲AV无码乱码国产麻豆穿越 | 欧美激情久久久久久久大片 | 亚洲一区二区三区四区五区六 | 中文字幕亚洲男人的天堂网络 | 夜夜精品视频一区二区 | www.xxxx.日本 | 国产免费网站看v片元遮挡 国产免费区 | 国产 欧美 亚洲 中文字幕 | 综合网天天 | 国产午夜爽爽窝窝在线观看 | 久久极品 | 国内精品美女视频免费直播 | 天堂中文在线资源库用 | 日韩第二页 | 在线成人综合色一区 | 91精品福利久久久 | 狠狠操网址 | 国产一级一级毛片 | 日韩视频在线观看中字 | 日本一区不卡在线 | 亚洲一区二区三区在线视频 | 成全在线观看免费播放 | 亚洲AV无码一区东京热在线播放 | 色偷偷一区二区三区视频 | 热99这里只有精品 | 四虎国产成人免费观看 | 韩国三级在线高速影院 | 超级狂色而且免费又超好看 | 8x永久在线视频 | 五月丁香激色婷五月天 | 巨乳女子校生 | 国模嘉妮极品美胞 | 亚洲久久少妇中文字幕 | av电影下载网址 | 特级毛片片A片AAAAAA | 麻豆国产巨作AV剧情 | 工口里番全彩全彩无遮挡 | 午夜成人在线视频 | 亚洲AV又黄又爽超级A片软件 | 美日韩毛片| 4480yy午夜私人影院 | 甜涩性爱下载 | 日韩精品人妻AV一区二区三区 | 久久狼人综合 | 国产成人亚综合91精品首页 | 两个人免费视频在线观看直播 | a级毛片免费 | 国自产拍偷拍精品啪啪 | 人妻天天爽夜夜爽三区麻豆A片 | 国产无遮挡成人免费视频网站 | 欧美高清视频看片在线观看 | 蜜桃日本MV免费观看 | 免费看日b视频 | 西部矿业集团有限公司 | 2020夜夜操 | 久国产 | 久久久久久综合一区中文字幕 | 一本色道在线久88在线观看片 | 久久精品23 | 欧美性生交XXXXX无码久久久 | 日韩中文字幕视频 | 黄色片黄色片黄色片黄色片黄色片 | 天天干夜夜添 | 日韩国产精品人妻无码久久久 | 五月婷婷综合在线 | 欧美天天视频 | 偷窥国产亚洲免费视频 | 久久观看 | 亚洲AV成人一区二区三区在线看 | 最近中文字幕完整版视频 | 99热久久这里只精品国产WWW | 狠狠色丁香久久婷婷综合丁香 | 久久国产成人精品 | 亚洲一区二区三区成人 | 日本阿v视频高清在线 | 激情午夜婷婷 | 亚洲精品一区二区三浪潮AV | 狠狠狠色 | 乱码丰满人妻一二三区 | 免费看国产曰批40分钟 | 国产精品人妻一区夜夜爱 | 色爱区综合激情五月综合激情 | www.av小视频| 欧美bbw极品另类 | 久久综合色网 | 五月天国产精品 | 五月婷婷七月丁香 | 天天综合网天天做天天受 | 亚洲综合色色图 | 99爱精品 | 五月婷婷久久草丁香 | 99九九热 | 97国产精华最好的产品在线 | 2019中文字幕在线观看 | 久久久久国产午夜 | 波多野结衣私拍重置版APP | 国产永久视频 | 亚洲第一AAAAA片 | 草草影院在线播放 | 免费费很色视频大片 | 九九热在线视频观看这里只有精品 | 四虎影视影院电影在线 | 黄页网站在线 | 天堂网2021天堂手机版丶 | 2024一級特黃色毛片免費看 | 日本vps私人大片 | 亚洲AV一宅男色影视 | 猛烈顶弄H| WWW国产亚洲精品久久小说 | 日韩特级毛片免费观看视频 | 欧美老妇xxx | 99久久免费国产精品 | 日韩在线视频观看在线看 | 狠狠干狠狠操视频 | 久草免费福利资源站在线观看 | 日本19岁护士伦理在线 | 最新黄yyid| 免费做爰猛烈吃奶摸视频在线观看 | 亚洲中文字幕AV色情网址 | 日韩午夜欧美精品一二三四区 | 高清在线免费观看完整版电影大全 | 在线看午夜福利片 | 天天草综合 | 97免费看 | 大尺度一级毛片波多野结衣 | 国产又爽又黄又爽又刺激 | 黄色三级a | 久久草免费线看线看2 | 亚洲国产精品一区二区动图 | 欧美日韩中文国产一区发布 | 狠狠色噜噜狠狠狠狠2021天天 | 少妇做爰高潮呻吟A片免费 少妇做爰又色又紧夜视频 谁有三级网站 | 亚洲欧美制服丝袜一区二区三区 | 成人免费视频69 | 亚洲精品久久一区二区三区四区 | 国产欧美一区二区三区免费 | 国产 ts 人妖 在线 | 四虎影视免费大全 | 天天色视频 | 亚洲精品一区三区三区在线观看 | 激情影院在线 | 中文字幕久久第13页 | 国产国产乱老熟女视频网站97 | 四库影院884TT永久地址 | 久久精品视在线看1 | 免费一区二区三区久久 | 欧美熟妇无码XXXXXX | 飞空精品影院首页 | 97夜夜澡人人爽人人模人人喊 | 流氓软件app免费下载大全下载 | 久久国产这里只精品免费 | 国产老肥熟 | 亚洲 国产专区 校园 欧美 | 窝窝在线视频 | 亚洲精品无码高潮喷水A片软件 | 91精品国产免费 | 丁香花视频资源在线观看 | 欧美日韩一二区旡码高清在线 | 国产伦精品一区二区三区免费观看 | www日韩免费高清视频 | 草草免费观看视频在线 | 亚洲乱码国产一区三区 | 樱花草免费视频在线观看WWW | 99久久精品久久久 | 96色视频 | 久久免费看少妇高潮A片特黄多 | 三级国产三级在线 | 久久综合五月开心婷婷深深爱 | 好满好深好撑好涨h | 91孕妇精品一区二区三区 | 久热网| 国产真实乱人偷精品人妻图 | 日韩一本在线中文字幕 | 亚洲精品一区二区三区四区手机版 | 午夜精品久久久久久久99热 | 工口里番外番全彩无遮挡 | 69欧美xxxxx色护士视频 | 精品欧美一区视频在线观看 | 呻吟国产AV久久一区二区 | 又长又大又粗又硬3p免费视频 | 国精产品999永久中国有限公司 | 粗大的内捧猛烈进出A片 | 日本无码色哟哟婷婷最新网站 | 性freexxxxhd欧美在线 | 亚洲日本激情 | 久久永久免费视频 | 日韩毛片在线 | 欧美日韩中文国产一区发布 | 欧美一区二区三区成人看不卡 | 国产精品av免费观看 | ririai66视频在线播放 | 日本护士xxxxx在线 | 九九久久亚洲综合久久久 | 欧美亚洲高清国产 | 亚洲国产在线精品国自产拍五月 | 精品无码日本蜜桃麻豆走秀 | 啊轻点灬大JI巴又大又粗A片 | 国产真实乱人偷精品人妻图片 | 国产99热在线观看 | hd成人免费电影 | 国产亚洲精品精品精品 | A国产一区二区免费入口 | 国产精品99久久免费观看 | 日韩一区二区三区四区区区 | 老妇毛片久久久久久久久 | 老司机深夜福利视频 | 欧洲每年百万吨电子垃圾流向亚非 | 久久九九免费视频 | 国产成人精品999在线 | WWW日韩AV免费高清看 | 手机在线观看视频免费视频 | 最近最新最好的2018中文字幕 | 亚洲乱码一卡2卡3卡 | 国产精品国产三级国产在线观看 | 在线免费观看国产视频 | 婷婷六月天激情 | 日韩视频免费一区二区三区 | 免费国产黄网站在线观看可以下载 | 日本一区二区在线播放 | 亚洲精品无码一区二区 | 蜜桃在线观看无码免费 | 97超级碰碰人妻中文字幕 | 欧美色影| 无码成A毛片免费 | 黄金网站app在线看 黄黄网 | 婷婷精品国产亚洲AV在线观看 | 又硬又粗进去好爽A片66 | 十八禁啪漫动漫在线看 | 成人区人妻精品一区二欧美毛片 | 国内精品中文字幕 | 国产精品久久久久精 | 久久久久女人精品毛片九一 | 手机看片国产在线 | 日韩 在线视频精品 | 日本黄色一级网站 | 国精产品一区一区三区有限公司 | 午夜西瓜视频在线观看 | 国产精品主播在线高清不卡 | WWW国产成人免费观看视频 | 一级不卡毛片免费 | 乱码丰满人妻一二三区 | caoporn 超频在线视频 | 国产二级一片内射视频播放 | 亚洲成在人色婷婷 | 蜜臀AV国产精品久久久久 | 中文字幕乱码 电影在线观看 | 免费无码又爽又刺激A片小说在线 | 久久综合九色综合狠狠97 | 亚洲国产品综合人成综合网站 | 九九九九在线精品免费视频 | 超91精品手机国产在线 | 日韩性做爰免费A片AA片 | 国产精品中文字幕在线 | 久综合色 | 国产午夜亚洲精品国产 | 91传媒蜜桃香蕉在线观看 | 亚洲欧美在线观看 | 久久精品66 | 亚洲欧洲视频一区 | 欧美做受 | 三要四妾国语免费观看 | 四房播播在线电影 | 久久日本片精品AAAAA国产 | 免费在线观看一区 | 久久精品国产亚洲精品 | 亚洲精品伦理熟女国产一区二区 | 色哟哟视频在线观看免费播放 | 黄色网页在线免费观看 | 亚洲中文字幕在线播放YW193. | 免费看一区二区三区 | 成人综合网址 | 亚洲精品久久AV无码麻小说 | 伊人久久99 | 国产亚洲一区二区在线观看 | 男女又黄又刺激B片免费网站 | 精品乱码卡一卡2卡三免费 精品乱码久久久久久中文字幕 | 真实国内老女人的露脸视频 | 一区二区三区毛AAAA片特级 | 精品人妻无码一区二区三区下一页 | 六月伊人| 欧美精品无码一二三区网站 | 欧美精品18videose 性欧美 | 亚1州区2区3区产品乱码站 | 日本亚洲精品 | 亚洲视屏在线 | 日韩内射美女人妻一区二区三区 | 成人片在线观看免费人A片 成人区色情综合小说 | 国产不卡在线 | 六月丁香激情 | 岛国大片在线播放高清 | 日韩爽爽爽视频免费播放 | 漂亮的丰年轻的继坶3在线 漂亮的丰年轻的继坶3在线观看 | 91久久精品国产亚洲 | 国产精品人妻一区二区高 | 2024精品极品国产色在线观看 | 簧片高清在线观看 | 麻豆精品国产 | 99视频在线看观免费 | 老司机午夜剧场 | 婷婷综合在线观看丁香 | 98久久人妻少妇激情啪啪 | 最新黄网 | 香蕉黄网 | 成年必看视频在线观看 | 亚洲日韩在线a视频在线观看 | 四虎comwww最新地址 | 日本不卡不码高清免费 | 99久久精品免费看国产四区 | 色狠狠一区二区 | 日韩吃奶摸下AA片免费观看 | 日本一在线中文字幕天堂 | 秋霞伦理电院韩日 | 丰满人妻妇伦又伦精品APP国产 | 亚洲欧美中文字幕5发布 | 黄在线视频播放免费网站 | 激情深爱 | 婷婷激情五月网 | 国产福利一区二区精品 |