2

I've been going through the Play! 2.1 example to setup a basic login system following the ZenTasks example. Where I get stuck is the JavaForms part. I want to validate the login request using an instance of an auth service that is provided via Guice DI.

I'm following Play20 Sample. This example uses a static authenticate() method to run the authentication when form validation is requested after form submission. Any thoughts on how to perform this validation step in a non-static scope?

Note: I have looked at the Play! Authenticate plugin as well as the SecureSocial plugin, however those projects are overkill for what I want to do right now. Also, I am interested in a general solution for allowing non-static validation in JavaForms.

Edit: It seems there is some confusion about what I am asking for here. What I am hoping to find is an alternate way to perform the validation step of the form submission that is sent by a Play! framework Form.form() generated form. Currently it requires that a validate() method be called on an instance of a POJO which is not created through the DI framework. This results in static references being required to access authorization services etc...

Edit 2: The current solution I am working with is this:

public static class AuthServiceFormReference {
    @Inject
    public static Provider<AuthService> authService;        
}

// In my auth module configure()
//...
    requestStaticInjection(AuthController.AuthServiceFormReference.class);
//...

public static class Login {
    @Required
    public String email;
    @Required
    public String password;

    public String validate(){
        if(AuthServiceFormReference.authService.get().authenticateAdmin(email, password) == null) {
            return "Invalid user or password";
        }
        return null;
    }
}

It's an okay workaround, but it still relies on static injection :(

torbinsky
  • 1,450
  • 10
  • 17

2 Answers2

0

Play Framework does not offer Dependency Injection out of the box. However you can integrate it with Guice or Spring. As a lazy developer you could also create a Singleton for the service, or make it a plugin (as it probably needs to prepare work on application startup anyways). Then you can get a reference to your plugin -- Play.application().plugin(AuthPlugin.class).

In this particular case you can do a database lookup in the validate methods, e.g.

User u = User.find.where().eq("username", username).eq("password`,password).findUnique();
if (u == null)
 return "Error.";
else
 return null;

So this isn't so much about Play Framework, but Java programming in general.

Mirko Adari
  • 5,083
  • 1
  • 15
  • 23
  • This is very similar to the example given by the Play! framework login sample which I linked to. The main reason I don't like this is because it requires static injection. I am hoping to find a solution that allows me to perform the JavaForm validate() functionality in a non-static scope. – torbinsky Jan 24 '13 at 18:27
0

Assuming you use Spring, you can do it like in any other Java program:

@Configurable
public class MyModel {
    @Autowired
    transient MyService myService;

    public String validate() { ... }
}

The @Configurable annotation makes the class capable of dependency injection. The transient qualifier makes sure the field doesn't get picked up as a field to save into a database.

Spring works fine with Play 2.0/2.1 in one of my projects. I don't consider dependency injection in model objects aesthetically pleasing, but if you need it you can use it.

DCKing
  • 4,253
  • 2
  • 28
  • 43
  • I don't like DI in my model objects either and typically try to keep them as POJO's with annotations only. I use a DAO layer to do my queries etc... That being said, this doesn't really address my core problem of wanting to perform the Play! JavaForm validate() in a non-static scope. What I am looking for is an alternate way to perform form validation in Play! – torbinsky Jan 24 '13 at 18:29
  • @Configurable *should* be able to do what you want. Check out this question: http://stackoverflow.com/questions/4703206/spring-autowiring-using-configurable . Mind you that Spring's AspectJ stuff and Play's Scala compiler don't always get along well so your mileage may vary. – DCKing Jan 26 '13 at 15:13