2011-11-17 6 views
5

No encontré esto en ninguna parte, ¿puedo decir Play! que un método de controlador específico debe (solo) accederse a través de HTTP POST?¿Puedo marcar un método de controlador como POST en Play usando anotaciones?

Algo como el HttpPost attribute en Asp.Net MVC de C#?

public class MyController extends Controller { 

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

actualización - No entiendo lo que la adición de una ruta Postdo:

  1. petición UN POST funcionará sin la adición de tal ruta.
  2. Debido a que el método todavía está atrapado por la regla GET "Catch all", incluso agregar la ruta POST no evitará las solicitudes GET a este método.
+0

Debe eliminar * catch all si desea que se acceda a su método solo a través de POST. De todos modos, eso solo debería usarse para el desarrollo. ¡También lo ayuda a ver exactamente lo que está exponiendo! – mericano1

+0

@ mericano1 - todo es genial para seguir el modismo de Convención sobre Configuración, no creo que sea malo para la producción (de lo contrario, simplemente duplicaré las listas de controladores/acciones allí ... más mantenimiento). Supongo que enviaré una solicitud de función. – ripper234

+0

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

Respuesta

1

Usted puede hacerlo de esta manera:

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

Pero hay que tener en cuenta que su código y su archivo de rutas podrían estar fuera de sincronía.

Además, puede usar el código Groovy dentro del archivo de rutas, por lo que no es necesario duplicarlo.

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

Genial por las rutas geniales, pero eso es más que el punto: necesito el código para trabajar en Prod, no solo Dev. – ripper234

+0

Aceptaré su respuesta porque es la mejor opción para lo que quería, pero vea el problema que abrí sobre marcar esto con una anotación: https://play.lighthouseapp.com/projects/57987-play-framework/ tickets/1260-ability-to-mark-controller-methods-as-post-by-annotation – ripper234

+0

El código de Groovy anterior desactiva el catch all en Prod, implementa lo que @ mericano1 sugirió. Pero veamos si aceptan tu boleto. ¿Qué respuesta HTTP esperas cuando alguien accede a tu acción con el método equivocado? –

2

Esto se hace en el archivo de rutas:

POST /person/add MyController.addPerson 

Hay más documentación sobre este here.

+0

Vi esta opción, pero se siente un poco incómodo. Además, incluso si agrego esta ruta, este método también responderá a las solicitudes GET, ya que coincidirá con la ruta predeterminada "Catch all". ¿Existen planes para permitir establecer esto mediante una anotación? ¿Debo presentar una solicitud de función? – ripper234

+0

Ver mi pregunta actualizada. – ripper234

2

llego un poco tarde a la fiesta. que yo sepa no hay ninguna está construido en anotación, pero se puede escribir muy fácilmente uno mismo:

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

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

de uso: controladores /Admin.java

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