国产精品青草久-国产精品情侣愉拍-国产精品区网红主-国产精品区一区二-国产精品热久久-国产精品热热热-国产精品人aⅴ-国产精品人成在线-国产精品人妻人伦-国产精品人人

金喜正规买球

Result機制——豐富您的視圖

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

概述:Result機制——豐富您的視圖

# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>

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

  Result的職責(zé) 

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

  封裝跳轉(zhuǎn)邏輯

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

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

  以JSP轉(zhuǎn)向為例,在Struts2自帶的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重定向為例,在Struts2自帶的ServletRedirectResult中,也同樣存在著重定向的核心代碼:

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

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

....

response.sendRedirect(finalLocation);

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

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

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

  以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到底是如何獲取各種對象的值的。

  控制輸出行為

  有的時候,針對同一種類型的View展示,我們可能會有不同的輸出行為。具體來說,可能有時候,我們需要對輸出流指定特定的BufferSize、Encoding等等。Result層,作為一個獨立的層次,可以提供極大的擴展性,從而保證我們能夠定義自己期望的輸出類型。

  以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的定義 

  讓我們來看看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;
}

  這個接口定義非常簡單,通過傳入ActionInvocation,執(zhí)行一段邏輯。我們來看看Struts2針對這個接口實現(xiàn)的一個抽象類,它規(guī)定了許多默認(rèn)實現(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;
}

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

  如果我們試圖編寫自定義的Result,我們可以實現(xiàn)Result接口,并在struts.xml中進行聲明:

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 

  接下來,大致介紹一下Struts2內(nèi)部已經(jīng)實現(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等以頁面為基礎(chǔ)View視圖,這個也是Struts2默認(rèn)的Result類型。在使用dispatcher時,唯一需要指定的,是JSP或者HTML頁面的位置,這個位置將被用于定位返回的頁面:

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

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

  而Struts2本身也沒有對dispatcher做出什么特殊的處理,只是簡單的使用Servlet API進行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ù)的越來越流行,使用Freemarker或者Velocity模板進行View層展示的開發(fā)者越來越多。Struts2同樣為模板作為Result做出了支持。由于模板的顯示需要模板(Template)與數(shù)據(jù)(Model)的緊密配合,所以在Struts2中,這兩個Result的主要工作是為模板準(zhǔn)備數(shù)據(jù)。

  以Freemarker為例,我們來看看它是如何為模板準(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ù)進行輸出  
    // 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ù)進行輸出
    // 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)看到過這個方法的源碼,這個方法所準(zhǔn)備的數(shù)據(jù)不僅包含ValueStack中的數(shù)據(jù),還包含了被封裝過的HttpServletRequest,HttpSession等對象的數(shù)據(jù)。從而使得模板能夠以它特定的語法輸出這些數(shù)據(jù)。 [SPAN]

  Velocity的Result也是類似,有興趣的讀者可以順著思路繼續(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í)行另一個Action,有2種方式可供選擇。一種是forward,另外一種是redirect。有關(guān)forward和redirect的區(qū)別,這里我就不再展開,這應(yīng)該屬于Java程序員的基本知識。在Struts2中,分別對應(yīng)這兩種方式的Result,就是chain和redirect。

  先來談?wù)剅edirect,既然是重定向,那么源地址與目標(biāo)地址之間是2個不同的HttpServletRequest。所以目標(biāo)地址將無法通過ValueStack等Struts2的特性來獲取源Action中的數(shù)據(jù)。如果你需要對目標(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>

  同時,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"/>

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

  Struts2 Reference 寫道: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.

  也就是說,ChainingInterceptor的作用是在Action直接傳遞數(shù)據(jù)。事實上,源Action中ValueStack的數(shù)據(jù)會被做一次Copy,這樣,2個Action中的數(shù)據(jù)都在ValueStack中,使得對于前臺來說,通過ValueStack來取數(shù)據(jù),是透明而共享的。chain這個Result有一些常用的使用情景,這點在Struts2的Reference中也有說明:

  Struts2 Reference 寫道: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.

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

  不過chain這種Result,是在使用時需要慎重考慮的一種Result:

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

  而Struts2也做出了理由上的說明:

  Struts2 Reference 寫道: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.

  從實戰(zhàn)上將,使用chain作為Result也的確存在著上面所說的許多問題,我個人也是非常不推崇濫用這種Result。尤其是,對于使用Spring和Hibernate的朋友來說,如果你開啟OpenSessionInView模式,那么Hibernate的session是跟隨HttpServletRequest的,所以session在整個action鏈中共享。這會為我們的編程帶來極大的麻煩。因為我們知道Hibernate的session會保留一份一級緩存,在action鏈中,共享一級緩存無疑會為你的調(diào)試工作帶來很大的不方便。

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

  stream

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

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

  StreamResult等價于在Servlet中直接輸出Stream流。這種Result被經(jīng)常使用于輸出圖片、文檔等二進制流到客戶端。通過使用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>

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

  其他

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

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

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

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

  1. 使用Annotation

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

  2. Codebehind插件

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

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

  不過我本人對使用Annotation簡化配置的評價不高。因為實際上使用Annotation,只是將原本就非常簡單的配置,從xml文件中移動到j(luò)ava代碼中而已。就代碼量而言,本身并沒有減少。

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

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

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

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

Java代碼
return "success"; 

return "success";

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

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

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

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

  j:user —— 返回一個JSON的Result,JSONResult的Root對象為user

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

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


標(biāo)簽:

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

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

為你推薦

  • 推薦視頻
  • 推薦活動
  • 推薦產(chǎn)品
  • 推薦文章
  • 慧都慧問
掃碼咨詢


添加微信 立即咨詢

電話咨詢

客服熱線
023-68661681

TOP
亚洲国产精品午夜伦不卡 | 国产在线观看精品 | 国产乱子伦在线观看视频 | 欧美成人伊人久久中文字幕 | 欧美v国产v| 国产成人无码aa精品一区 | 国产成人8x人网站在线视频 | 国产精品亚洲av高清二区 | 国产果冻 | 国产精品后入内射日本在线观看 | 欧美日韩 | 国产不卡一区二区三区視频。 | 精品国产免费第一区二区三区日 | 国产学生真实初次破初视频网站 | 日本高清天码一区在线播放 | 国产成人精品午夜视频 | 亚洲免费图区在线视频 | 91在线免费观看 | 欧美最猛性xxxxx大叫 | 一区二区三区免费观看 | 少妇av| 精品欧美一区二区三区四区 | 91在线国产手机在线 | 加勒比东京热在线观看 | 日韩欧美三级 | 国产一区丝袜高跟在线i91传媒 | 人妻无码在线视频二区 | 成人网站免费大全日韩国产 | 国产三级精品三级在线专区91 | 国产aaaaaa | av永久天堂一区二区三区 | 无码专区日韩精品中文字幕 | 国产精品亚洲欧美大片在线观看 | 成年女人免费视频播放大全 | 精品无码国产自产拍在线观看蜜桃 | 国产成人久久综合区 | 国产欧美va欧美va香蕉在线观看 | 东京热一本无码av | 91桃色永久免费福利版下载 | 91精品在线观看入口火爆更新 | 国产精品日本一区二区在线 | 毛片成人永久免费视频 | 亚洲av无码久久寂寞少妇多毛 | 精品久久久久久久久久 | 国产成人99久久亚洲综合精品 | 亚洲国产日产无码精品 | 国产婷婷高清在线观看免费 | 国产成人综合高清 | 亚洲精品国产啊女成拍色拍 | 九一制片厂果冻 | 成人性三级欧美在线观看 | 国产精品人人爽人 | 国产欧美精品系列在线播放 | 99国内自产精华 | 国产激情一区二区三区四区 | 亚洲av理论在线电影网 | 精品国精品国产自在久国产 | 欧美人妻羞羞一区二区三区 | 亚洲综合精品一区二区三区 | 亚洲精品tv久久久久久久久 | 99久久精品熟女高潮喷水免费 | 成人av在线播 | 欧美丝袜高跟鞋一区二区 | 国产美女亚洲精品久久久毛片 | 国产精品一区在线蜜臀 | 亚洲av无码乱码在线观看性色扶 | 亚洲av无码专区一级婬片毛片 | 国产福利一区二区免费视频 | 99国产精品免费看 | 国产av巨作情欲放纵无码 | 国产精品福利写真 | 超碰国产精品最新 | 久久成人免费 | 国产精鲁鲁视频在线观看 | 99久久久久国 | 亚洲欧美日韩、中文字幕不卡 | 精品免费亚洲三级 | 日韩av无码成人精品国产 | 亚洲aⅴ一区二区三区四区 亚洲aⅴ永久无码天 | 韩国国产一区二区三区 | 中文字幕无码视频专区在线播放 | 国产一级二级在线观看 | 精品亚洲av无码综合网 | 成人无码区免费a片www | 欧美精品一区二区三区不卡网 | 国内精品久久久久影视 | 久久爱评论库第12章第1页 | 深夜免费网站一区在线观看 | av无码av天天av天天爽 | 中文字幕无码成人免费视频 | 国内亚洲精品视频在线观看 | 无码国产在线国产97在线 | 97久久婷婷五月综合色d啪蜜芽 | 精品99精品在 | 国产综合久久久久久鬼色 | 亚洲乱码国产乱码精品精大量 | 午夜亚洲av永久无码精品 | 九一果冻制品厂推出新剧达达兔 | 国产高潮国产高潮久久久 | 国产aⅴ视频一区二区三区 国产aⅴ天堂亚洲国产av | 中文字幕有码在线观看 | 亚洲无码黄色视频在线 | 国产精品jizz视频 | 国产成人久久精品二区三区 | 91无码人妻精品一区二区 | 在线看性爱av网站 | 日本欧美一区 | 丰满人妻一区二区三区性色 | 欧美多人顶级午夜寂寞影院 | 国产乱码一区二区三区爽爽爽女仆 | 国产日韩欧美视频在线 | 人妻少妇久久久久久97人妻 | 国产精品午夜爆乳美女视频 | 国产成人av无码片在线影院 | 日本一区午夜艳熟免费 | 国产成人精品a视频一区 | 香蕉视频在线观看免费 | 国产精品一区二区三区不卡福利 | 亚洲成在人网站天堂日本 | 国产成人av无码网站久久 | 99久久99久久久精品久久 | 91福利网站 | 中文字幕日产乱码一区 | 精品久久久一区二区三区 | 国产午夜福利片在线观看 | 国产成人麻豆精品午夜福利在 | 亚洲无码在线观看一区二区 | 国产乱妇乱子视频在播放 | 黄色成人在线 | 女性喷水高潮在线观看 | 丰满爆乳肉感一区二区三区 | 白丝爆浆18禁一 | 成熟看a级毛片 | 亚洲av无码av专区在线观看 | av软件 | 国产综合激情在线亚洲第一页 | 国产成人亚洲精品无码青app | 久久99精品国产 | 日韩av激 | 91亚洲国产成人久久精品蜜臀 | 亚洲精品成人久久久影院 | 国产亚洲精品福利视频在线观看 | 亚洲精品久久久中文字幕痴女 | 性色av无码无在线观看 | 亚洲午夜精品一区二区三区 | 黄毛片网站免费在线观看 | 成人午夜精品网站在线观看 | 二区三区麻豆 | 中文字幕爆乳 | 国内精品久久久久 | 国产mcu精品91 | 国产婷婷综合在线视频 | 成人在线高清 | 中文字幕色婷婷在线精品中 | 国产精品黄色成人 | 中文字幕不卡二区亚洲 | 欧美性猛| 国产高潮流白浆的视频 | 日韩精品卡2卡3卡4卡5 | 国产区美女91精品视频 | 欧美日韩综合视频一区 | 国产白丝jk制服在线视频 | 国产毛多水多高潮高清 | 中文字幕久无码免费久久 | 精品无码国产自产拍在线观看蜜 | 日韩人妻一区二区三区蜜桃视频 | 在线视频免费观看www动漫 | 午夜福利 | 国产口爆吞精在线视频 | 日本午夜福利在线观看 | 午夜亚洲乱码伦小说区 | 亚洲av无码乱观看明星换脸va | 国产免费无码av片在线观看不 | 二区精品视频在线观看 | 亚洲熟女一区二 | 91在线无码精品秘入口果冻 | 欧美性大战xxxxx久久久√ | 91香蕉国产线在线观看免费网友评价 | 亚洲av高清不卡久久 | 一区二区三区av波多野结衣 | 亚洲av无码版在线观看 | 午夜视频福利在线观看 | a级毛片无码 | 99午夜福利精品视频 | 丰满少妇夜夜爽爽高潮水 | 午夜神马| 日本三级片在线观看 | 亚洲乱码国产乱码精品精 | 国产91精品一区二区 | 免费无码国产v片在线观看 免费无码国产白丝视频 | 香蕉久久91综合一区二区三区 | 激情a∨无| 成人区人| 色情无码一区二区三区 | 亚洲精品aa片在线观看 | 亚洲蜜芽在线精品一区 | 在线极品美女a毛片费观看 在线精品91青草国产 | 亚洲av无码一区二区三区在线播放 | 色偷偷av一区 | 97久久天天综合色天天综合色 | 国产亚洲精品a | 精品综合久 | 国产精品成av人在线观看片 | 伊人色综合一区二区三区 | 人与动物ppt免费模板大全 | 国产高清自拍视频 | 国产精品成人亚洲一区二区 | 91嫩草国产在线无码观看 | 国内精品久久久久久影院 | 亚洲午夜成人精品电影在线观看 | 国产av人人夜夜澡人人爽 | 91精产国品一二三产区 | 国产精品欧美一区喷水 | 午夜国产精品福利视频100集 | 中文字幕熟妇人妻在线视频 | 色婷婷久久综合中文久久 | 丰满风流护士长bda片 | 人妻系列偷拍无码视频 | 亚洲精品国产品国语原创 | 国产成人92精品午夜福利 | 亚洲综合国产精品一区二区99 | 国产精品毛片一区视频播 | 国产又大又硬又粗 | 国产成人拍精品免费视频 | av在线播放不卡 | 精品粉嫩 | 精人妻无码一区二区三区 | 麻豆成人91精品二区三区 | 少妇无码av无码专区在线观看 | 精品亚洲无码一区 | 狠狠噜天天噜日日噜无码 | 中文字幕在线看aⅴ无码 | 人妻丰满av| 国产爆乳美女娇喘呻 | 97久久婷婷五月综合色d啪蜜芽 | 亚洲精品亚洲人成在线播放 | 久久99久久99精品免视看 | 成人免费a | 国产潮吹喷水 | 91亚洲精品在线 | 精品欧美久久99久久久另类专区 | 日韩亚洲影院 | 亚洲精品合集直播在 | 日韩欧美国产一区二区三区免费 | 中美日韩毛片免费观看 | 日本免费一区二区三区最新 | 91精品国产综合久久青草 | 日韩人妻| 福利姬液液 | 亚洲视频在 | 久久99国产精品二区 | 国产精欧美一区二区三区 | 少妇高潮对白在线 | 日韩成人男女福利电影在线播放网站 | 国产激情视频在线观看免费播放 | 99爱视频99爱在线观看 | 精品动漫中文字幕一区二区三区 | 国内揄拍高清国内精品对白 | 成人av鲁片一区二区 | 九一影视 | 精品一区二区三区视频在线观看免 | 91在线无码一区二区 | 丰满少妇又爽又紧又丰满在线 | 伊人小蛇婷婷色香综合缴缴情 | 精品国产成a人在线观看 | 亚洲欧美精品一中文字幕 | 国产高潮流白浆免费观看不卡 | 97国产在线公开免费观看 | 国产狼友视频一区 | 亚洲综合国产精品一区二区99 | 亚洲精品第一国产综合野 | 在线视频精 | 亚洲精品成人av观看 | 国产色系视频在线观看 | 精品综合久久久久久99 | 91麻豆国产原创剧情片 | 日韩a毛片免费观看 | 国产日韩欧美综合色视频在线 | 国产无套视频在线观看aa在线 | 国产欧美日韩综合精品久久一 | av无码高潮在线网站 | 九色综合狠狠综合久久 | 黄网站免费在线观看日韩 | 一级生性活片全黄在线观看 | 午夜人成在线观看深夜两性视频试看 | 99久久久精品综合 | 精品国产麻豆免费 | 亚洲av不卡无码国产粉色 | 国产午夜理论片不卡在线观看 | 亚洲五码中文字幕 | 欧美精品偷自拍另类在线观看 | 日韩在线a视频免费播放 | 国内最真实的xxxx人伦 | 国产麻豆md传媒视频 | 羞羞影院午夜男女爽爽免费 | 麻豆乱码国产一区二区三区 | 国产高清综合乱色视频 | 精品国产91久久久久久久a | 国产精品tv在线麻豆 | 无人区乱码现象频发 | 亚洲精品少妇久久久久久希岛爱理 | 黄色午夜精品视 | 区二区不卡 | 亚洲一区二区免费在线观看 | 97久久天天综合色天天综合88 | 91新地址永久入口安全检测 | 精品无码人妻一区二区三区不卡 | 国产人妻人伦精品1国产盗摄 | 亚洲国产gv在线观看 | 国产精品亚洲a∨天堂不卡 国产精品亚洲av高清二区 | 美女18禁黄无遮挡网站 | 亚洲国产成人精品女 | 91桃色a片无限免费看 | 国产在线精品国自产拍影院同性 | 色婷婷综合久久久久中文图片 | 99热这里是精品与其他应用相比 | 亚洲av不卡无码国产粉色 | 国产精品日本一区二区在线播放 | 日本一区中 | 敌伦交换一区二区三区流畅不卡顿 | 久久99精品久久久久久野外 | 久草超碰一区二区在线 | 国产精品无码午夜福利免费看 | 亚洲av无码专区在线观 | 无码国产精品一区二区免费久久 | 国产日韩欧美中文字幕在线 | 香蕉免费在线一区二区三区 | 午夜福利精品视频在线 | 国产精品夜间视频香蕉 | 一区二区三区精密机械 | 国产在线aa视频免费观看 | 精品国产av一区二区三区6 | 69视频在线观看免费 | 亚洲阿v天堂在线 | 亚洲成av人片无码天堂 | 国产大片黄在线观看私人影院 | 香蕉视频在线观看亚洲 | 日韩欧美精品一区二区三区在线 | 三级黄色视频 | 中文字幕在线播放 | 欧美日韩性高爱潮视频 | 自慰少妇裸体无码30p | 国产精品视频六区 | 欧美亚洲性爱在线看 | 人人妻人人藻人人爽欧美一区 | 国产亚洲人成在线v网站 | 亚洲电影日韩精品 | 国产成人无码aⅴ片在线观看 | 在线观看一区二区三区av | 国产精品亚洲日韩aⅴ在线 国产精品亚洲色婷婷99久久精品 | 日韩a优精品在线观看 | 无码人妻av免费一 | 中文字幕在线 | 国产伦精品一区二区三区视频猫咪 | 亚洲av无码一区二 | 国产av无码专区毛片 | 精品亚洲一区二区在 | 午夜福利在线视频亚洲 | 99国产这里有精 | 无码一级毛片免费 | 亚洲精品高清αv在线播放 亚洲精品高清国产 | 欧美午夜不卡在线观看 | 久久电影| 91精品人妻一区二区三区蜜臀 | 91欧美在线视频 | 欧美成人欧美va天堂在线电影 | 亚洲av无码一区 | 国产福利在线播放 | 日韩av毛片不卡无码免费 | 一区二区免费视频中文乱码 | 国产在线观看91精品一区 | 天天日天天干天天射 | 91制片厂果冻传媒公司 | 亚洲国产成人精品无码区99 | 91精品国产综合久久久蜜臀 | 国产精品激情综合久久 | 91制片天美果冻传媒 | 欧美成人精品一区二区三区 | 69国产成人综合久久精 | 黄色香蕉视频 | 蜜臀色欲av在线播放国产日韩 | 久草免费版官方最新版下载 | 国内视频在线精品一区 | 97精品一区二区三区 | 亚洲成人av片在线观看无码 | 三级欧美视频自拍 | 中文字幕无码不卡一区二区三区 | 久久99精品久久久久久不卡 | 国产91短视频 | 久久99精品 | 亚洲成熟丰满熟妇高潮xxxxx | 国内精品国产成人国产三级 | 国产欧美日韩v | 国产精品乱码高清在线观看 | 久久99久久99| 综合激情校园第一页 | 国产精品久久久久一区二区三区 | 日韩无码中文另类 | 色欲国产av一级无码 | 久久99精品无码一区二区 | 在线成人免费视频 | 成人先峰 | 91精品国产自产91精品蜜臀 | 91在线码无精品秘入口是什么 | 91成人亚洲综合欧美日韩 | 亚洲成av人片在线观看无码 | 国产欧美一区二区三区在线看 | 自拍无码国产 | 久草福利在线观看 | 91丝袜精品诱惑在线观看 | 中文字幕爆乳巨爆乳系列无码 | 国产亚洲人成无码网在线观看 | 特级黄绝一级在线观看不卡 | 99久久国产 | 成年午夜免费aⅴ在线观看 成年午夜一级毛 | 国产精品视频久久久 | 国产午夜福利在线永久视频 | 亚洲日韩在线 | 精品综合久久久 | 国产精品亚洲专区无码不卡 | 91精品一区二区三区在 | 日韩欧美国产传媒第一区二区 | 精品国产欧美一区二区三区不卡 | 免费无码又爽又高潮视频 | 国产一级做a爰片久久毛片99 | 日韩无人区| a亚洲欧美中文日韩在线v日本 | 亚洲国产精品va在线观看无 | 日本免费黄色片网站 | 亚洲精品无码不卡在线播放he | 麻豆一区二区99久久久久 | 欧美久久综合 | 91人成尤物在线 | 爱豆传媒免费全集在线观看反转爽剧 | 十八禁无码免费网站 | 91精品欧美一区二区综合在线 | 高清无码不卡视频 | 无码精品人妻一区二区三 | 国产午夜精品视频 | 国产91成人免费网站 | 成人碰碰视频公开老师 | 不卡无码人妻一区三区音频 | 国内亚洲精品视频在线观看 | 无码专区 | 精品黑人一区二区三区 | 成人欧美日韩视频一区 | 国产日产欧洲无码视频 | 久久电影| 中文无码在线观看可乐视频 | 午夜在线观看视频免费成人 | 午夜成人鲁丝片午夜精品 | 国产h片在线观看视 | 亚洲福利在线老司机 | 国产综合av一区二区三区无码 | 香蕉视频在线观看福利国产 | 国产精品毛片一区视频播 | 国产日韩精品无码区免费专区国产 | 色资源av | 99热这里只| 精品视频在线免费 | 国产午夜精品一区二区三区四区 | 97爽a高清免费在线观 | 日韩无码亚洲中文字幕 | 狠狠色伊人亚洲 | 欧美嫩交一区二区三区 | 精品无码久久久久久久久久 | 欧美久久久久久精品一区 | 亚洲丰满熟女一区二区v | 日韩免费在线中文字幕 | 国产精品乱码一区二区毛片 | 国产成人精品在线免费观看 | 国产一级按摩精油电影 | 国产aⅴ无码专区亚洲av麻豆 | www.一区二区 | 国产激情视频在线播放 | 欧美三级午夜理伦三级中文字幕 | 99国精品午夜福利 | 中文无码日韩欧 | 亚洲av无码精品色午 | 日韩乱码人妻无码中文 | 国产一区二区粉嫩在线观看 | 无码专区一码二码三码 | 日韩精品一区二区三区四区蜜桃 | 99久久免费热在线精 | 免费一区二区三区手机av | 国产精品va在线 | 国内精品久久久久久久久久影视 | 精品久久久久久久久国产免费 | 国产精品一区二区久久宅男 | 97制片厂爱豆传媒 | 国产白浆一区免费 | 精品国产日韩亚洲一区91 | 欧美色伊人 | 蝌蚪窝在线观看免费视频 | 黄色网页在线观看 | 亚洲国产精品超碰 | 亚洲av无码乱码国产精000 | 亚洲午夜精品成人毛片 | 人妻无码αv中文字幕久久 人妻无码不卡在线看 | 亚洲国产欧美日韩一区二区 | 国产亚洲成av人片在线观黄桃 | 亚洲成人国产综合2025 | 国产aⅴ天堂亚洲国产av | 亚洲成在人线a免费 | 精品国际久久无色无码 | 国产精品香港三级国产av | 欧美亚洲综| 91精品无码久久久久久久久 | 欧美日韩| 中文字幕无码一区在线 | 韩国三级无码高在线观看 | 精品国产群3p在线观看 | 欧美性生交大片免费看a片 欧美性受xxxx黑人xyx性爽 | 亚洲日韩在线观看不卡 | 91麻豆| 国产亚洲精品一级在线观看 | 91欧美| 国产亚洲精品va片在线播放 | 日韩成人精品视频国产在线观看成人 | 国语自产精 | 国产对白刺激 | 午夜福利视频免费看片 | 欧美婷婷| 中文字幕亚洲男人的天堂网络 | 波多野结衣av无码久久一区 | 日韩精品国产免费av | 色偷偷中| 99国产精品永久免费视频 | 国产亚洲3p无码一区二区 | 中文字幕人成乱码熟女app | 中文字幕 | 国产美女精品一 | 精品丰满欧美一区二区三区 | 亚洲欧美变态另类综合 | 最新中文字幕日本 | 国产v在线在线观看羞羞答答 | 国产一区二区三区四区精华液毛 | 无码日韩免费视频一区二区二区 | 国产极品精品免费视频能看 | 久久99视频 | 国产亚洲精品久久久ai换脸 | 精品视频在线 | 蜜臀色欲av在线播放国产日韩 | 99久久综合精品国产 | 人澡人澡人澡人澡91 | 国产香蕉尹人综合在线观看 | 国产欧美二区三区 | 国产精品视频久久 | 毛片va一区二区三区 | 无码一区二区波多野结衣 | 无码精品国产一区二区 | 中文字幕av一本 | 国产在线观看麻豆91精品免费 | 99免费精品无码视频 | 97人妻精品一区二区三区免 | 久草视频网站 | 一区二区亚洲av无码 | 国产人成免费视频 | 99精品无码一区二区毛片免费 | 少妇高潮惨叫久久久久久 | 午夜精品成人毛片 | 无码不卡一区二区三区在线观看 | av香港经典三级级在线观看 | 午夜免费视频 | 国产精品亚洲精品日韩已满 | 久久99久久 | 中文字幕无码久久久久久 | 日韩精品亚洲人成在线观看 | 97色伦97色伦国产 | 国产国产人精品视频69 | 国产a∨国片精品白丝美女视频 | 日本成人网在线观看 | 超碰人人看人人爽 | 深夜成人网站 | 国产午夜福利电影在线观看2 | 国产在线观看私人影院 | 69风韵老熟 | 国产精品激情综合 | 欧日韩在线不卡视 | 无码专区—va亚洲v专区 | 国产精品成人久久久久久久 | av中文一区二区三区桃花岛 | 天天爽天天干天天操 | 久久91精品牛牛 | 亚洲日韩aa特黄毛片试看 | 国产亚洲精品国产91 | 国产av激情久久无码天堂 | 成人性三级欧美在线观看 | 卡一卡二卡三精品入口 | 自拍亚洲一区欧美另类 | 中文亚洲成a人片在线播放 中文亚洲成a人片在线观看 | 丰满少妇又爽又紧又丰满在线观看 | 成人网站 | 国产又黄又大又粗的视频 | 免费无遮挡又黄又爽网站 | 国产传媒在线观看 | 女同久久| 亚洲影院天堂中文av色 | 亚洲一区二区三区中文字幕在线 | 99久久国产热无码精品免费 | 国人国产免费观看av在线 | av无码一区二区老年 | 国产激情视频在线观看免费播放 | 精品无码av一区二区三区 | αv天堂在线观看免费αⅴ αv在线视频免费观看男人 | 国产精品无码无 | 精品欧美日韩在线视频 | 爆乳邻居肉欲中文字幕 | 精品蜜桃秘一区二区三区粉嫩 | 果冻破解版(果冻视频)下载免费 | 最新国产一级a一片免费观看 | 99伊人网| 国内一本到不卡在线观看 | 亚洲精品高清国产一久久 | 国产91精品一区二区麻豆亚洲 | 国产日韩精品一区二区在线观 | 中文精品久久久久国产不卡 | 久久东京热无码av | 国产欧美日韩 | 国产高清在线精品一区二区 | 欧美日韩免费观看 | 国产亚洲av片a区二区三区 | 国产精品v日 | 成人免费精品网站在线观看影片 | 欧美性插b在线视频网站 | 亚洲av福利院在线观看 | 亚洲成av人片一区二区密柚 | 国产三级电影在线观看 | 国产爆乳无码视频在线观看3 | 国产欧美日本韩高清视频一区 | 国产熟女一区二区三区浪潮 | 97色伦背后的神秘故事与深刻思考 | 国产成人aa免费视频 | 无码人妻精品一区二区三区99 | 国产精久久一区二 | 国产精品巨作无遮拦 | 日韩+欧美+亚洲 | 亚洲免费人成视频在线观看 | 无码精品一区二区三区视频蜜臀 | 91精品国产白丝在线观看 | 成人黄片免费观看 | 熟女综合一区二区 | 无人区麻豆乱码久久久 | 欧美生活大片在线观看 | 亚洲无码视频一区二区 | 亚洲国产欧美日韩一区二区 | 在线观看无码av免费不卡网站 | 国产成人无卡在线观看 | 国内一本到不卡在线观看 | 精品一区二区三区四区日产 | 海角社区视频精品熟妇乱久久久 | 国产一区二区三区免费在线 | 99热这里只有精品第一页 | 91精品人妻少妇无码影院 | 午夜视频污在线观看 | 亚洲国产成人精品久久久 | 日本国产成人国产在线播放 | 狠狠躁天天躁中文字幕 | wwwxxx国产在线 | 日韩a优精品在线观看 | 亚洲午夜在线视频观看 | 亚洲成av人影院在线观看网 | 国产精品成人一区二区三区 | 国产免费av在线播放不卡 | 国产人妻人伦精品1国产盗摄 | 日韩久久久精品中文字幕 | 免费无码肉片在 | av在线中文观看 | 久久99精品久久 | 国产精选秘免费进入竹菊影视 | 国产人成无码视频在 | 国产亚洲日韩av在线播放 | 区不卡二区不卡三区 | 精品无码成人久久久久久动漫 | 国产精品18久久久久久妖精 | 成人精品一区二区三区日本久久 | 国产av性爱亚洲 | 91无人区卡一卡二卡三乱码 | 无码av免费一区二区三区 | 精品偷拍 | 日韩aⅴ精品国内在线 | 中文字幕在线精品视频入口一区 | 三年在线观看免费观看 | 波多野结衣中文字幕久久 | av无码一码免费在线观看 | 在线观看国产成人av天堂 | 蝌蚪窝在线观看免费视频 | 亚洲成人国产 | 亚洲午夜成人精品 | 99热门精品一区二区三区无码 | 久久99精品久久久久麻豆 | 三級中文字幕電影大全 | 韩国大尺度电影 | 亚洲精品国产a久久久久久 亚洲精品国产va在 亚洲精品国产啊女成拍色拍 | 国产无遮挡裸 | 99在线精品日韩一区免费国产 | 91久久国产 | 97人人模人人爽人人 | 另类欧美日韩综合一区 | 国产一级毛片国语版 | 91人妻丝袜美腿一区二区 | 亚洲av无码片区一区二区三区 | 国产97视频人人做人人爱 | 在线看不卡 | 久久成人亚洲香蕉草草 | 亚洲精品成人无限看 | 91天堂素人精品系列全集亚洲 | 国产精品高潮呻吟久久av | 亚洲欧美日本综合一区二区 | 国产精品日本一区二区在线播放 | 无码h肉动漫在线观看 | 在线欧美日韩亚洲国产一区 | 亚洲精品国产综合一线久久 | 日本欧美一区 | 中文亚洲成a人片在线播放 中文亚洲成a人片在线观看 | 中文精品久久久久 | 亚洲欧美手机在线观看 | 精品视频在线免费 | 综合激情五月综 | 无码一区二区三三精品视频久久久 | 国产成人亚洲日本精品 | av男人的天堂在线观看第三区 | 亚洲精品国产一区黑色丝袜 | 国产娇小粉嫩在线观看 | 国产成人亚洲综合精品 | 99久久99这里只有免费精品 | 少妇太爽了在线观看 | 国产av国片精品无套内谢无码 | 在线免费观看小视频 | 亚洲无码视频一区 | 白丝爆浆18禁一区 | 亚洲成av人在线观看影院 | 91精品国产91久久综合 | 亚洲av永久精品毛片天堂 | 国产真实露脸乱子伦 | 国产色青青视频在线观看撒 | 91传媒制片厂制作网 | 91大神精品视频高清免费观看 | 国产精品成人一区二区三区影院 | 日本中文字幕在线视频播二区 | 久久se精品一区精品二区 | 日本a级精品一区二区三区 日本a片把舌头伸进 | 国语自产精品视频熟女 | 久久99精品久久久久久9 | 国产av+刺激+无码 | 天美传媒麻豆精东蜜桃 | 国产国产人精品视频69 | 91精品啪在线观看国产线免费 | 国产三级精品三级在线观看专 | 无码特级毛片免费看 | 精品国产三级a乌鸦在线观看99 | 欧洲国产伦久久久久久久 | 91久久大香伊蕉在人线 | 亚洲成av人片在www色猫咪 | 99精品视频久久精品视频 | 精品国产一区二区三区不卡在 | 无套内内射视频网站 | 亚洲国产中文精品无码专区网站 | 国产精品国内免费一区二区三区 | 午夜人成在线观看深夜两性视频试看 | 国产三级片一级在线观看 | 精品无码人妻被多人侵犯av | 午夜不卡久久精品无码免费 | 亚洲视频在线观看不卡 | 精品亚洲 | 人妻少妇久久久久久97人妻 | 国产激情免费视频在线观看 | 麻豆国产尤物av尤物在线看 | 国语精品91自产拍在线观看一区 | 午夜福利免 | 国产色欲色欲色www无码 | 毛片福利视频 | 亚洲精品aa在线 | 无码精品人妻一区二区三区中 | 丰满人妻系列无码专区 | 97精品一区二区视频在线观看 | 国产熟女高潮视频 | 亚洲精选av | 中文字幕人妻伦伦 | 国产精品午夜一级毛片密呀 | 午夜全免费一级毛片在线播放 | 国产高潮视频在线播放 | 国产久爱青草视频在线观看 | 欧美精品黑人粗大 | 国产精品无码久久久久久曰本 | av在线中文字幕不卡电影网 | 国产91长腿美女在线观看 | 国产欧美久久久精品影院 | 亚洲一区二区影视 | 亚洲精品国产专区91在线 | av在线天堂网自拍 | 91av在线播放 | 国产精品白丝av在线观看播放 | 精品国产乱码久久久久久一区 | 亚洲成av人片在线观看 | 在线天堂中文在线资源 | 亚洲欧美日韩变态另类 | 在线一区二区不卡 | 日本动漫在中国的传播黄金时期 |