2011-11-17 8 views
5

Nigdzie tego nie znalazłem - czy mogę powiedzieć Play! że konkretna metoda kontrolera powinna być (tylko) dostępna za pośrednictwem HTTP POST?Czy mogę oznaczyć metodę kontrolera jako POST w Play przy użyciu adnotacji?

Coś jak HttpPost attribute w C# Asp.Net MVC?

public class MyController extends Controller { 

    @Post 
    public void addPerson(String name, String address) { 
    } 
} 

Aktualizacja - Nie rozumiem, co dodanie trasy POST zrobić:

  1. żądanie POST będzie działać bez dodawania taką trasę.
  2. Ponieważ metoda jest nadal przechwytywana przez regułę GET "Catch all", nawet dodanie trasy POST nie zapobiegnie żądaniom GET dla tej metody.
+0

Musisz usunąć * catch all, jeśli chcesz, aby twoja metoda była dostępna tylko poprzez POST. To wszystko powinno zostać wykorzystane do rozwoju. Pomaga także dokładnie zobaczyć, co ujawniasz! – mericano1

+0

@ mericano1 - catch all jest świetny do naśladowania idiomu Konwencja nad konfiguracją, nie sądzę, że jest to złe dla produkcji (w przeciwnym razie po prostu powielę listy kontrolerów/działań tam ... więcej konserwacji). Chyba przedłożę prośbę o funkcję. – ripper234

+0

Wysłano zgłoszenie: https://play.lighthouseapp.com/projects/57987-play-framework/tickets/1260-ability-to-mark-controller-methods-as-post-by-annotation – ripper234

Odpowiedz

1

Można zrobić to w ten sposób:

public static void onlyPost() { 
    if (request.method.equals("POST")) { 
    // ... Do stuff 
    render(); 
    } 
    else 
    forbidden(); 
} 

Należy jednak pamiętać, że kod i plik trasy może być zsynchronizowane.

Możesz również użyć kodu Groovy wewnątrz pliku tras, więc nie musisz duplikować.

# Catch all 
#{if play.mode.isDev()} 
* /{controller}/{action}  {controller}.{action} 
#{/if} 
+0

Chłodno o groovy w trasach - ale to poza tym punktem - Potrzebuję kodu do pracy w Prod, nie tylko Dev. – ripper234

+0

Przyjmuję twoją odpowiedź, ponieważ jest to kolejna najlepsza rzecz do tego, co chciałem - ale proszę zobacz problem, który otworzyłem o zaznaczeniu tego z adnotacją - https://play.lighthouseapp.com/projects/57987-play-framework/ tickets/1260-skill-to-mark-controller-methods-as-post-by-adnotacja – ripper234

+0

Powyższy kod Groovy wyłącza blokadę w Prod, implementuje to, co sugerował @ mericano1. Ale zobaczmy, czy akceptują twój bilet. Jakiej odpowiedzi HTTP oczekujesz, gdy ktoś uzyska dostęp do Twojego działania przy użyciu niewłaściwej metody? –

2

Można to zrobić w pliku trasach:

POST /person/add MyController.addPerson 

Jest bardziej dokumentacja na ten here.

+0

Widziałem tę opcję, ale czuje się trochę niezręcznie. Ponadto, nawet jeśli dodaję tę trasę, ta metoda będzie również odpowiadać na żądania GET, ponieważ będzie pasować do domyślnej trasy "Catch all". Czy planuje się zezwolić na ustawienie tej wartości za pomocą adnotacji? Czy powinienem wysłać żądanie funkcji? – ripper234

+0

Zobacz moje zaktualizowane pytanie. – ripper234

2

Jestem trochę spóźniony na imprezę. AFAIK nie ma zbudowany w adnotacji, ale można dość łatwo napisać samemu:

adnotacje/HttpMethod.java

/** 
* Add this annotation to your controller actions to force a get/post request. 
* This is checked in globals.java, so ensure you also have @With(Global.class) 
* in your controller 
*/ 
@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD) 
public @interface HttpMethod{ 
    String method() default "POST"; 
} 

controllers/Global.java

/** 
* All the funky global stuff ... 
*/ 
public class Global extends Controller{ 

    @Before 
    public static void before(){ 
     if(getActionAnnotation(HttpMethod.class) != null){ 
      HttpMethod method = getActionAnnotation(HttpMethod.class); 
      if(!method.method().equals(request.method)){ 
       error("Don't be evil! "); 
      } 
     } 
    } 
} 

wykorzystania: kontrolerów /Admin.java

@With({Global.class, Secure.class}) 
public class Admin extends Controller { 
    @HttpMethod(method="POST") 
    public static void save(MyModel model){ 
     // yey... 
    } 
}