2011-11-17 9 views
5

Non ho trovato questo ovunque - posso dire Play! che un metodo specifico del controllore dovrebbe (solo) essere accessibile tramite HTTP POST?Posso contrassegnare un metodo di controllo come POST in riproduzione usando le annotazioni?

Qualcosa come lo HttpPost attribute in Asp.Net MVC di C#?

public class MyController extends Controller { 

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

Aggiornamento - Non capisco che cosa l'aggiunta di un percorso POST fare:

  1. richiesta Un POST funziona senza l'aggiunta di un tale percorso.
  2. Poiché il metodo viene ancora catturato dalla regola GET "Catch all", anche l'aggiunta della route POST non impedirà le richieste GET a questo metodo.
+0

È necessario rimuovere * catch all se si desidera accedere al metodo solo tramite POST. Quello che cattura tutto dovrebbe essere usato solo per lo sviluppo comunque. Aiuta anche a vedere esattamente cosa stai esponendo! – mericano1

+0

@ mericano1: il catch all è ottimo per seguire l'idioma della Convenzione rispetto alla configurazione, non penso che sia dannoso per la produzione (altrimenti mi limiterò a duplicare gli elenchi di controller/azioni lì ... più manutenzione). Immagino che invierò una richiesta di funzionalità. – ripper234

+0

Pubblicato un ticket: https://play.lighthouseapp.com/projects/57987-play-framework/tickets/1260-ability-to-mark-controller-methods-as-post-by-annotation – ripper234

risposta

1

che si possa fare in questo modo:

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

Ma tenere a mente che il codice e il file percorsi potrebbero essere fuori sincrono.

Inoltre, è possibile utilizzare il codice Groovy all'interno del file di percorsi, quindi non è necessario duplicare.

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

Fantastico per le rotte - ma non è questo il punto - ho bisogno del codice per lavorare in Prod, non solo Dev. – ripper234

+0

Accetterò la tua risposta perché questa è la prossima cosa migliore per quello che volevo - ma per favore vedi il problema che ho aperto riguardo a ciò con un'annotazione - https://play.lighthouseapp.com/projects/57987-play-framework/ biglietti/1260-abilità-marcatore-controllore-metodi-come-post-per-annotazione – ripper234

+0

Il codice Groovy sopra disattiva il catch all in Prod, implementa ciò che @ mericano1 suggerisce. Ma vediamo se accettano il tuo biglietto. Quale risposta HTTP ti aspetti quando qualcuno accede alla tua azione con il metodo sbagliato? –

2

A tale scopo, nel file rotte:

POST /person/add MyController.addPerson 

V'è di più documentazione su questo here.

+0

Ho visto questa opzione, ma sembra un po 'imbarazzante. Inoltre, anche se aggiungo questa rotta, questo metodo risponderà anche alle richieste GET, perché corrisponderà alla rotta predefinita "Catch all". Ci sono piani per consentire l'impostazione tramite un'annotazione? Devo inviare una richiesta di funzionalità? – ripper234

+0

Vedere la mia domanda aggiornata. – ripper234

2

Sono un po 'in ritardo per la festa. afaik non c'è built in annotazione, ma si può facilmente scrivere uno voi stessi:

annotazioni/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"; 
} 

controllori/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! "); 
      } 
     } 
    } 
} 

di utilizzo: controllori /Admin.java

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