国产凹凸在线-国产拗女一区二区三区-国产白白视-国产白领-国产白拍-国产白丝jk被疯狂输-国产白丝喷-国产白丝在线

金喜正规买球

Result機制——豐富您的視圖

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

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

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

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

  Result的職責 

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

  封裝跳轉邏輯

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

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

  以JSP轉向為例,在Struts2自帶的ServletDispatcherResult中就存在著核心的JSP跳轉邏輯:

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);

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

  準備顯示數據

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

  以Struts2自帶的FreemarkerResult為例,在Result中,就存在著為模板準備數據的邏輯代碼:

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);
        }
    }
}

  我們可以在這里添加我們自定義的內容到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,執行一段邏輯。我們來看看Struts2針對這個接口實現的一個抽象類,它規定了許多默認實現:

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;
}

  很顯然,這個默認實現是為那些類似JSP,Freemarker或者Redirect這樣的頁面跳轉的Result而準備的一個基類,它規定了Result將要跳轉到的具體頁面的位置、是否需要解析參數,等等。 [SPAN]

  如果我們試圖編寫自定義的Result,我們可以實現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內部已經實現的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等以頁面為基礎View視圖,這個也是Struts2默認的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"/>

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

  以Freemarker為例,我們來看看它是如何為模板準備數據的:

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());  
    // 為模板準備數據  
    TemplateModel model = createModel();  
 
    // 根據模板和數據進行輸出  
    // 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());
    // 為模板準備數據
     TemplateModel model = createModel();

    // 根據模板和數據進行輸出
    // 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()方法真正為模板準備需要顯示的數據。而之前,我們已經看到過這個方法的源碼,這個方法所準備的數據不僅包含ValueStack中的數據,還包含了被封裝過的HttpServletRequest,HttpSession等對象的數據。從而使得模板能夠以它特定的語法輸出這些數據。 [SPAN]

  Velocity的Result也是類似,有興趣的讀者可以順著思路繼續深究源碼。

  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執行完畢后,希望執行另一個Action,有2種方式可供選擇。一種是forward,另外一種是redirect。有關forward和redirect的區別,這里我就不再展開,這應該屬于Java程序員的基本知識。在Struts2中,分別對應這兩種方式的Result,就是chain和redirect。

  先來談談redirect,既然是重定向,那么源地址與目標地址之間是2個不同的HttpServletRequest。所以目標地址將無法通過ValueStack等Struts2的特性來獲取源Action中的數據。如果你需要對目標地址傳遞參數,那么需要在目標地址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的值,并成為參數傳遞到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"/>

  再來談談chain,之前提到,chain其實只是在一個action執行完畢之后,forward到另外一個action,所以他們之間是共享HttpServletRequest的。在使用chain作為Result時,往往會配合使用ChainingInterceptor。有關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直接傳遞數據。事實上,源Action中ValueStack的數據會被做一次Copy,這樣,2個Action中的數據都在ValueStack中,使得對于前臺來說,通過ValueStack來取數據,是透明而共享的。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.

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

  不過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.

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

  所以,謹慎使用chain作為你的Result,應該成為一條最佳實踐。

  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被經常使用于輸出圖片、文檔等二進制流到客戶端。通過使用StreamResult,我們只需要在Action中準備好需要輸出的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支持許多參數,對輸出的Stream流進行參數控制。具體每個參數的作用,可以參考://struts.apache.org/2.0.14/docs/stream-result.html

  其他

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

  關于Result配置簡化的思考 

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

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

  1. 使用Annotation

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

  2. Codebehind插件

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

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

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

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

  前一段時間,曾經熱播一部電視劇《暗算》,其中的《看風》篇中數學家黃依依的一段話給了我靈感:

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

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

Java代碼
return "success"; 

return "success";

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

  success —— 使用codebehind的規則進行JSP,Freemarker模板的尋址

  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設置成text/html

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


標簽:

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

文章轉載自:JavaEye

為你推薦

  • 推薦視頻
  • 推薦活動
  • 推薦產品
  • 推薦文章
  • 慧都慧問
掃碼咨詢


添加微信 立即咨詢

電話咨詢

客服熱線
023-68661681

TOP
免费国产va在 | 欧美日本一区二区视频在线播放 | 最新国产精品精品视频 | 免费人成年短视频免费网站 | 亚洲日本va | 精品一区二区免费 | 欧美又大粗又爽又黄大片视频 | 国产啪视频1000 | 国语自产精品视频在线区 | 国产精品综合一区二区在线观看 | 综合狠狠| 精品日韩欧美在 | 精品国产国产综合精品 | h片在线观看资源网站 | 欧美三级视频 | 国产欧美激情亚洲情 | 国产性爱精品家庭乱伦视频 | 欧美在线观看精品国产 | 亚洲欧美日韩综合aⅴ电影 国产一区二区欧美专区 | 亚洲自偷自偷精品 | 92看片淫黄大片看国产片 | 日产日产自线一二三四2025 | 欧美xxxx黑人又粗又长精品 | 亚洲男人的天堂在线aⅴ视频 | 欧美aⅴ菲菲影视城视频 | ady中文字幕| 熟女一区中文字 | 成全看免费观看 | 中文在线免费视频 | 中文字幕亚洲欧美 | 日韩精品二区 | 永久在线观看免费视频 | 中文字幕一区二区三区四区 | 免费99精品国产自在现 | 另类欧美变态 | 午夜国产福利在线直播 | 婷婷国产精品中文字幕 | 日韩在线国产播放 | 亚洲欧美日韩中文高清一 | 精品国产一区二区三区香蕉欧美 | 日本在线观看免费高清 | 在线观看免费精品国产第一区 | 精品国产亚洲一区二区三区在线观 | 欧美伊人影院 | 欧美乱妇日本无乱码特黄大片 | 国产又粗又黄又爽又硬的软件 | 一道免费一区二区三 | 国产caouv在线观看 | 免费poren国| 亚洲国产中文字幕在线观看 | 菠萝蜜视频在线观看高清 | 777米奇| 性爱网在线免费 | 精品玖玖玖视 | 综合激情在线 | 国产盗拍精品视频 | 亚洲高清不卡在线观看 | 99这里有精品视频 | 99精品偷自拍 | 欧美视频在线视频精品 | 人在线观看 | 日本va午 | 欧美日韩亚洲国产无线码 | 国产欧美日韩va另类在线 | 免费观看国产一区二区三区 | 精品大片ww | 最近中文字幕完整版2025一页 | а√天堂资源8在线官网在线 | 国产精品亚洲在线播放 | 亚洲+欧洲+日产 | 日本中文字幕专区视频在线 | 国产9.1国产精成人 办公室第1季9集在线观看 | 天堂网一区二区 | 精品三级影视在线免费观看 | 野花日本大全免费观看中文7 | 三级三级三级a级全黄三电影 | 欧美日韩精品在线二区 | 国产日韩91精品 | 韩国非常大度的电影原声 | 国产福利一区二区在线精品 | 精品九九热在线免费视频 | 日韩在线中文字幕视频 | 五十路熟女俱乐部 | 国产精品天天在线午夜更新 | 欧美亚洲日产综合新一区 | 欧美插逼视频 | 亚欧视频在线观 | 国产亚洲一区区二 | 国产欧美v欧美v在观看 | 久别的草原在线影院播放免费 | 日本理论午夜高清中文字幕 | 日本高清视频www | 韩国午夜理伦三级理论在线观看 | 一个人看的www视频免 | 日本阿v片在线播放免费 | 国产高清乱码又大又圆 | 风流老熟女一区二区三区 | 久欠免费看 | 精品香蕉伊思人在线观看 | 成年女性特黄午夜视频免费看 | 国产一级a毛一级a视频 | 国产免费高清mv视频在线观看 | 星辰影视大全免费版官网 | 痴汉系列在线观看 | 国产黄大片在线观看视频 | a级全黄试看30分钟gif动图 | 日本一区二区三区成人免费观 | 91香蕉成人 | a级精品九九九大片免费看 国产在线观看第二十三页 亚洲午夜成人精品电影在线观看 | 国产日韩另类视频一区爱 | 国产又色又爽又黄又刺激的视 | 亚洲天堂网一区二区三区四区 | 国产福利在线观看免费第一福利 | 韩国日本三级在线播放 | 国产精品天天看特色大片 | 日韩福利免费网站视频在线 | 国产午夜福利片在线观看一区 | 国产综合成人一区二区三区电影院 | 99视频精品免费在线观看 | 国产欧美日韩丝袜精品一区 | 欧美日韩国产免费一区在线观看 | 日本高清www午色夜在线网站 | 新开a3| 欧美激情一区二区三级高清视频 | 欧美xxxx黑人又粗又长精品 | 日韩一区二区三区四区 | 国产99精品免费视频看 | 91高清免费国产自产拍 | 国产特黄特色大片免费 | 国产精品极品美女自在线观看免 | 91亚色视 | 亚洲无线| 欧美综合视频在线观看 | 欧美精品视频在线不卡 | 91国高清在线播放 | 亚洲欧美综合图 | 国产短裙黑色丝袜在线观看下 | 色人阁第四色 | 国产精品va欧美精品v日韩 | 日韩精品一区不卡 | 国产亚洲欧美日韩精品不卡 | 日韩高清码中文字幕日韩 | 精品日本永久免费网站 | 韩国成人精品久 | 不卡电影网 | 国产精品午夜自在在线精品 | 日本黄在线观 | 免费大学生国产在线观看p 97国产精华最好的产品亚洲 | 欧美日韩一级二级三级 | 青苹果乐园 | 久99热这里只有精品 | 亚洲国产区男人本色 | 国产高清乱理伦片中文 | 国产在线激情视频 | 国产午夜亚洲精品不卡免下载 | 国产3344视频在线观看 | 男人的天堂v在线播放 | 日韩精品电影一区亚洲高清 | 日本中文字幕a∨在线观看 免费b站在线观看人数在哪儿找 | 亚洲va在线va天堂va在线 | 色综合天天综 | 日韩一二三区 | 国产又爽又黄又不遮挡视频 | 日韩欧美一级 | 国产中文成人精品小说 | 亚洲综合狠狠99婷婷 | 国语自产 | 国产精品99在线观看 | 欧美中文字幕第一页 | 亚洲欧美中 | 韩国中文全部三级伦在线观看中文 | 亚洲精品国产一级高清在线观看 | 国产香蕉尹人在线 | 欧美在线一级午夜免费 | 最新电影 | 亚洲欧美一区二区三区久本道 | 日韩欧美国产一线 | 欧洲一区二区 | 日韩性爱在线观看 | 国产欧美现场va另类 | 成人欧美一区二区三区视频 | 蜜桃臀v福日本福利一区 | 草莓视频污免 | 欧美激情都市国产 | 欧美日产国产韩国 | 欧美在线视 | 日本hs在线播放观看 | 国产一级变态a视频 | 国产精品免费一级在线观看 | 91福利影院还会玩转热点 | 91人成亚洲高清在线观看 | 日韩欧美福利在线 | 国产精品香蕉在线一区 | 国产又欲又色的视频在线观看 | 国产精品永久免费视频观看 | 九九精品电影 | 男女午夜视频 | 亚洲在在线观看免费视频 | 又黄的免费视频 | 精品亚洲综合在线第一区 | 国产日韩精品欧美一区色 | 国产在线手机视频时看 | 国产妇女视频免费 | 国产高清影片 | 欧美精品亚洲精品日韩专区va | 日本那些又骚又爽的视频 | 国产亚洲精品日韩综合网 | 岛国一区二区三区 | 国产在线偷 | 99视频精品全部免费免费观 | 亚洲中文字幕人成乱在线 | 日韩亚洲精品在线播放 | 亚洲欧美日韩综合在线一区二 | 高清免费视频一区二区三区 | 日本不卡卡中文字幕在 | 亚洲精品在线中文字幕视频 | 成人免费精品视频 | 国产不卡一区二区三区免费视频 | 国产伦精品一区二区三区免费迷 | 91色色| 国产精品乱码一区二区视频 | 91欧美精品| 国产91精品在线观看 | 亚洲裸男gv | 亚洲国产精品自在拍在线播放蜜臀 | 精品第一国产综合精品蜜芽 | 日本高清中文字幕免费一区二区 | 国产一区在线播放资源 | a级大胆欧| a级国产乱理片在线观看 | 亚洲中文字幕一二三区 | 亚洲欧洲国产日产综合综合 | 免费v片在线观看 | 免费看成年视频在线入口完整版 | 亚洲韩国日本 | 97国产亚洲精品第一综合 | 久精品国产欧美亚洲色aⅴ大片 | 777米奇| 国产精品天天在线看 | 国产a在视频线精品视频 | 国产99在线播放免 | 日韩在线一 | 国产69精品| 欧美大片日韩精品 | 区二区网站 | 白丝袜美 | 18黑白丝 | 中字幕视频在线永久在线观看免费 | 无区码一码二码三码 | 噼里啪啦| 韩国理论片在线看 | 成年人免费视频软件 | 日韩vr欧美vr性视频 | h肉动漫在线观看 | 日本黄页网站免费观看 | 色眯眯国产在线播 | 加勒比精品 | 欧美另类69 | 国产三视频在线观看网站 | 中文字幕v亚洲ⅴv天堂 | 日韩在线观看中文字幕一区二区 | 88华人永久免费 | 亚洲精品一区二区三区四区五区 | 77尤物精选在线观看 | 国产高清视频一区免费观看 | 国产一级一区在线一页 | 国产一区二区精品国产一级 | 国产一区二区三区四区五区加勒比 | 日韩在线不卡 | 国内揄拍高清国内精品对白 | 国产国产人免费人成免 | 国产精品九九 | 高清自在线看 | 性爱国产精品福利在线 | 99亚洲国产综合 | 亚洲欧美综合精品成人导航 | 人免费观看在线视频www | 好吊妞人成视频在线观看 | 性猛交╳xxx乱大交 亚洲va在线观看 | 国产白白白在线永久播放 | 精品区2区3区国产 | 国产在线观看aⅴ免费 | 自产视频在线观看 | 国产末成年女噜噜 | 高清一区二区三区视 | 国色天香社区视频免费版 | 国产传媒61精品o | 国产在线观看不卡免费高清 | 日韩电影在线观看视频 | 国产乱伦一区二区三区 | 国产女m视 | 亚洲日本va在线视频观看 | 亚洲一区二区三区四区在线观看 | 欧美一区一区二区 | 国产.欧美一区二区三区 | 国产综合专区一区二区 | 国产精品视频一 | 色爱综合网| 欧美乱强伦xxxx | 精品二区中文字幕播放 | 国产偷伦精品视频 | 午夜视频在线观看国产 | 欧美色哟哟在线 | 国产精品分类在线播放 | 欧美日韩中文综合第一页 | 中文字幕乱码高清免费网站 | 国产人成精品一区二区三区 | 国精产品一区一区三区有限公司 | 999zyz玖| 精品国产午夜福利在线观看蜜月 | 91精品福利在线观看播放 | 欧美另类激情在线观看网站 | 日韩丝袜中文字幕在线观看 | 国产网爆门事件视频在线观看 | 国产尤物一区在线不卡 | 青青河边草高清免费版新闻 | 欧洲一曲二曲三曲视频 | 国产欧美日韩在线 | 国偷自产| 精品国产乱码一区二区三区99 | 日韩精品一区二区三区中文不卡 | 欧美激情视频在线观看 | 国产成年女人 | 日本一区二区三区中文字幕 | 无色码中文字幕亚洲精品 | 国产日产高清欧美一区 | 十九岁中国电影在线观看免费 | 片在线播放 | 国产欧美日韩精品第二区 | 欧美日韩精品视频一区在线观看 | 国产精品欧美激情 | a在线视频播放免费视 | 亚洲欧洲一区二区 | 无限免费资源在线看片 | 99爱免费观看视频在线 | 午夜电影网在 | 国产一级一片免费播放视频 | 韩国日本国产片免费观看 | 欧美亚洲日韩一区 | 亚洲自偷精品视频自拍 | 免费精品一区二区三区第35 | 国产精品亚洲四区在线观看 | 老司机在线精品视频播放 | 国产精品视频色拍拍 | 凹凸国产熟女精品 | 国产精品极品 | 国产伦理精品一区二区三区 | 国产香蕉国产精品偷在线观看 | 日产2025一区在线观看 | 天堂网www中文在线 99热这里只有 | 日韩欧美高清 | 中文字幕在线观看网站 | 亚洲愉拍自拍欧美精品app | 国产精彩乱子真实视频 | 国产对白在 | 免费国产小视频在线观看 | 国产午夜激情视频自拍 | 精品国产福利盛宴在线观看 | 日本中文字幕亚洲东 | 五月桃花网婷婷亚洲综合 | 成人看的羞 | 精品亚洲成a人在线看片 | 中美日韩亚洲中文专区小说 | 欧美影院一区 | 天堂网www天堂网最新版 | 日韩精品专区中文字幕 | 日韩男女在线视频免费观看 | 国99精品| 欧美日韩国产一区二区精品 | 日本免费在线看aⅴ | 四川w搡bbb搡wbbb搡按摩 | aaaaa级少| 亚洲国产精品综合一区在线 | 亚洲欧美激情精品一区二区 | 日本一区二区三区视频在线观看 | 日韩乱码 | 99亚洲精品高清一二区 | 欧美日韩综合aⅴ图片 | 337p日本大胆欧美人术 | 激情亚洲一区国 | 国产又粗又猛又爽视频上 | 国产一区二区三区免费观 | ⅴa在线观看 | 国产激情影视在线 | 国产系列丝袜熟女精品网站 | 400部国产精品偷自产在线 | 欧美日韩国产免费一区在线观看 | 中文字幕国产 | 激烈网站 | 国产欧美日本综合在线 | 欧美日本一道免费一区三区 | 日本中文字幕一区二区高清 | 国产高清成人mv在线观看 | 精品91一区二区三区 | 精新精新国产自在现 | 国产视频一区在线一区在线看 | 精品潘金莲| 又大又粗又黄又硬又爽又免费视 | 九草免费在线观看 | 韩国午夜理 | 国产一级强片在线观看 | 亚洲品质在线观看一区二区 | 影视最全更新最快 | 日韩欧美国产高清亚洲 | 亚洲欧美日韩精品高清 | 日韩成人一区二区三区在线观看 | 国产+欧美+日韩+另类 | 国产欧美日韩精品免费看 | 手机免费在线观看完整版 | 国产拍偷 | 国产免费v片在线观看完整版 | 国内精品一区二区三区最新 | 日韩精品一区二区三区免费在线 | 国产一级自拍亚洲精品在线看 | 91视频国产亚洲精品 | 就去吻亚洲精品国产欧美 | 97在线精品国自产拍中文 | 国产成视频 | 91热国产在线观看 | 国产又黄又爽胸又大免费视频 | 亚洲欧美另类激情综合区蜜芽 | 菠萝菠萝蜜视频在线观看免 | 国产女学生破女初在线观看 | 天美麻花星空视 | 福利资源在线导航网址 | 成人āv专区精 | 成人精品久 | 99热在线免费 | 免费国产不卡一区二区三区 | 亚洲日韩一区二区三区四区高清 | 另类重口 | 久热九九 | 欧美一区二区三区视频在线 | 国产91区精品福利在线社区 | 中文字幕国产在线 | 精品一区二区三区成人精品 | 精品欧美日韩一区二区三区 | 国产全肉乱妇杂乱视频 | 日本免费一区日本一大免费高 | 日韩在线中文 | 欧美在线观看精品免费 | 日韩精品免费一区二区三区 | 日韩丝袜中文字幕在线观看 | 在线观看国产亚洲自拍 | 日本免费不卡高清网站 | 日本视频一区在线播放 | 国产精品伦理在线 | 国产精品欧美日韩一区二区 | 亚洲国产福利一区二区三区 | 国产精品一卡二卡三卡四卡 | 欧美国产精品一级二级三级 | 国产白丝jk学生在线播放 | 8x8ⅹ国产精品一区二区 | 欧美亚洲精品免费高清 | 精品人伦一区二区三区 | 妺妺窝人体色www聚色窝 | 美女aⅴ高清电影在线观看 任你躁在线精 | 国产网站一区二区三区导航 | 7777在线| 国产精品三级国语在线看 | 欧美日韩精品一区二区三区高清 | 日韩a在线播放 | 精品福利私拍 | 日本免费看黄 | 日本剧情片在线播放网站 | 飘雪影院手机免 | 自拍伦理视频一区二区三区 | 电影在线免费高清中文 | 免费1级a做爰片在 | 美女被男人桶到爽免费网站 | 特级西西 | 第四色伊人 | 五十路息与子在线观看 | 呦呦在线观 | 91午夜在线免费观看小视频 | 亚洲人成小说网站色在线观看 | 99re6热在线精品视频观看 | 三年片在线观看免费观看大全 | 国产中文视频一区在线 | 中文字幕在线免费专区 | 亚洲福利中文字幕在线网址 | 国产99视频精品免费观看9 | 区三区夜夜嗨 | 99re6国产精品视频播放 | 欧美性猛交ⅹxxx乱大交 | 日韩在线视频一区中文字幕不卡 | 国产青榴视频在线观看网站 | 自产小说 | 国产激情一区二区小说 | 女日韩优在线 | 欧美日韩深夜视频在线观看 | aⅴ手机看片高清 | 国产精品不卡福利小 | 亚洲欧美日本a∨在线观看 国产精品成人va | 国产精品91一线天 | 奇米视频在线观看 | 日本高清无卡一区二区三区 | 欧美日韩中文字幕一区二区三区 | 日韩国产高清一区二区卡通动漫 | 国产欧美日韩综合精品区一区二区 | 日韩精品在线免费观看 | 亚洲精品视频一卡二卡三卡 | 欧美手机手机在线视频一区 | 欧美aⅴ菲菲影视城视频 | 欧美日韩在线播放 | 日本欧美大码a在线观看 | 性爱国产精品福利在线 | 国产高清不 | 日本动漫在线 | 精品日本一区二区三区在线 | 亚洲国产精品欧美日韩一区二区 | 日产精品一品二品三品 | 排行榜电视剧全集手机免 | 国产欧美日韩精品在线一区 | 国产精品538一区二区在线 | 欧美激情另类专区在线视频 | 欧美阿v高清 | 日本亚洲欧美国产日韩ay | 国产片第一福利片 | 最近最新中文字幕在线第一页 | 国产精品欧美精品aⅴ在线 中文一区二区三 | 九一国产在线视频免观看 | 中奖视频在线观看国产 | 欧美成aⅴ人高清三级 | 日韩成人一区三区 | 成年人免费在线观看视频 | 国产精品美女在线露脸 | 免费91最新地址永久入口 | 国产高清在线a视频在线观看 | 日本精品一区二区 | 日本特级一区二区三区大片 | 国产在线一区二区三区在线 | 国产制服丝袜亚洲高清 | 91极品国产 | 亚洲国语中文字幕理论片 | 欧美日本综合 | 亚洲中文国产综合 | 国产高清专区免费资源网站 | 成人午夜爽爽 | 果冻传媒视频电影 | 国产午夜理论片不卡在线观看 | 愛妃精選)国产视频二区 | 国产亲子| 欧美日韩在线图片一区 | 二区三区99 | 国产精品自在线拍国产手机版 | 菠萝蜜视频在线观看高清 | 日韩在线手机看片免费看 | 好吊操视频这里只有精品 | 国产ā片在线观看免费观看 | 国产老妇伦国产熟女老妇视频 | 国产ts在 | 日韩精品视频在线观看免费 | 精品成人一区二区三区免费视频 | 国产一区二区三区高清在线观看 | 三年在线观看免费大全 | 欧美日韩一区二区一 | 91部国产精品免费观看 | 日韩经典午夜福利发布 | 37pao国产成视频 | 国产一区二区三区在线观看免费 | 午夜韩国理论片在线观看 | 国产黄频在线观看视频 | 欧美交换配乱 | 国产一区二区三区在 | 真实国产日韩欧美全部综合视频 | 欧美成a | 日本在线观看中文字幕无线观看 | 色综合天天综合网 | 最近免费中文字幕大全 | 成人a视频片在线观看免费 极品女神 | 亚洲精品不卡影院 | 麻花天美星空mv免 | 女女中文字幕女同scxc | 国产亚洲精品线观看k频道 大香网伊 | 国产xx| 国产精品视频一区二区三区四 | 视频一区二区三区 | 国产99日韩精品第一页 | 免费国产午夜视频在线 | 国产午夜福利片在线播放老 | 国产精品永久免费视频 | 日本黄页网址在线看免费不卡 | 精品国产午夜理论片不卡 | 免观看在线 | 中文精品久 | 欧美精品第1页www | 中文字幕在亚洲第一在线 | 国产片侵 | 欧美交a欧美精品喷水 | 国产一区二区三区不卡在线 | 国产ts人妖系列 | 在线观看日产一区二区三区 | 人人干97 | 亚洲综合第 | 欧美一级高清在线观看 | a级国产乱理伦片在线播放 夫妻之间免费观看完整版 精品女同 | 最新亚洲国产精品 | 91夜色 | 精品亚洲一区二区三区在线播放 | 国产黄大片在线观看视频 | 九九热这里只有精品在线观看视 | 成人专区一区二区三区四区 | 91精品国产品国语在线不卡 | 综合五月激情二区视频 | 国产中文99视频在线观看 | 午夜国产精品电影在线观看一区 | 成人短视频在线免费观看网站 | 免费高清影视资源观看 | 欧美一区二区三区精品视频在 | 97在线免费视频观看 | 亚洲成年看| 日韩欧美在线视频一区二区 | 亚洲永久精品 | 国产初高中系列视频在线 | 亚洲精品蜜桃 | 717电影秋霞理论片 91丨国产丨 | 欧美专区中文字幕 | 日韩欧美中 | 国产色产综合色产在线观看视频 | 免费国产在线一区二区 | 91精品啪在线观看国产老人令品 | 在线中文字幕亚洲 | 日本欧美一区二区三区免费不卡 | 在线精品99re网 | 国产一区曰韩二区欧美三区 | 日韩中文高清在线专区 | 男女在线观看免费视频公开 | 精品一区在线观看 | 好看的韩剧在线 | 国产盗摄一区二区三区 | 有码+日韩+在线观看 | 亚洲欧美日韩精品色xxx | 成人人免费夜夜视频观看 | 日韩精品精品一区二区三区 | 日本怡春院欧美一区二区三区 | 91大神千人斩| 欧美日韩国产精品自在自线 | 国产一级a毛一级a在线观看 | 欧美精选一区二区三区 | 丁香伊人 | 成人欧美一区二区三区白人 | 日本不卡视 | 日本中文字幕有码在线视频 | 日本免费在线观看视频 | 国产玉足脚交极品在线视频 | 欧洲中文日韩亚洲精品视频 | 军人暴力强伦姧视频 | 日本aⅴ日| 欧美精品自拍一区 | 国产热妇 | 国产xxx69麻| 野花香视频在线观看免费高清版 | 亚洲а∨天堂在线网站 | 日本一本二本在线观看 | 国产精品精品国产一区 | 旋复花7799电影 | 精品欧美日韩在线视频 | 久99国产精品成人欧美日韩 | 国产视频这里只有精品 | 婷婷亚洲久悠悠色在线播放 | 国产精品视频美女在播放 | 日韩欧美在线视频一区二区 | 欧美日韩一区日本成人一区二区 | 国产精品自在线拍国产电影 | 欧美精品色精品一区二区三区 | 欧美精品国产日韩综合在线 | 国产日韩欧美www在线观看 | 影音先锋亚洲综合小说在线 | 精品高清欧美日韩一区 | 男子操性感黑丝美女视频 | 亚洲成色综 | 高清一级做a爱过程不卡视频 | 日本免费精品 | 国产青榴视频在线观看网站 | 欧美日韩专区中文字幕 | 日韩大片免费观看 | 国产又粗又猛又大爽又黄的视频 | 国产户外露出在线观看 | 国产特黄精品一区二区在线 | 日本黄页在线观看免费 | 国产亚洲精品福利在线无卡一 | 亚洲人成在线观看网站播放 | 欧美中文高清日韩 | 亚洲精品在线看 | 日本三级韩国三级美三级91 | 天天射天天爱天天射干 | 国色天香在线观看 | 国产精品丝袜一区二区三区 | 日韩一二三四区永久地址 | 91精品国产手机在线版 | 国自产视频在线观看 | 另类欧美区综合区图片区 | 欧美成本人动漫在线观看 | 日韩国产卡一卡二卡三卡四 | 尤物视频 | 人成黄页在线观看国产 | 99国产在线线 | 国内精品免费久 | 亚洲中文娱乐网在线观看 | 日本欧美一区二区三区在线 | 中文字幕无线码一区2025青青 | 欧美亚洲日韩动漫偷自拍页 | 717午夜伦 | 女人色极品影院 | 国内女人喷潮完整视频 | 最近更新中文字幕2025视频 | 黄+片在线免费观看+精品+巨 | 56prom精品视频在放免费 | 国产乱伦视频 | 日本一区二区三区在线观看网站 | 巨熟乳波霸若妻在线播放 | 星光影院 | www啦啦啦视频在线观看免费 | 片专区成人 | 99国产精品婷婷 | 亚洲精品一区二区三区四区五区 | 国产精品看 | 亚洲一区二区三区视频 | 免费在线| 99视频在线国产 | 中文字幕一区二 | 免费追剧大全 | 91精品丝袜国产在线一区 | 欧美人与牲禽ⅹxxx伦交 | 制服丝袜中 | 国外精品视频在线 | 亚洲一区二区三区四区在线观看 | 欧美午夜片在线观看 | 亚洲无线| 久一在线视频 | 国产一区二区三区免费观看在线 | 性色生活片在 | 91国内揄拍国内精品对白 | 国产精品线在线精品 | 国产一二三四精 | xyx性爽欧美观看 | 97在线免费视频观看 | 视频一区视频二区在线观看 | 国产一区成人 | 国产午夜福利1000我不卡 | 精品一区二区日本高清 | 亚洲一区二区三区视频 | 在线看伦理片 | 国产在线一区二区三区不卡 | 国产经典aⅴ三级观看 | 国产乱码精品一区 | 草草视频在线 | 国产香线蕉手机视频在线观看 | 中文字幕日韩经典 | 精品高清美女精品国产区 | 91拍拍在线观看 | 日产精品卡二卡三卡四卡乱码视频 | 亚洲国产欧美日韩另类 | a级高清观看视频在线看 | 日韩一区二区三区免费高清 | 国产精品网站 | 国产午夜福利a∨在线机视频 | 五十路丰满中年熟女 | 国产午夜福利在线观看1000集 | 五月丁香六月综合 | 九三精品私密视频在线观看 | 国产美女91 | 日韩中文高清一 | 国产在亚洲线视频观看。 | 不卡影片| 亚洲欧美日韩综合在线丁香 | 国产欧美精品在线 | 愛妃)日韩视频在线免费观看 | 久99久热只有精品国产澳门 | 欧美激情一区二区三区高清视 | 欧美亚洲一区电影 | 欧美日韩视费观 | 欧美第一页 | 乱子伦一区二区三区 | 欧美熟女激情视频 | 欧美三级美国一 | 91精品国自产在线观看 | 国产一级三级三级在线视 | 国产美女精品免费视频观看 | 国产亚洲人成a | 日韩极品精品一区二区三区 | 欧美一级大片在线观看 | 欧美国产激情视频一区 | 99热永久地址有精品 | 国产欧美亚洲精品综合在线 | 欧美亚洲日本在线播放 | 欧美三级网址 | 欧美精品18v | 成综合网网站欧美 | 免费观看日本一区二区 | 91精品国产色综 | 在线免费视频一区二区 | 国自产精品手机在线观看 | 亚洲国产一区欧美 | 国产一区二区三区免费观看在线 | 亚洲日韩国产一区二区三区在线 | 国产精彩对白在线91 | 玖玖精品在线观看 |