Fóruns

Início » Liferay Portal » Español » 5. Portal Framework

Visualização combinada Visão plana Exibição em árvore
Tópicos [ Anterior | Próximo ]
toggle
Ignacio Roncero Bazarra
Cómo operar con los formularios usando Service Builder y Spring MVC
16 de Fevereiro de 2012 05:23
Resposta

Ignacio Roncero Bazarra

Ranking: New Member

Mensagens: 19

Data de entrada: 14 de Dezembro de 2010

Mensagens recentes

Buenas a todos,

después del primer portlet en el que he pasado olímpicamente del Service Builder, me he decidido crear un segundo portlet usando esta vez para la capa de persistencia el Service Builder y la verdad es que solo encuentro problemas:

El principal en el que estoy metido ahora mismo es como trabajar con los formularios usando los modelos que provee el Service Builder. Es decir, yo hasta la fecha en el controlador del portlet usaba una cabecera como esta (para el método encargado de recoger la información del formulario):

1
2@RequestMapping(params = { "javax.portlet.action=accion", "action=workflow.occupation.save" })
3protected final void occupationSave(Model model, @RequestParam("action") String action, @ModelAttribute (value="occupationForm") QAOccupation occupation, ActionRequest actionRequest, ActionResponse actionResponse)
4


Y si QAOccupation es una clase funciona perfectamente. Pero el Service Builder trabaja con interfaces y QAOccupation es una interfaz, por lo que al hacer submit Spring me lanza el siguiente error:
1
2org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [xxx.model.QAOccupation]: Specified class is an interface


Eso es debido a que Spring no puede instanciar una interface usando la annotation @ModelAttribute (lógicamente no sabe que clase específica usar para la instancia).

Por lo que mi duda es:

Si el Service Builder siempre trabaja con interfaces ¿Cómo lo hacéis vosotros cuando queréis recuperar los datos que el usuario os envía a través del formulario si dicho formulario es una entity generada con el service builder.
Cierto es que podría coger los datos uno a uno ya que son atributos del request pero no es lo suyo (imagina que el bean tiene una lista de objetos y editas dicha lista en el formulario).



Aprovecho el post para comentar que según he visto ya se ha discutido sobre la conveniencia de poder asignar tipo entidades a las columnas de las entity en el service.xml para así crear relaciones one-to-one, por ejemplo. Esto no es posible actualmente (versión 6.0.5 y 6.0.6, no se en la 6.1) y el service builder lanza un error. Como workarround se propone el añadir el método de tipo getLanguage, por ejemplo, y en dicho método como tienes en la clase el languageId, podrías devolver el objeto entero Language a partir de dicho id. Como solución temporal no está mal, pero cuando modificas la implementación del modelo (ubicada en xxx.mode.impl) y vuelves a ejecutar el service builder este no modifica las interfaces, por lo que dicho método no está accesible.
Yo lo he solucionado modificando a mano las interfaces para tener acceso a dicho método (y ya puedo usarlo en el formulario como si fuese un atributo más, es decir, occupation.language.name, por ejemplo). Pero, ¿Hay algún método para que el service builder se fije en las modificaciones de las implementaciones de los modelos y no solo ne la de los servicios?
Mikel Goikoetxea
RE: Cómo operar con los formularios usando Service Builder y Spring MVC
17 de Abril de 2012 23:51
Resposta

Mikel Goikoetxea

Ranking: Junior Member

Mensagens: 56

Data de entrada: 16 de Março de 2010

Mensagens recentes

Hola Ignacio,

Para recuperar los datos de un formulario correspondientes a un entity generado con el service builder tendrías que hacerlo de la siguiente manera:
1@ActionMapping(params = "accion=anadirEmpleado")
2    public void anadirEmpleado(@ModelAttribute("empleado") EmpleadoImpl empleado, BindingResult result, Model model, ActionRequest request, ActionResponse response) throws SystemException {

Si te fijas en lugar de utilizar la interface utilizamos la implementación de nuestra entidad que es un clase, "EmpleadoImpl".
Y en el "service.xml" tendríamos la siguiente entidad:
1<entity name="Empleado" table="SPRING_EMEPLADO" local-service="true"
2        remote-service="false" cache-enabled="false">       
3        <column name="idEmpleado" db-name="IDEMPLEADO" type="long" primary="true" />
4        <column name="nombre" db-name="NOMBRE" type="String" />
5        <column name="apellidos" db-name="APELLIDOS" type="String" />
6        <column name="telefono" db-name="TELEFONO" type="long" />
7        <column name="email" db-name="EMAIL" type="String" />
8</entity>

Y en la JSP:
 1<portlet:actionURL var="ejecutarAccionURL">
 2    <portlet:param name="accion" value="anadirEmpleado" />
 3</portlet:actionURL>
 4
 5<form:form action="${ejecutarAccionURL}" commandName="empleado" id="<portlet:namespace/>altaEmpleado">
 6    <table>
 7        <tr>
 8            <td>
 9                <label for="<portlet:namespace/>nombre">
10                    <spring:message code="nombre" />
11                </label>
12            </td>
13            <td>
14                <form:input path="nombre" id="<portlet:namespace/>nombre"/>
15            </td>
16        </tr>
17        ...
18        <tr>
19            <td></td>
20            <td>
21                <spring:message code="guardar" var="msnGuardar" />
22                <input type="submit" value="${msnGuardar}" title="${msnGuardar}" />
23            </td>
24        </tr>
25    </table>
26   
27</form:form>

Además utilizamos la anotación @ActionMapping ya que la el botón "Guardar" de nuestro formulario ejecutará una ACTION.

Por otro lado, para modificar la implementación del modelo lo que hay que hacer es:
  • Añadir tus modificaciones en el model.impl.EmpleadoImpl. Por ejemplo:
     1private Language language; // (más los getters y setters correspondientes)
     2
     3public Language getLanguage() {
     4     return language;
     5}
     6
     7public void setLanguage(Language language) {
     8     this.language = language;
     9}
  • Ejecutar el build service.
  • Y ya tendrías acceso al language dentro de tu objeto Empleado:
    1Empleado empleado = new EmpleadoImpl();
    2empleado.setLanguage(...);
    3empleado.getLanguage();

Un saludo,

Mikel Goikoetxea Bilbao (@mgoibil)
B2B 2000
Ignacio Roncero Bazarra
RE: Cómo operar con los formularios usando Service Builder y Spring MVC
6 de Junho de 2012 04:57
Resposta

Ignacio Roncero Bazarra

Ranking: New Member

Mensagens: 19

Data de entrada: 14 de Dezembro de 2010

Mensagens recentes

Gracias por la respuesta Mikel,

siento la tardanza en contestar, pero al no estar suscrito al hilo no me ha llegado el correo de tu comentario y no sabía que me había respondido alguien emoticon. A partir de hora me suscribiré a mis propios post también para ver los cambios en ellos en el correo.

Ahora mismo estoy liado subiendo de versión a las 6.0.6 para corregir un bug con el editor javascript de contenido web. Pero en cuanto tenga un rato pruebo lo que me comentas y dejo aquí los resultados. Así podremos cerrar el hilo y ayudar a la gente que busque lo mismo (o que tenga el mismo problema).

Un saludo.