BeanWrapperImpl se resuelve solo con WebSphere
-
27-10-2019 - |
Pregunta
Diferente entre nuestro estaba en Dev y nuestro local fue
Nuestra aplicación está utilizando Spring-Security con Spring Versión 3.1.0 Liberación.
Comienza en un archivo JSP, estamos tratando de mostrar el nombre de usuario conectado:
ON estaba en Dev, tenemos una NotablePropertyException: "La propiedad de Bean 'Principal' no es legible o tiene un método Getter no válido: ¿El tipo de retorno del Getter coincide con el tipo de parámetro del setter?"
Esto se debe a que la AuthenticationTag está usando un beanwrapper (beanwrapperiMpl)
En la línea 729 (lanzamiento de primavera 3.1.0) del archivo beanwrapperiMpl, el error es lanzado,
727:PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
728:if (pd == null || pd.getReadMethod() == null) {
729: throw new NotReadablePropertyException(getRootClass(), this.nestedPath + propertyName);
730:}
Entonces PD es nulo o PD.getReadMethod () es nulo. En los casos normales, GetReadMethod Devuelve esto: Método de objeto [público java.lang.object org.springframework.security.authentication.useNamePasswordAuthenticationToken.getPrincipal ()]
actualizarDespués de depurar y agregar algunos registros en la clase, parece que "PD" es nulo
Escribí este código en Java puro para identificar el error
logger.info(session.getAttribute("SPRING_SECURITY_CONTEXT").getClass().toString());
final SecurityContextImpl sci = ((SecurityContextImpl) session.getAttribute("SPRING_SECURITY_CONTEXT"));
logger.info(sci.getAuthentication().getClass().toString());
final Authentication auth = sci.getAuthentication();
logger.info(auth.getPrincipal().getClass().toString());
final User u = (User) auth.getPrincipal();
logger.info(u.getUsername());
logger.info(SecurityContextHolder.getContext().getAuthentication().getName());
logger.info("use beanWrapper :");
final BeanWrapperImpl wrapper = new BeanWrapperImpl(auth);
String property = "principal";
Object result = wrapper.getPropertyValue(property);
logger.info("property : " + property + " value :[" + result.toString() + "]");
property = "principal.username";
result = wrapper.getPropertyValue(property);
logger.info("property : " + property + " value :[" + result.toString() + "]");
Iniciar sesión en nuestro estaba en Dev:
[2012-01-12 12:23:19,843] INFO [WebContainer : 8] [c.b.e.e.w.c.IndexController] class org.springframework.security.core.context.SecurityContextImpl
[2012-01-12 12:23:19,843] INFO [WebContainer : 8] [c.b.e.e.w.c.IndexController] class org.springframework.security.authentication.UsernamePasswordAuthenticationToken
[2012-01-12 12:23:19,843] INFO [WebContainer : 8] [c.b.e.e.w.c.IndexController] class org.springframework.security.core.userdetails.User
[2012-01-12 12:23:19,843] INFO [WebContainer : 8] [c.b.e.e.w.c.IndexController] superadmin
[2012-01-12 12:23:19,843] INFO [WebContainer : 8] [c.b.e.e.w.c.IndexController] superadmin
[2012-01-12 12:23:19,843] INFO [WebContainer : 8] [c.b.e.e.w.c.IndexController] use beanWrapper :
<500 Error>
Los registros en nuestro local fueron:
[2012-01-13 08:51:10,062] INFO [WebContainer : 4] [c.b.e.e.w.c.IndexController] class org.springframework.security.core.context.SecurityContextImpl
[2012-01-13 08:51:10,062] INFO [WebContainer : 4] [c.b.e.e.w.c.IndexController] class org.springframework.security.authentication.UsernamePasswordAuthenticationToken
[2012-01-13 08:51:10,062] INFO [WebContainer : 4] [c.b.e.e.w.c.IndexController] class org.springframework.security.core.userdetails.User
[2012-01-13 08:51:10,062] INFO [WebContainer : 4] [c.b.e.e.w.c.IndexController] superadmin
[2012-01-13 08:51:10,073] INFO [WebContainer : 4] [c.b.e.e.w.c.IndexController] superadmin
[2012-01-13 08:51:10,073] INFO [WebContainer : 4] [c.b.e.e.w.c.IndexController] use beanWrapper :
[2012-01-13 08:51:10,095] INFO [WebContainer : 4] [c.b.e.e.w.c.IndexController] property : principal value :[org.springframework.security.core.userdetails.User@99ac08b4: Username: superadmin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: SuperAdmin]
[2012-01-13 08:51:10,095] INFO [WebContainer : 4] [c.b.e.e.w.c.IndexController] property : principal.username value :[superadmin]
Nuestro WAS en Dev es una versión completa,
Nuestro local era una versión ligera y gratuita de desarrollador
ACTUALIZAR
Después de codificar una solución para obtener el nombre de usuario, el problema ocurre más adelante en el futuro, aún con el bannwrapperiPLPL
org.springframework.beans.NotReadablePropertyException: Invalid property 'codeAndName' of bean class [com.data.model.Country]: Bean property 'codeAndName' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:729)
at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:721)
at org.springframework.web.servlet.tags.form.OptionWriter.doRenderFromCollection(OptionWriter.java:216)
at org.springframework.web.servlet.tags.form.OptionWriter.renderFromCollection(OptionWriter.java:186)
at org.springframework.web.servlet.tags.form.OptionWriter.writeOptions(OptionWriter.java:139)
at org.springframework.web.servlet.tags.form.OptionsTag.writeTagContent(OptionsTag.java:169)
ACTUALIZAR 2 :
El problema está más aislado: sin depenidad a la seguridad de la primavera, solo SpringMVC,
Cuando se ha colocado en Beanwrapper no tiene un setter correspondiente al Getter, lanza una no lectura de propertyException solo en el Dev.
Cuando hay un setter, entonces no hay problema. Suponiendo que la clase UserNamePassWalDauthenticationToken es una clase de Spring Security.class.
Solución
Una solución encontrada:
El problema se debe a la introducción de ExtendedBeanInfo Inf Spring3.1
...
Entonces, la solución es tomar la versión anterior de CachedinTrospectionResults y ponerla en el paquete "org.springframework.beans" para que se sobrescribiera,
Pero debes asegurarte de que la clasificación de la aplicación sea el primero.
Otros consejos
Tenía el mismo problema cuando intentaba establecer una propiedad anidada usando BeanWrapper. El problema era que la propiedad no tenía un setter, aunque no creía que el setter fuera necesario. Agregar el setter solucionó mi problema. ¡Gracias por proporcionar las actualizaciones Benoit! Mi frijol:
public class Bean {
private InnerBean innerBean = new InnerBean();
public InnerBean getInnerBean() {
return this.innerBean;
}
}
Mi código de beanwrapper que estaba fallando:
BeanWrapper wrapper = new BeanWrapperImpl(new Bean());
wrapper.setPropertyValue("innerBean.property","some value");