1. 程式人生 > >play框架05--控制層--action、攔截器

play框架05--控制層--action、攔截器

5.4Action鏈

  Play中的Action鏈與Servlet API中的forward不盡相同。Play的每次HTTP請求只能呼叫一個Action,如果需要呼叫其他的Action,那麼必須將瀏覽器重定向到相應的URL。在這種情況下,瀏覽器的URL始終與正在執行的Action保持對應關係,使得後退、前進、重新整理操作更加清晰。

      呼叫控制器中其他Action方法也可以實現重定向,框架會攔截該呼叫並生成正確的HTTP重定向。具體實現如下:

public class Clients extends
Controller {
 
   
public static void show(Long id) {
       
Client client = Client.findById(id);
        render
(client);
   
}
 
   
public static void create(String name) {
       
Client client = new Client
(name);
        client
.save();
        show
(client.id);
   
}
}

      相應的路由規則定義如下:

GET            /clients/{id}                              
Clients.show
POST          
/clients                                   Clients.create

      按照定義,Action鏈的生命週期為:

  • 瀏覽器向/clients傳送POST請求;
  • 路由器呼叫Clients控制器中的create方法;
  • create方法直接訪問show方法;
  • Java呼叫被攔截,路由器逆向生成帶有id引數的URL來呼叫Clients.show;
  • HTTP響應重定向為:/clients/3132;
  • 瀏覽器位址列中URL展現為:/clients/3132;


5.5、攔截器


    控制器中可以定義攔截方法(也可稱之為攔截器),為控制器及其子類的所有Action提供服務。當所有的Action都需要進行通用的處理時,該功能就顯得非常有用:比如驗證使用者的合法性,載入請求範圍內的資訊等。

      讀者在使用時需要注意的是,這些攔截器方法不能定義為public,但必須是static,並通過有效的攔截標記進行註解。


5.5.1 @Before#

      使用@Before註解的方法會在每個Action呼叫之前執行。如建立具有使用者合法性檢查的攔截器:

public class Admin extends Application {
 
   
@Before
   
static void checkAuthentification() {
       
if(session.get("user") == null) login();
   
}
 
   
public static void index() {
       
List<User> users = User.findAll();
        render
(users);
   
}
 
   
...
 
}

      如果不希望@Before註解攔截所有的Action方法,那麼可以使用unless引數列出需要排除的方法:

public class Admin extends Application {
 
   
@Before(unless="login")
   
static void checkAuthentification() {
       
if(session.get("user") == null) login();
   
}
 
   
public static void index() {
       
List<User> users = User.findAll();
        render
(users);
   
}
 
   
...
 
}

      或者直接使用only引數把需要攔截的方法列舉出來:

public class Admin extends Application {
 
   
@Before(only={"login","logout"})
   
static void doSomething() {  
       
...
   
}
   
...
}

      unless和only引數對@After,@Before以及@Finally註解都適用。


5.5.2 @After#

      使用@After註解的方法會在每個Action呼叫之後執行:

public class Admin extends Application {
 
   
@After
   
static void log() {
       
Logger.info("Action executed ...");
   
}
 
   
public static void index() {
       
List<User> users = User.findAll();
        render
(users);
   
}
 
   
...
 
}


5.5.3 @Catch#

      如果有Action方法丟擲了異常,那麼使用@Catch註解的方法就會執行,且丟擲的異常會以引數的形式傳遞到@Catch註解的方法中。具體實現如下:

public class Admin extends Application {
       
   
@Catch(IllegalStateException.class)
   
public static void logIllegalState(Throwable throwable) {
       
Logger.error("Illegal state %s…", throwable);
   
}
   
   
public static void index() {
       
List<User> users = User.findAll();
       
if (users.size() == 0) {
           
throw new IllegalStateException("Invalid database - 0 users");
       
}
        render
(users);
   
}
}

      使用@Catch註解和普通的Java異常處理程式一樣,捕獲父類往往可以獲得更多的異常型別。如果擁有多個需要捕獲的方法,可以通過指定優先順序來確定他們的執行順序。具體實現如下:

public class Admin extends Application {
 
   
@Catch(value = Throwable.class, priority = 1)
   
public static void logThrowable(Throwable throwable) {
       
// Custom error logging…
       
Logger.error("EXCEPTION %s", throwable);
   
}
 
   
@Catch(value = IllegalStateException.class, priority = 2)
   
public static void logIllegalState(Throwable throwable) {
       
Logger.error("Illegal state %s…", throwable);
   
}
 
   
public static void index() {
       
List<User> users = User.findAll();
       
if(users.size() == 0) {
           
throw new IllegalStateException("Invalid database - 0 users");
       
}
        render
(users);
   
}
}


5.5.4 @Finally#

      @Finally註解的方法總是在每個Action呼叫之後執行(無論Action是否成功執行):

public class Admin extends Application {
 
   
@Finally
   
static void log() {
       
Logger.info("Response contains : " + response.out);
   
}
 
   
public static void index() {
       
List<User> users = User.findAll();
        render
(users);
   
}
 
   
...
 
}

      如果@Finally註解的方法中包含的引數是可丟擲的異常,其方法中的內容還是可以繼續執行的,具體如下:

public class Admin extends Application {
 
   
@Finally
   
static void log(Throwable e) {
       
if( e == null ){
           
Logger.info("action call was successful");
       
} else{
           
Logger.info("action call failed", e);
       
}
   
}
 
   
public static void index() {
       
List<User> users = User.findAll();
        render
(users);
   
}
   
...
}


5.5.5 使用@with註解增加更多攔截器

相關推薦

play框架05--控制--action攔截

5.4Action鏈   Play中的Action鏈與Servlet API中的forward不盡相同。Play的每次HTTP請求只能呼叫一個Action,如果需要呼叫其他的Action,那麼必須將瀏覽器重定向到相應的URL。在這種情況下,瀏覽器的URL始終與正在執行的Action保

play框架05--控制--結果返回

5.3結果返回    Action方法需要對客戶端作出HTTP響應,最簡單的方法就是傳送結果物件。當物件傳送後,常規的執行流程就會中斷。以下面這段程式碼為例,最後一句System.out.println的輸出不會被執行: public static void show(

play框架05--控制

5.1、概述   Play的控制層位於應用的controllers包中,其中的Java類即為控制器(Controller)。如圖4.1所示,Application.java和MyController.java都屬於控制層。 (圖4.1 控制器為controllers包中的Jav

05攔截與檔案上傳

Interceptor implements Interceptor extends AbstractInterceptor 與filter的區別:先過filter再過interceptor 檔案上傳: 三種上傳方案 虛擬路徑與真實路徑 /upload copyFile與copydire

java spring框架控制接收日期型別資料,出現403,接收不到等問題

總結的兩個日期接收器 一 :前端傳字串型別日期 條件:只會接收到 指定型別 日期yyyy-MM-dd可以按自己想的 寫 @InitBinder protected void initBinder(WebDataBinder binder) { binder.registerCustom

Java框架(十五)之springMVC(檔案上傳攔截

一、jackson @RequestBody/ @ResponseBody處理Json資料 作用: @RequestBody註解用於讀取http請求的內容(字串),通過springmvc提供的HttpMessageConverter介面將讀到的內容轉換為json

MVC控制struts1struts2springmvc

1)  客戶端初始化一個指向Servlet容器(例如Tomcat)的請求。2)  這個請求經過一系列的過濾器(Filter)。3)  接著FilterDispatcher被呼叫,FilterDispatcher詢問ActionMapper來決定這個請是否需要呼叫某個Action。4)  如果ActionMap

一句話總結,什麼是許可權控制(即登入控制攔截

許可權控制(即登入控制),就是判斷使用者請求的資源(即發起一個http url請求http://127.0.0.1:8080/testProject/authuser/add)是否合法: 如果合法,就,雖然一樣會被攔截器攔截,但是不被攔截到其他http url(即讓使用者去

Springmvc異常攔截格式轉換國際化處理配置文件以及java類

2.3 gin ltm erb nal ges contex utf on() 1.springmvc配置文件自動註解設置。 <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.sp

關於攔截與過濾器使用場景攔截與過濾器的區別整理

body fcm 選擇符 spf java ee 彈性 javaee 定義 asp 過濾器在web.xml中配置: (1)因為一開始在過濾器中映射的url-pattern填寫路徑是*.action。所有的action要經過它的過濾。<url-pattern>*.

Spring MVC溫故而知新 – 參數綁定轉發與重定向異常處理攔截

單獨 UC exclude require 加載 pre buffered nts 節點 請求參數綁定 當用戶發送請求時,根據Spring MVC的請求處理流程,前端控制器會請求處理器映射器返回一個處理器,然後請求處理器適配器之心相應的處理器,此時處理器映射器會調用Spr

過濾器攔截AOP切面執行順序的比較

過濾器:基於 Servlet,通過函式回撥方式實現,可以過濾請求和圖片檔案等,每個請求一個過濾器只能過濾一次。   攔截器:基於 java 的反射機制,代理模式實現,只能攔截請求,可以訪問上下文等物件,功能強大,一個請求可多次攔截。   攔截器是 Spring 中

spring中過濾器(filter)攔截(interceptor)和切面(aop)的執行順序

1.程式執行的順序是先進過濾器,再進攔截器,最後進切面。注意:如果攔截器中preHandle方法返回的為false時,則無法進入切面,例子如下 @RestController @RequestMapping("/user") public class UserController {

MyBatis分頁功能的實現(陣列分頁sql分頁攔截,RowBounds分頁)

前言:學習hibernate & mybatis等持久層框架的時候,不外乎對資料庫的增刪改查操作。而使用最多的當是資料庫的查詢操

過濾器監聽器攔截各自的應用場景

過濾器 監聽器 public interface HttpSessionListener extends EventListener { public void sessionCreated ( HttpSessionEvent se );

為springmvc設定servelet攔截(interceptor)監聽器(listener)過濾器(filter),型別轉換

1.攔截器<mvc:interceptors>   <!-- 登入攔截器 -->   <mvc:interceptor>    <mvc:mapping path="/**" /> <

SpringBoot | 第七章:過濾器監聽器攔截

前言 在實際開發過程中,經常會碰見一些比如系統啟動初始化資訊、統計線上人數、線上使用者數、過濾敏高詞彙、訪問許可權控制(URL級別)等業務需求。這些對於業務來說一般上是無關的,業務方是無需關係的,業務只需要關係自己內部業務的事情。所以一般上實現以上的功能,都會或多或少的

責任鏈設計模式(過濾器攔截

在閻巨集博士的《JAVA與模式》一書中開頭是這樣描述責任鏈(Chain of Responsibility)模式的:   責任鏈模式是一種物件的行為模式。在責任鏈模式裡,很多物件由每一個物件對其下家的引用而連線起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個物件決定處理

Javaweb中過濾器監聽器攔截的區別

轉載自:https://blog.csdn.net/x_yp/article/details/6358630 1.過濾器 Servlet中的過濾器Filter是實現了javax.servlet.Filter介面的伺服器端程式,主要的用途是過濾字元編碼、

SSM框架——springmvc檔案上傳和攔截

檔案上傳 1.檔案上傳前提 form表單的enctype取值必須是:mutipart/form-data(預設值是:application/x-www-form-urlencoded) method屬性取值必須是Post 提供一個檔案選擇域 2.使用 Commo