亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

將struts程序移植到JSF

系統(tǒng) 1580 0

? 將Struts 應(yīng)用程序移植到 JSF

為了將 Struts Web 應(yīng)用程序與 JSF 集成,遵循以下步驟:

  • 將 struts-faces.jar 文件與特定于 JSF 的 JAR(jsf-api.jar、jsf-ri.jar) 添加到 Web 應(yīng)用程序的? WEB-INF/lib 目錄中。?
  • 如果準備使用 JSF 和 JSTL,則將特定于 JSTL 的 JAR(jstl.jar、standard.jar)添加到? WEB-INF/lib ?文件夾中。這一步只有在部署到常規(guī) Tomcat 時才會需要。JWSDP 已經(jīng)提供了這些 JAR。?
  • 修改 Web 應(yīng)用程序部署描述符 (? /WEB-INF/web.xml )以便有一個 Faces Servlet 項, 如清單 5 所示。?
  • 修改 JSP 頁面以使用 JSF 和 Struts-Faces 標記而不是 Struts 標記。特別是用 Struts-Faces 相應(yīng)標記替換? html、b ? ase、 ? form ?和? errors ?標記。用 JSF 相應(yīng)標記替換? text ?、? textarea ?和? radio ?標記。Struts-Faces 沒有單獨針對這些的標記。盡管沒有要求,但是您可能還會考慮用 JSTL 標記替換 Struts Logic 標記。?
  • 對于每一個使用 JSF 標記的 JSP,修改 struts-config.xml 文件以在指向該 JSP 的 Action Mapping 中的? global-forwards 和? local-forwards 中加入前綴? /faces 。?
  • 如果 Web 應(yīng)用程序使用了任何您創(chuàng)建的自定義組件,那么您就需要用 JSF 實現(xiàn)的默認 RenderKit 注冊它們。可以通過在? WEB-INF ?文件中創(chuàng)建一個 faces-config.xml 文件、并增加每一個組件和 renderer 的項做到這一點。不過,要記住 faces-config.xml 文件已經(jīng)綁定在 struts-faces.jar 文件中了。您必須從 struts-faces.jar 文件中提出它、加入自己的內(nèi)容并將它放到? WEB-INF 文件夾中。


清單 5. 在 web.xml 中聲明 FacesServlet

?

<!-- JavaServer Faces Servlet Configuration -->
<servlet >
<servlet-name > faces </servlet-name >
<servlet-class > javax.faces.webapp.FacesServlet </servlet-class >
<load-on-startup > 1 </load-on-startup >
</servlet >

<!-- JavaServer Faces Servlet Mapping -->
<servlet-mapping >
? <servlet-name > faces </servlet-name >
? <url-pattern > /faces/* </url-pattern >
</servlet-mapping >

集成 Struts-Faces 和 Tiles 的挑戰(zhàn)

Struts-Faces 庫提供了 Struts 與 JSF 之間的一個高效的橋梁,使得在 J2EE Web 應(yīng)用程序中擁有豐富的表示層成為現(xiàn)實。您可以通過在組合體中添加 Titles 使表示層更豐富,這樣不僅得到了 Struts 和 JSF 組合的好處,而且還可以高效地重復使用不同的 JSP 頁面,因為它們將由可以根據(jù)需要添加或者刪除的組件部分或者 tiles 所構(gòu)成。

本文已經(jīng)展示了 Struts 和 JSP 的集成,您會想將 Tiles 加入到組合中只是小事一樁,是不是?

不幸的是,JSF 仍然處于早期階段,還沒有給出最后的發(fā)布。基于這一考慮,Struts-Faces 集成軟件開發(fā)仍然在不斷地發(fā)展以包括 JSF 的不同的功能,并且還沒有支持 Tiles。

Struts 和 Tiles 可以無縫地共同工作,但是在集成之路上您會遇到路障。在下面幾小節(jié)中,您會看到在與 Tiles 共同使用 Struts-Faces 集成庫時經(jīng)常遇到的問題的匯總。對于每一個問題,我們詳細說明了一個修改 Struts-Faces 類的解決方案。我們將用一個航班搜索示例解釋這個解決方案。

清單 6 展示了航班搜索頁面的布局。注意我們稱它為航班搜索頁面而不是 FlightSearch.jsp。這是因為 FlightSearch JSP 是用戶在 foobar 旅行 Web 站點看到的合成頁面的主體。

現(xiàn)在,我們保持實際的 FlightSearch.jsp 不變。我們將隨著進展改變它。在您這邊,也需要用航班搜索頁的定義創(chuàng)建一個 Tiles 定義文件。清單 7(緊接著清單 6)展示了 Tiles 定義文件中航班搜索頁的一項。注意對帶有? extends ?屬性的主布局模板的重復使用。

在清單 6 和 7 后是每一個可能的挑戰(zhàn)。


清單 6. 航班搜索例子的 Tiles 布局

?

<%@ taglib uri= "/WEB-INF/struts-tiles.tld" prefix= "tiles" % >
<%@ taglib uri= "http://jakarta.apache.org/struts/tags-faces" prefix= "s" % >

<!-- Layout component parameters: header, menu, body, footer -->
<s :html>
<head>
? <title> <tiles:getAsString name = "title" / > </title>
? <s :base/ >
</head>
<body>
? <TABLE border = "0" width = "100%" cellspacing = "5" >
? ? <tr>
? ? ? <td> <tiles:insert attribute= "header" / > </td>
? ? </tr>

? ? <tr>
? ? ? <td> <tiles:insert attribute= "body" / > </td>
? ? </tr>

? ? <tr> <td> <hr> </td> </tr>

? ? <tr>
? ? ? <td> <tiles:insert attribute= "footer" / > </td>
? ? </tr>
? </TABLE>
</body>
</s :html>
<!-- Master Layout definition? -->
<definition name = "foobar.master-layout"
? path = "/faces/layout/MasterLayout.jsp" >

? ? ? <put name = "title" ? value = "Welcome to Foo Bar Travels" />
? ? ? <put name = "header" value = "/faces/common/header.jsp" />
? ? ? <put name = "footer" value = "/faces/common/footer.jsp" />
? ? ? <put name = "body" ? ? value = "" />
</definition >

? <!-- Definition for Flight Search Page -->
<definition name = "/foobar.flight-search"
? extends = "foobar.master-layout" >

? ? ? <put name = "body" ? ? value = "/faces/FlightSearch.jsp" />
</definition >

響應(yīng)已經(jīng)提交

這是您在試圖訪問航班搜索表單時馬上會看到的第一個問題。小心查看堆棧跟蹤。您會看到問題出在類? com.sun.faces.lifecycle.ViewHandlerImpl ?上。這是一個實現(xiàn)了? ViewHandler ?接口的 JSF-RI 類。

圖 2 展示了? ViewHandler ?所扮演的角色。這是一個將請求轉(zhuǎn)發(fā)給下一頁的類。在轉(zhuǎn)發(fā)請求時,它不在轉(zhuǎn)發(fā)前檢查響應(yīng)的狀態(tài) -- 這只有在使用 Tiles 時才會發(fā)生,因為 Tiles 內(nèi)部將 JSP 頁面包括在響應(yīng)內(nèi),而 JSF-RI 在第一次轉(zhuǎn)發(fā)后提交響應(yīng)、然后試圖再次轉(zhuǎn)發(fā)給下面的包括 JSP 的 Tiles。

要解決這個問題,必須創(chuàng)建一個自定義的? ViewHandler ?實現(xiàn),它將檢查響應(yīng)的狀態(tài)以確定它是否提交過。如果響應(yīng)沒有提交過,那么請求就轉(zhuǎn)發(fā)給下一頁,否則,就加入請求并顯示相應(yīng)的 JSP。我們將創(chuàng)建一個名為? STFViewHandlerImpl ?的類,它實現(xiàn)了? ViewHandler ?接口并實現(xiàn)了所需要的方法? renderView()。 ?清單 8 展示了? STFViewHandlerImpl ?中的? renderView() ?方法:


清單 8. STFViewHandlerImpl 中的 renderView()方法

RequestDispatcher rd = null ;
Tree tree = context. getTree ( ) ;
String requestURI = context. getTree ( ) . getTreeId ( ) ;
rd = request. getRequestDispatcher ( requestURI ) ;

/** If the response is committed, include the resource **/
if ( !response. isCommitted ( ) ) {
? ?rd. forward ( request, context. getServletResponse ( ) ) ;
}
else {
? ?rd. include ( request, context. getServletResponse ( ) ) ;
}

現(xiàn)在您實現(xiàn)了自己的? ViewHandler ?,如何通知 JSF-RI 使用您的? ViewHandler ?而不是默認的實現(xiàn)呢?要回答這個問題,就必須理解? FacesServlet ?的工作過程。

在 Faces 初始化過程中,? FacesServlet ?會讓? LifecycleFactory ?實現(xiàn)返回? Lifecycle ?類的一個實現(xiàn),如清單 9 所示:


清單 9. FacesServlet 中 Faces 的初始化

?

//Get the LifecycleFactory from the Factory Finder
LifecycleFactory factory = ( LifecycleFactory )
? FactoryFinder. getFactory ( "javax.faces.lifecycle.LifecycleFactory" ) ;

//Get the context param from web.xml
String lifecycleID =
getServletContext ( ) . getInitParameter ( "javax.faces.lifecycle.LIFECYCLE_ID" ) ;

//Get the Lifecycle Implementation
Lifecycle lifecycle = factory. getLifecycle ( lifeCycleID ) ;

Lifecycle ?實現(xiàn)對象擁有在呈現(xiàn)響應(yīng)階段要使用的? ViewHandler ?。您可以通過對? Lifecycle ?實現(xiàn)調(diào)用? setViewHandler ?方法讓自己的? ViewHandler ?實現(xiàn)成為默認的。

現(xiàn)在問題變?yōu)槿绾蔚玫侥J? Lifecycle ?實現(xiàn)?回答是不需要這樣做。只要創(chuàng)建一個新的實現(xiàn)并用一個惟一 ID 注冊它,如清單 10 所示:


清單 10. 注冊自定義 ViewHandler 和 Lifecycle

?

//Get the LifecycleFactory from the Factory Finder
LifecycleFactory factory = ( LifecycleFactory )
? FactoryFinder. getFactory ( "javax.faces.lifecycle.LifecycleFactory" ) ;

//Create a new instance of Lifecycle implementation -
//com.sun.faces.lifecycle.LifecycleImpl
//According to the documentation, factory.getLifecycle("STFLifecycle")
//should work, but JSF-RI has a defect.
//Hence this workaround of creating a RI class explicitly.
LifecycleImpl stfLifecycleImpl = new LifecycleImpl ( ) ;

//Create a new instance of our STFViewHandler and set it on the Lifecycle
stfLifecycleImpl. setViewHandler ( new STFViewHandlerImpl ( ) ) ;

//Register the new lifecycle with the factory with a unique
//name "STFLifecycle"
factory. addLifecycle ( "STFLifecycle" , stfLifecycleImpl ) ;
您可以看到? lifecycleId ?硬編碼為? STFLifecycle ?。實際上不是這樣。當您回過頭分析? 清單 9 時就會清楚。? FacesServlet ?從在 web.xml 文件中聲明的上下文參數(shù)中得到名為? javax.faces.lifecycle.LIFECYCLE_ID ?的 lifecycle ID,如下所示:
?? ? <context-param >
? ? ? ? <param-name > javax.faces.lifecycle.LIFECYCLE_ID </param-name >
? ? ? ? <param-value > STFLifecycle </param-value >
? ? </context-param >

因為? FacesServlet ?取決于其初始化時的? Lifecycle ?實現(xiàn),在? 清單 10 中展示的代碼應(yīng)該在? FacesServlet ?初始化之前執(zhí)行。通過創(chuàng)建另一個 servlet 并在? FacesServlet ?之前初始化它而做到這一點。

但是一種更聰明的辦法是實現(xiàn)一個? ServletContextListener ?接口。這個類聲明兩個方法:? contextInitialized() ?和? contextDestroyed() ?,在 Web 應(yīng)用程序被創(chuàng)建及 Web 應(yīng)用程序被銷毀之前會分別調(diào)用它們。因而? 清單 10 中的代碼在? contextInitialized() ?方法中執(zhí)行,而自定義? ViewHandler ?已經(jīng)用標識名? STFLifecycle ?注冊到? Lifecycle ?,并且可被? FacesServlet ?使用。? ServletContextListener ?類本身是在 web.xml 文件中聲明的,如下所示:

<listener >
? <listener-class > foo.bar.stf.application.STFContextListener
? </listener-class >
</listener >

這不是注冊一個帶有自定義? ViewHandler ?的? Lifecycle ?惟一方法。事實上? FactoryFinder ?實現(xiàn)了自己的發(fā)現(xiàn)算法以發(fā)現(xiàn)? Factory ?對象,包括? LifecycleFactory ?。這些機制按照順序包括在系統(tǒng)屬性中查看工廠實現(xiàn)類名的機制、faces.properties file、或者 1.3 Services 發(fā)現(xiàn)機制(? META-INF/services/{factory-class-name} ?)。不過,我們討論的這種機制是最容易的,也是最不具有破壞性的一種。

404 Resource Not Found

在解決了提交響應(yīng)的問題后,單擊任何一個 Tiles 特定的鏈接或者輸入一個會呈現(xiàn) Faces 響應(yīng)的 URL。在這里,可以輸入顯示? FlightSearchForm ?的 URL。

在這樣做了以后,您會得到一個? foobar.flight-search - 404 Resource Not Found ?錯誤。? foobar.flight-search ?是航班搜索頁面的 Tiles 定義的名字。? FacesRequestProcessor ?不能處理 Tiles 請求(因為它擴展的是 RequestProcessor ?而不是? TilesRequestProcessor ?),所以會得到錯誤。

為解決這個問題,我們將創(chuàng)建一個名為? STFRequestProcessor ?(表示? Struts-Tiles-Faces Request Processor )的新的請求處理程序。現(xiàn)在我們將拷貝? FacesRequestProcessor ?的所有代碼到這個新類中。惟一的區(qū)別是? STFRequestProcessor ?繼承的是? TilesRequestProcessor ?而不是繼承常規(guī)的? RequestProcessor ?。這個新的? RequestProcessor ?可以處理 Tiles 請求。清單 11 詳細列出了這個? STFRequestProcessor ?:


清單 11. STFRequestProcessor.java

正如您所知道的,? Struts ?框架的? RequestProcessor ?是在 struts-config.xml 文件中指定的。將下面的項添加到? struts-cinfig.xml? 文件中后,? STFRequestProcessor ?就成為處理程序:

<controller processorClass="foobar.stf.application.STFRequestProcessor" />

表單提交顯示返回同一個表單

由于? STFRequestProcessor ?的作用,這時您就可以瀏覽并查看航班頁面了。不過,在提交航班搜索表單時,您會得到返回來的同一個表單,而且沒有頁頭和頁腳!并且沒有驗證錯誤。事實上,根本就沒有進行驗證!

為了了解到底發(fā)生了什么事情,我們用瀏覽器回到航班頁面并檢查 HTML 源代碼。您會看到像下面這樣的一項:

?

                      
                        <form name="FlightSearchForm" method="post"    action="/flightapp/faces/FlightSearch.jsp">  
                      
                    

?

注意表單 action 是指向 JSP 頁而不是一個? .do ?的。啊哈!這就是問題!這不是由于同時使用 Tiles 和 Struts-Faces 而帶來的新問題,Struts-Faces 的默認行為是讓 JSP 與表單 action 有同樣的名字。這種行為在有單一的 JSP 頁(如在前面的 Struts-Faces 例子中)時沒有問題。? 清單 3 展示了原來的 FlightSearch.jsp,讓我們繼續(xù)并像下面這樣修改 action:

?

                      
                        <s:form action="/listFlights.do> 
                      
                    

?

當然,光有這種修改并不能解決問題。作了這種改變后,您就會發(fā)現(xiàn)? STFRequestProcessor ?不能找到? ActionForm ?。顯然還需要其他的改變。

不過,在繼續(xù)往下之前,看一下圖&#160 5。它顯示了在呈現(xiàn)負責 Struts-Faces 表單的 faces 時相關(guān)的一系列事件。這與? 圖 3 相同,除了在? FormComponent ?中突出顯示的方法? createActionForm()。 ?由 Struts-Faces API 提供的? FormComponent ?類是? javax.faces.component.UIForm ?的特殊子類,它支持請求或者會話范圍的表單 Bean。

圖 5. 呈現(xiàn) Struts-Faces 響應(yīng) ?
單擊這里 以查看該圖。

正如您所看到的,? createActionForm() ?方法使用 action 名以從 Struts 配置文件中得到? ActionMapping ?。因為沒有對于? /listFlights.do ?的? ActionMapping ?,所以 Struts 不能找到? ActionForm。

這個問題的解決方法是使用? org.apache.struts.util.RequestUtils ?。? RequestUtils ?中的 static 方法? getActionMappingName() ?具有足夠的智能解析映射到正確? ActionMapping ?的路徑(? /x/y/z )或者后綴(? .do )。

清單 12 以粗體顯示對? createActionForm ?方法的改變。我們沒有對 Struts-Faces 中的? FormComponent ?作這些改變,而是通過繼承? FormComponent ?并覆蓋? createActionForm()? 方法創(chuàng)建了一個新的? STFFormComponent。


清單 12. FormComponent 中修改過的 createActionForm() 方法

                      
                        // Look up the application module configuration information we need ModuleConfig moduleConfig = lookupModuleConfig(context);  // Look up the ActionConfig we are processing String action = getAction(); String mappingName = RequestUtils.getActionMappingName(action); ActionConfig actionConfig = moduleConfig.findActionConfig(mappingName); .... .... 
                      
                    

?

對新的? STFFormComponent ?還要作一項改變。Struts-Faces 將 action 名本身作為表單名。這需要改變,因為 action 帶有后綴? .do ,而表單名沒有后綴? .do 。所以我們在? STFFormComponent ?上增加一個名為? action 的新屬性,并覆蓋? getAction() ?和? setAction() ?方法。

FormRenderer 的改變

必須對? FormRenderer ?(以 HTML 格式呈現(xiàn) Struts-Faces 表單的類)的? encodeBegin ?方法進行類似于? 清單 10 所示的修改。

同樣,通過繼承? FormRenderer ?做到這一點。此外,還必須改變寫出到 HTML 的表單 action。清單 13以粗體詳細列出了這些改變:


清單 13. FormRenderer 的改變

                      
                        protected String action(FacesContext context, UIComponent component) {      String treeId = context.getTree().getTreeId();     StringBuffer sb = new StringBuffer        (context.getExternalContext().getRequestContextPath());     sb.append("/faces");      // sb.append(treeId); -- This is old code, replaced with      // the two lines below.      STFFormComponent fComponent = (STFFormComponent) component;     sb.append(fComponent.getAction());          return (context.getExternalContext().encodeURL(sb.toString())); } 
                      
                    

?

FormTag 的改變?
正如您已經(jīng)知道的,當組件和 renderer 改變時,標記也必須改變。在這里,通過繼承 Struts-Faces 中的? FormTag ?創(chuàng)建一個新的標記:? STFFormTag ?。不必改變?nèi)魏喂δ埽灰采w? getComponentType() ?和? getRendererType() ?方法。清單 14 展示了從? STFFormComponent ?覆蓋的方法:


清單 14. FormTag 的改變

                      
                        public String getComponentType() {     return ("STFFormComponent"); }  public String getRendererType() {     return ("STFFormRenderer"); }  
                      
                    

?

修改 faces-config.xml 文件

自定義組件和 renderer 必須在 faces-config.xml 文件中聲明,這樣 JSF 框架才可以初始化并使用它們。現(xiàn)在我們已經(jīng)創(chuàng)建了一個新組件? STFFormComponent ?和一個新 renderer? STFFormRenderer ?。

現(xiàn)在我們將在 faces-config.xml 文件中增加一個聲明,如清單 15 所示。? component-class ? 是組件的完全限定類名。? component-type ?指的是在? STFFormTag ?(? 清單 12 )中用于標識組件的名字。以類似的方式發(fā)現(xiàn)和解釋 renderer。注意 faces-config.xml 文件是在 struts-faces.jar 文件中的。從 struts-faces.jar 文件中取出這個文件并將它放到 Web 應(yīng)用程序的? WEB-INF 文件夾中并修改它。


清單 15. 在 faces-config.xml 中聲明自定義組件和 renderer

                      
                        <faces-config>    <!-- Custom Components -->   <component>      <component-type>STFFormComponent</component-type>     <component-class>       foobar.stf.component.STFFormComponent     </component-class>   </component>   ..   ..   ..   <!-- Custom Renderers -->    <render-kit>      <renderer>       <renderer-type>STFFormRenderer</renderer-type>       <renderer-class>         foobar.stf.renderer.STFFormRenderer       </renderer-class>      </renderer>     ..     ..     ..   </render-kit> </faces-config> 
                      
                    

?

修改 struts-faces.tld 文件

您不會在這個示例 Struts-Faces 應(yīng)用程序中看到 struts-faces.tld 文件,它打包到了 struts-faces.jar 文件中。打開并分析這個文件。它聲明了一個名為? org.apache.struts.faces.taglib.LifecycleListener ?的類,這個類實現(xiàn)了? ServletContextListener ?并初始化? FacesRequestProcessor ?。

因為希望使用新的? STFRequestProccessor ?,所以必須將這個文件從 struts-faces.jar 文件中刪除,將它放到 Web 應(yīng)用程序的? WEB-INF ?文件夾中,并刪除偵聽器聲明。如果讓這個 tld 文件保持原樣,那么在初始化這個 Web 應(yīng)用程序時,除了? STFRequestProcessor ?,還會實例化一個? FacesRequestProcessor。

修改 base href 標記?
現(xiàn)在,您已經(jīng)完成了 Struts、Tiles、JSF 集成的最困難的部分了。您甚至可以瀏覽航班搜索頁面,并輸入搜索標準查看航班列表。現(xiàn)在試著從航班列表頁面返回航班搜索表單。您會得到一個 HTTP 400 錯誤。這個錯誤的原因是 HTML? base href ?標記。它被設(shè)置為 Master Layout 頁面。

?

                      
                        <base href=   "http://localhost:8080/stf-example/faces/layout/MasterLayout.jsp" />            |_________|       |_____________________|               Context               Servlet Path 
                      
                    

?

程序所有頁面瀏覽都是相對于布局頁面計算的。如果加入的? base href ?標記只達到 Web 應(yīng)用程序上下文則會很方便,像這樣:

?

                      
                        <base href="http://localhost:8080/stf-example/" />  
                      
                    

?

我們可以通過定制 Struts-Faces? BaseTag ?做到這一點。這個類中的改變相當微不足道。只須在 base href 中去掉? HttpServletRequest.getServletPath() ?。

因為這些改變是與顯示相關(guān)的,所以為它創(chuàng)建了一個名為? STFBaseRenderer ?的新 renderer。這個新標記稱為? STFBaseTag ?,它聲明? STFBaseRenderer ?作為其關(guān)聯(lián)的 renderer。不需要新的組件。

有了這些信息,通過繼承? BaseTag ?并覆蓋? getRendererType ?方法創(chuàng)建新的? STFBaseTag ?,如下所示:

?

                      
                        public String getRendererType() {     return ("STFBaseRenderer"); } 
                      
                    

?

到目前為止所作的改變

恭喜!經(jīng)過這些相對較小的修改,您已經(jīng)成功地集成了 Struts、Tiles 和 JSF,并保留了您以前在這些技術(shù)上所做的所有投資。本文演示了如何將 JSF 強大的前端能力、 Tiles 的內(nèi)容格式編排優(yōu)勢以及 Struts 控制器層的靈活性結(jié)合在一個包中,使得創(chuàng)建一個 J2EE Web 應(yīng)用程序成為一項更容易的任務(wù)。

padding-top: 0px; padding-right: 0px; padding-left: 0px; padding-bottom: 6px; clear: both; text-align: left; margin-top: 0px; margin-right: 0px; marg

分享到:
評論
pokerwen
  • 瀏覽: 30693 次
  • 性別: Icon_minigender_1
  • 來自: 深圳
最近訪客 更多訪客>>
社區(qū)版塊
最新評論

將struts程序移植到JSF


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 奇米777在线 | 99久久亚洲国产高清观看 | 欧美亚洲另类图片 | 国产亚洲福利精品一区二区 | 九九九精品午夜在线观看 | 91aaa免费观看在线观看资源 | 久久精品国产99久久久 | 亚洲婷婷在线视频 | 四虎最新永久免费网址 | 中文字幕曰韩一区二区不卡 | 亚洲精品免费在线观看 | 天天操天天看 | 国产成人a∨麻豆精品 | 手机看片日韩国产一区二区 | 久久综合精品国产一区二区三区无 | 色婷婷在线视频 | 亚洲精品美女久久久aaa | 看全大色黄大色黄大片一级爽 | 日韩欧美亚洲 | 亚洲精品一区二 | 男人手机天堂 | 色九九视频 | 免费骚视频| 亚洲图片在线观看 | 老司机深夜免费福利 | 精品久久久久久中文字幕2017 | 久久福利| 亚洲精品久久久久午夜福 | 草逼综合 | 日韩在线视频一区 | 久久精品国产欧美成人 | 国产三及 | 久草小区二区三区四区网页 | 国产精品日本一区二区不卡视频 | 九九热国产 | 欧美成人性色大片在线观看 | 亚洲国产精品婷婷久久久久 | 一区二区视频免费看 | 99热精品久久 | 91福利社在线观看 | 青青免费视频精品一区二区 |