2012-04-10 10 views
15

Tengo un servlet que, pasado parámetros de consulta, obtiene una lista de objetos de DAO, convierte la lista en JSON y la envía de regreso a la respuesta. Cada lista está hecho de objetos que tienen un método:¿Cómo se puede pasar una Lista <objetos que implementan una interfaz> a un método?

public String getAsJson(){...} 

Y el servlet tiene un montón de métodos mayoría indentical que se parecen:

private String getUserListAsJson() { 
    List<User> userList = this.dao.getUsers(); 
    StringBuilder builder = new StringBuilder(); 
    builder.append('['); 
    // loops over the list appending the value of each objects getAsJson() 
    builder.append(']'); 
    return builder.toString(); 
} 

El problema es que tengo unos 6 métodos (y creciendo) que se ven exactamente así, excepto por diferentes consultas DAO. Mi idea era crear una interfaz que solo tuviera la definición del método getAsJson(), hacer que cada bean lo implementara, y luego tener otro método en el servlet que tomara los objetos que implementaban esa interfaz. Terminó pareciéndose a esto:

public Interface JsonEnabled { 
    public String getAsJson(); 
} 

public class User implements JsonEnabled { 
    .... 
    @Override 
    public String getAsJson() {...} 
} 

public class TheServlet { 
    ... 
    private String getUserListAsJson() { 
     List<User> userList = this.dao.getUsers(); 
     return this.getListAsJson(userList); 
    } 
    private String getListAsJson(List<? implements JsonEnabled> list) { 
     // The loop code that is in each method. 
    } 
} 

Así que si alguien realmente ha leído hasta aquí = P, que no se compila y después de buscar algún tipo de documentación de Oracle, que sólo puede tener extiende y no implementa para los parámetros genéricos Hacer que todas las clases se extiendan desde una clase abstracta que solo tiene el método getAsJson() no tiene sentido semánticamente (las clases no están relacionadas).

No he encontrado una buena solución en SO o simplemente buscando en Google, por lo que cualquier ayuda/idea sería apreciada.

+1

tangental pero ¿realmente desea construir cadenas JSON usted mismo? Sugiera usar una biblioteca como Jackson u otra cosa –

Respuesta

36

Para comodines genéricos la palabra clave extends funciona tanto para las clases e interfaces:

private String getListAsJson(List<? extends JsonEnabled> list) { ... } 

extends tiene un poco diferente significado cuando se utiliza para definir los límites genéricos - que, esencialmente, se traduce en "es, o se extiende o implementos".

+0

¡Gracias! Funcionó como por arte de magia. Pensé que tenía que haber una manera de hacerlo, supongo que debería leer la documentación nuevamente ahora que la has explicado y ver si los documentos dicen lo mismo. – Windle

+0

Ojalá pudiera dar muchos más +1. Esto es exactamente lo que necesitaba también, y ahora entiendo lo que significa también. – reidisaki

3

Por qué no sólo tiene que utilizar

private String getListAsJson(List<JsonEnabled> list) { ... } 

?

+3

Basado en el ejemplo de código OP, no puede pasar un parámetro 'List ' a esa función. –

+1

@LuiggiMendoza lo clavó. Me da la sensación de que voy a tomar la molestia de enviar cada lista a una lista . También podría hacer allí el JSON. Aunque tuve el mismo pensamiento. – Windle

+0

@LuiggiMendoza Ya veo, gracias. Parece que he perdido este punto. Sin embargo, puede crear la Lista y completarla con Usuarios y luego pasarla también. –

Cuestiones relacionadas