編寫Play 2的模塊,第2部分:攔截器

在本教程的第一部分中,我們介紹了創建,發布和調用模塊的基本知識。 我們創建的模塊并沒有真正做很多事情,因此現在是時候使用Play的某些功能來擴展功能了。

1.攔截器

攔截器使您可以攔截對控制器的調用,并增強或阻止其行為。 在第一個示例應用程序中,我們向MyLogger添加了顯式調用,以將消息記錄到控制臺。 如果我們擴大規模,并且您想在每個控制器方法調用中都使用這個非常有用的插件,那么您將編寫大量樣板代碼。 攔截器使我們能夠自動應用動作,從而減少樣板。

1.1添加代碼

在app目錄中,創建一個名為action的新程序包。 在這里,我們將添加LogMe注釋,以及將在存在注釋時執行的LogMeAction。

此時,LogMe.java是一個非常簡單的注釋,不帶任何參數

package actions;import play.mvc.With;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @author Steve Chaloner (steve@objectify.be)*/
@With(LogMeAction.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@Inherited
@Documented
public @interface LogMe
{
}

看一下注釋,然后您將看到(LogInAction.class)–這讓Play知道遇到此注釋時,它應該在實際目標之前執行LogInAction。

package actions;import play.mvc.Action;
import play.mvc.Http;
import play.mvc.Result;/*** @author Steve Chaloner (steve@objectify.be)*/
public class LogMeAction extends Action{@Overridepublic Result call(Http.Context context) throws Throwable{System.out.println("MyLogger: " + context.request().path());return delegate.call(context);}
}

這是非常優雅的東西–動作具有LogMe的通用參數類型,該參數類型可以訪問提供給LogMe批注的任何參數。 這使您可以自定義動作的行為。 當我們添加一些額外的功能時,我們將看到這一點。 一旦完成您的代碼(在本例中為System.out的另一個類),然后您將返回proxy.class(context)的結果以恢復正常的執行流程。 同時,如果將@LogMe添加到控制器方法,則操作的路徑將記錄到控制臺; 如果將@LogMe添加到控制器,則對該控制器中任何方法的調用都會導致該路徑記錄到控制臺。

1.2更新Build.scala

由于我們擁有新版本的mylogger,因此我們應該更改版本號。 打開項目/Build.scala并進行更改

val appVersion      = "1.0-SNAPSHOT"

val appVersion      = "1.1"

1.3確保已檢測到您的項目更改

如果您已經在mylogger / project-code中運行Play控制臺,則需要執行“重新加載”以獲取對Build.scala的更改。 如果未打開控制臺,請立即將其打開-更改將在啟動時自動進行。

[mylogger] $ reload
[info] Loading project definition from C:\Temp\mylogger\project-code\project
[info] Set current project to mylogger (in build file:/C:/Temp/mylogger/project-code/)

1.4清理并發布

如前所述,在發布之前進行清理始終是一個好主意,以確保您不會推出任何不應存在的對象。

[mylogger] $ clean
[success] Total time: 0 s, completed Mar 19, 2012 9:17:25 PM
[mylogger] $ publish-local
[info] Packaging /tmp/mylogger/project-code/target/scala-2.9.1/mylogger_2.9.1-
1.1 -sources.jar ...
[info] Done packaging.
[info] Wrote /tmp/mylogger/project-code/target/scala-2.9.1/mylogger_2.9.1- 1.1
 .pom
[info] Updating {file:/tmp/mylogger/project-code/}mylogger...
[info] Done updating.
[info] :: delivering :: mylogger#mylogger_2.9.1;1.1 :: 1.1 :: release ::
Mon Mar 19 21:17:30 CET 2012
[info] Generating API documentation for main sources...
[info] Compiling 3 Java sources to /tmp/mylogger/project-code/target/scala-2.9.1
/classes...
[info]  delivering ivy file to /tmp/mylogger/project-code/target/scala-2.9.1
/ivy- 1.1 .xml
model contains 7 documentable templates
[info] API documentation generation successful.
[info] Packaging /tmp/mylogger/project-code/target/scala-2.9.1/mylogger_2.9.1- 1.1
 -javadoc.jar ...
[info] Done packaging.
[info] Packaging /tmp/mylogger/project-code/target/scala-2.9.1/mylogger_2.9.1- 1.1 .jar ...
[info] Done packaging.
[info]  published mylogger_2.9.1 to /home/steve/development/play/play-2.0/framework
/../repository/local/mylogger/mylogger_2.9.1/ 1.1 /poms/mylogger_2.9.1.pom
[info]  published mylogger_2.9.1 to /home/steve/development/play/play-2.0/framework
/../repository/local/mylogger/mylogger_2.9.1/ 1.1 /jars/mylogger_2.9.1.jar
[info]  published mylogger_2.9.1 to /home/steve/development/play/play-2.0/framework
/../repository/local/mylogger/mylogger_2.9.1/ 1.1 /srcs/mylogger_2.9.1-sources.jar
[info]  published mylogger_2.9.1 to /home/steve/development/play/play-2.0/framework
/../repository/local/mylogger/mylogger_2.9.1/ 1.1 /docs/mylogger_2.9.1-javadoc.jar
[info]  published ivy to /home/steve/development/play/play-2.0/framework/../repository
/local/mylogger/mylogger_2.9.1/ 1.1 /ivys/ivy.xml
[success] Total time: 3 s, completed Mar 19, 2012 9:17:31 PM

請注意,模塊的版本在日志記錄中已更改。 如果仍然看到1.0-SNAPSHOT,請確保在發布之前重新加載了項目!

1.5更新示例應用程序

返回示例應用程序,在project / Build.scala中更改所需的模塊版本

val appDependencies = Seq("mylogger" % "mylogger_2.9.1" % "1.1")

重新加載并運行“依賴項”以確保您具有正確的版本。 現在,您可以更新app / controllers / Application.java以使用以下新代碼:

package controllers;import actions.LogMe;
import play.mvc.Controller;
import play.mvc.Result;
import views.html.index;@LogMe
public class Application extends Controller
{public static Result index(){return ok(index.render("Your new application is ready."));}
}

運行此示例,現在您將看到通過注釋應用的MyLogger輸出。

2.添加了攔截器參數

僅記錄請求的路徑并不是特別有用或令人興奮。 如果應該為每種控制器或控制器方法提供特定的日志消息怎么辦? 在這種情況下,我們需要添加一些參數。

2.1更改注釋簽名

上載action / LogMe.java以使用value()參數-這是默認的注釋參數,因此在使用時無需顯式命名。 該值默認為空字符串,因此如果此處不存在此消息,則可以在操作中提供標準消息。

public @interface LogMe
{String value() default "";
}

在操作中,將繼承的配置字段鍵入通用參數(在本例中為LogMe),并提供對參數的訪問。 更新call(Http.Context)方法以利用此方法。

public Result call(Http.Context context) throws Throwable
{String value = configuration.value();if (value == null || value.isEmpty()){value = context.request().path();}System.out.println("MyLogger: " + value);return delegate.call(context);
}

2.2發布更改

再次重復步驟1.2至1.4,這次將appVersion更改為1.2

2.3更新示例應用程序

像以前一樣,在Build.scala中更新依賴項版本,重新加載并使用“ dependencies”進行確認。 現在,您可以向LogMe批注添加一條消息:

@LogMe("This is my log message")
public class Application extends Controller

運行該應用程序,現在您將在控制臺中看到注釋消息。

[info] play - Application started (Dev)
MyLogger: This is my log message

3.使攔截器交互

現在,您(希望)掌握了這個要訣,我們將加快一點。 在本節中,我們將研究攔截器如何相互交互。 Play首先將攔截器應用于方法,然后應用于控制器,因此,如果在方法和控制器級別都存在相同的注釋,它將執行兩次。 LogMe批注可以同時應用于類級別和方法級別,但是,如果您對整個控制器有一條通用的日志記錄消息,但一種方法需要使用另一條消息,那該怎么辦呢? 另外,我們只希望每次調用一個日志消息。 為此,我們可以使用傳遞給每個動作的上下文。

3.1更新模塊

更新LogMeAction以使其了解以前的調用:

package actions;import play.mvc.Action;
import play.mvc.Http;
import play.mvc.Result;/*** @author Steve Chaloner (steve@objectify.be)*/
public class LogMeAction extends Action{public static final String ALREADY_LOGGED = "already-logged";@Overridepublic Result call(Http.Context context) throws Throwable{Result result;if (context.args.containsKey(ALREADY_LOGGED)){// skip the logging, just continue the executionresult = delegate.call(context);}else{// we're not using the value here, only the key, but this// mechanism can also be used to pass objectscontext.args.put(ALREADY_LOGGED, "");String value = configuration.value();if (value == null || value.isEmpty()){value = context.request().path();}System.out.println("MyLogger: " + value);result = delegate.call(context);}return result;}
}

更新版本號,清理,重新加載和本地發布。

3.2更新示例應用程序

這次,我們將在index方法中添加第二個注釋。 這將覆蓋控制器級別的注釋。 因此,更新Build.scala中的依賴項編號,重新加載并運行。

package controllers;import actions.LogMe;
import play.mvc.Controller;
import play.mvc.Result;
import views.html.index;@LogMe("This is my log message")
public class Application extends Controller
{@LogMe("This is my method-specific log message")public static Result index(){return ok(index.render("Your new application is ready."));}
}

當您訪問http:// localhost:9000時,現在您將在控制臺中看到以下內容:

@LogMe("This is my log message")
[info] play - Application started (Dev)
MyLogger: This is my method-specific log message

4.又是啤酒時間

您現在擁有了支持參數化操作的基礎結構。 請記住,很多東西都可以作為注釋參數傳遞,但是-重要的是-并非所有東西都可以傳遞。 您可能需要為某些任務發揮創造力!

您可以在此處下載完整的源代碼。

參考: Play 2的編寫模塊,第2部分: Objective博客上JCG合作伙伴 Steve Chaloner的攔截器 。


翻譯自: https://www.javacodegeeks.com/2012/04/writing-modules-for-play-2-part-2.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/372908.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/372908.shtml
英文地址,請注明出處:http://en.pswp.cn/news/372908.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

c# ef報錯_C# EF調用MySql出現“未將對象引用設置到對象的實例”錯誤解決方案

C# EF調用MySql出現“未將對象引用設置到對象的實例”錯誤解決方案---修改步驟---1.打開Nuget管理包,把Mysql.Data替換為6.10.0以下任意版本。這里選擇的是6.8.82.修改完畢后,繼續把Mysql.Data.Entity也修改為對應版本6.8.8。3.安裝完成后可以看到App.Co…

js格式化時間

Date.prototype.format function(fmt) {var o { "M" : this.getMonth()1, //月份 "d" : this.getDate(), //日 "h" : this.getHours(), //小時 "m" : this.getMinu…

PHP---函數

一.函數定義的四個要素 返回類型,函數名,參數列表,函數體 //1.最簡單的定義方式/*function show(){ echo "hello";}show();*///2.有參數的函數定義/*function show($a){ echo $a;}show("bbbbb");*///3.有默認值的函數定義…

ServletRequest startAsync()的有用性有限

前段時間我遇到了Servlet 3.0中AsyncContext.start(…)的目的是什么? 題。 引用上述方法的Javadoc : 使容器調度線程(可能從托管線程池中)運行指定的Runnable 。 提醒大家, AsyncContext是Servl…

mysql所支持的比較運算符_mysql比較運算符有哪些?Mysql比較運算符詳解

比較運算符可用于比較數字和字符串。今天發一篇Mysql比較運算符詳解,希望對初學者有所幫助,雖然現在流行NoSQL,但是MYSQL還是很有用的,數字作為浮點值進行比較,字符串以不區為例進行比較,運算符用于比較表達…

數據結構0類模板的使用

類模板的使用 #include <iostream> #include <conio.h> #include <string> #define N 3 using namespace std;template <class numtype> class Swap{public :Swap(numtype a,numtype b){xa;yb;}numtype ___(){tempx;xy;ytemp;return x;}//testnumtype …

JavaScript 函數

函數 由于JavaScript的函數也是一個對象&#xff0c;所以類似function abs(v){}函數實際上是一個函數對象&#xff0c;而函數名abs可以視為指向該函數的變量。 因此&#xff0c;第二種定義函數的方式如下&#xff1a; var abs function (x) {if (x > 0) {return x;} else {…

Http Invoker的Spring Remoting支持

Spring HTTP Invoker是Java到Java遠程處理的重要解決方案。 該技術使用標準的Java序列化機制通過HTTP公開服務&#xff0c;并且可以被視為替代解決方案&#xff0c;而不是Hessian和Burlap中的自定義序列化。 而且&#xff0c;它僅由Spring提供&#xff0c;因此客戶端和服務器應…

mysql 日期列表_MySQL 生成日期表

1、創建一個num表&#xff0c;用來存儲數字0~9CREATE TABLE num (i int);2、在num表中生成0~9INSERT INTO num (i) VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);3、生成一個存儲日期的表&#xff0c;datalist是字段名CREATE TABLE if not exists calendar(dateli…

學習后綴自動機想法

小序&#xff1a;學習后綴自動機是要有耐心的&#xff0c;clj的論文自己看真心酸爽&#xff01;&#xff08;還是自己太弱&#xff0c;ls&#xff0c;oyzx好勁啊&#xff0c;狂膜不止&#xff09; 剛剛在寫博客之前又看了篇論文&#xff0c;終于看懂了&#xff0c;好開心 正文&…

【BZOJ】3575: [Hnoi2014]道路堵塞

題目鏈接&#xff1a;http://www.lydsy.com/JudgeOnline/problem.php?id3575 大概的做法是&#xff0c;按照順序枚舉每一條要刪去的邊&#xff0c;(假設當前點為$u$&#xff0c;在最短路徑上的下一個點是$v$)然后強制不走${u->v}$這條邊&#xff0c;將$u$入隊&#xff0c;做…

結合使用slf4j和Logback教程

在當前文章中&#xff0c;我將向您展示如何配置您的應用程序以使用slf4j和logback作為記錄器解決方案。 Java簡單日志記錄外觀&#xff08;slf4j&#xff09;是各種日志記錄框架的簡單外觀&#xff0c;例如JDK日志記錄&#xff08;java.util.logging&#xff09;&#xff0c;lo…

mysql 分組top_MySQL:如何查詢出每個分組中的 top n 條記錄?

問題描述需求&#xff1a;查詢出每月 order_amount(訂單金額) 排行前3的記錄。例如對于2019-02&#xff0c;查詢結果中就應該是這3條&#xff1a;解決方法MySQL 5.7 和 MySQL 8.0 有不同的處理方法。1. MySQL 5.7我們先寫一個查詢語句。根據 order_date 中的年、月&#xff0c;…

ACM第四站————最小生成樹(普里姆算法)

對于一個帶權的無向連通圖&#xff0c;其每個生成樹所有邊上的權值之和可能不同&#xff0c;我們把所有邊上權值之和最小的生成樹稱為圖的最小生成樹。 普里姆算法是以其中某一頂點為起點&#xff0c;逐步尋找各個頂點上最小權值的邊來構建最小生成樹。 其中運用到了回溯&#…

利用jenkins的api來完成相關工作流程的自動化

[本文出自天外歸云的博客園] 背景 1. 實際工作中涉及到安卓客戶端方面的測試&#xff0c;外推或運營部門經常會有很多的渠道&#xff0c;而每個渠道都對應著一個app的下載包&#xff0c;這些渠道都記錄在安卓項目下的一個渠道列表文件中。外推或運營部門經常會有新的渠道產生&a…

擁有成本分析:Oracle WebLogic Server與JBoss

Crimson Consulting Group 撰寫的非常有趣的白皮書 &#xff0c;比較了Weblogic和JBoss之間的擁有成本 。 盡管JBoss是免費的&#xff0c;但該白皮書卻嚴肅地宣稱&#xff0c;從長遠來看&#xff0c;Weblogic更便宜。 盡管此研究是由Oracle贊助的&#xff0c;但它看起來非常嚴肅…

mysql limit 分頁 0_Mysql分頁之limit用法與limit優化

Mysql limit分頁語句用法與Oracle和MS SqlServer相比&#xff0c;mysql的分頁方法簡單的讓人想哭。--語法&#xff1a;SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset--舉例&#xff1a;select * from table limit 5; --返回前5行select * from table limit 0…

與硒的集成測試

總覽 我已經使用了一段時間&#xff0c;遇到了一些似乎可以使生活更輕松的事情。 我以為可以將其作為教程分享&#xff0c;所以我將向您介紹這些部分&#xff1a; 使用Maven設置Web項目&#xff0c;配置Selenium以在CI上作為集成測試運行 尋找使用“頁面對象”為網站中的頁面…

linux每天一小步---sed命令詳解

1 命令功能 sed是一個相當強大的文件處理編輯工具&#xff0c;sed用來替換&#xff0c;刪除&#xff0c;更新文件中的內容。sed以文本行為單位進行處理&#xff0c;一次處理一行內容。首先sed吧當前處理的行存儲在臨時的緩沖區中&#xff08;稱為模式空間pattern space&#xf…

mysql trace工具_100% 展示 MySQL 語句執行的神器-Optimizer Trace

在上一篇文章《用Explain 命令分析 MySQL 的 SQL 執行》中&#xff0c;我們講解了 Explain 命令的詳細使用。但是它只能展示 SQL 語句的執行計劃&#xff0c;無法展示為什么一些其他的執行計劃未被選擇&#xff0c;比如說明明有索引&#xff0c;但是為什么查詢時未使用索引等。…