Validation Spring confusion to render error message - spring

I try to render error message but it's not appears:
I have validator:
#Component
class ValidatorFBOSSearch implements Validator {
#SuppressWarnings("rawtypes")
#Override
public boolean supports(Class clazz) {
return FormBackObjectSearch.class.equals(clazz);
}
#Override
public void validate(Object obj, Errors error) {
FormBackObjectSearch fbos = (FormBackObjectSearch)obj;
if ("".equals(fbos.particularDate)){
error.rejectValue("particularDate", "required.listOfDates", "This field is required");
}
}
}
it have to cheak does my field in backing object for form have value inputed or not. rejectValue has three param. First - looks for a value in Model Attribute in my backing object, Secong looks for error message in properties file(my properties file located in resourses/error forlder) Third param in methos says if it won't be able to find message in error properties file will render it as default, here is my sniped of code in my servlet-context.xml
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
And this my xml config for messageSourse to get errors for Validator in servlet-context.xml:
<!-- Resolves error messages for validator from /Education/src/main/webapp/resources/errors-->
<beans:bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<beans:property name="basename" value="errors/errormessages"/>
</beans:bean>
Here peace of my controller code for dealing with requests:
#RequestMapping(value="/search", method=RequestMethod.GET)
public void search(Model model) {
FormBackObjectSearch fbos = new FormBackObjectSearch();
model.addAttribute("fbosAttribute", fbos);
}
#RequestMapping(value ="/result", method=RequestMethod.POST)
public String extract(#RequestParam String nameOfInstitution,
#RequestParam String particularDate,
#RequestParam String typeOfInstitution,
#ModelAttribute("fbosAttribute") FormBackObjectSearch fbos,
BindingResult result, RedirectAttributes redirectAttributes,
Model model) throws Exception {
ValidatorFBOSSearch validatorFBOS = new ValidatorFBOSSearch();
validatorFBOS.validate(fbos, result);
if(result.hasErrors()) {
redirectAttributes.addFlashAttribute("fbosAttribute", fbos);
return "redirect:/search";
} else {
if(particularDate !="" && nameOfInstitution !="" && typeOfInstitution =="") {
controllerSupportClass.findWithDateAndName(nameOfInstitution, particularDate, model);
} else if(particularDate !="" && nameOfInstitution =="" && typeOfInstitution !="") {
controllerSupportClass.findWithAddedDateAndType(typeOfInstitution, particularDate, model);
} else if(particularDate !="" && nameOfInstitution =="" && typeOfInstitution ==""){
controllerSupportClass.findWithAddedDate(particularDate, model);
} else if(particularDate !="" && nameOfInstitution !="" && typeOfInstitution !="") {
throw new Exception("Search by choose all parameters is not exceptable");
} else {
throw new Exception("You didn't put any search parameters");
}
}
return "search";
}
And here is peace of my jsp:
<form:form action="result" method="post" modelAttribute="fbosAttribute" >
<table>
<tr>
<th>Date for extracting:</th>
<td><form:select path="particularDate">
<form:option value=""> -Choose date-</form:option>
<form:options items="${listOfDates}"></form:options>
</form:select> <td><form:errors path="particularDate" cssClass="error"/></td>
</td>
</tr>
</table>
</form:form>
The problem is thet I can not see error messages show up. I tried to use Flash Attributes to have error appears after riderect, but nothing heppend. cuz I found here that when I use rederect it makes my model and errors deleted and start new one. But How can I have advantage to use flash attibutes to solve my problem. Thank you

To register the validator for an specific controller you need can use the `#InitBimder' annotation.
#InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setValidator(new ValidatorFBOSSearch());
}
For mor details how to register the validator see my answer at:
Validation in Spring MVC
I think your check statement is wrong:
if ("".equals(fbos.particularDate)){
If a user enters nothing, then a String will not be empty ( "" ), it will be null. Therefore use:
if (fbos.particularDate == null || fbos.particularDate.isEmpty())

Related

Spring Security: How to get the originally thrown exception of a failed XwsSecurityInterceptor.validateMessage call

My application is using Spring Security to validate incoming Endpoint calls. I am trying to give the client specific error codes when anything goes wrong within the XwsSecurityInterceptor but I haven't yet found a way to do this.
This is what I have tried: I am using an EndpointInterceptor that inherits from XwsSecurityInterceptor:
<bean name="myInterceptor" id="myInterceptor" class="x.y.MyPreAuthenticationSecurityInterceptor">
<property name="policyConfiguration" value="classpath:/security.xml" />
<property name="callbackHandlers">
<list>
<bean id="myCallbackHandler" class="x.y.MyCallbackHandler" />
</list>
</property>
</bean>
The interceptor has a CallbackHandler 'myCallbackHandler' that handles PasswordValidationCallbacks. For testing purposes for each callback it attaches a validator that will instantly throw a certain exception (CustomException) with a certain error code:
#Override
protected void handleInternal(Callback callback) throws IOException, UnsupportedCallbackException {
if (callback instanceof PasswordValidationCallback) {
PasswordValidationCallback validationCallback = (PasswordValidationCallback) callback;
if (validationCallback.getRequest() instanceof PasswordValidationCallback.PlainTextPasswordRequest) {
validationCallback.setValidator(new MyValidator());
return;
}
} else if (callback instanceof CleanupCallback) {
SecurityContextHolder.clearContext();
return;
}
throw new UnsupportedCallbackException(callback);
}
private class MyValidator implements PasswordValidationCallback.PasswordValidator {
public boolean validate(PasswordValidationCallback.Request request) throws PasswordValidationCallback.PasswordValidationException
{
throw new PasswordValidationCallback.PasswordValidationException("test", new CustomException("some error code"));
}
}
As specified in https://docs.spring.io/spring-ws/site/reference/html/security.html, section 7.2.5 the exception handling is done in the handleValidationException method.
In 'MyPreAuthenticationSecurityInterceptor' I am overriding the handleValidationException method:
#Override
public boolean handleValidationException(WsSecurityValidationException ex, MessageContext messageContext) {
if (logger.isWarnEnabled()) {
logger.warn("Could not validate request: " + ex.getMessage());
}
return false;
}
Problem is that when debugging I can't find my CustomException in WsSecurityValidationException. The root cause of is 'com.sun.xml.wss.XWSSecurityException: Invalid Username Password Pair'.
Am I going about this the wrong way?

javax.el.ELException: Cannot convert Protocol#7ebc9002 of type class Protocol to class Protocol$$EnhancerByCGLIB$$22af7fa3 (lazy loadding)

I struggle to make hibernate 3.1 lazy loading working with JSF 1.2
Caused by: javax.el.ELException: Cannot convert foo.bar.Protocol#7ebc9002 of type class foo.bar.Protocol to class foo.bar.Protocol$$EnhancerByCGLIB$$22af7fa3
at org.apache.el.lang.ELSupport.coerceToType(ELSupport.java:438)
at org.apache.el.ExpressionFactoryImpl.coerceToType(ExpressionFactoryImpl.java:46)
at com.sun.faces.renderkit.html_basic.RadioRenderer.renderOption(RadioRenderer.java:87)
at com.sun.faces.renderkit.html_basic.SelectManyCheckboxListRenderer.encodeEnd(SelectManyCheckboxListRenderer.java:146)
I read that hibernate will replace the lazy loading proxy on demand, but it seems to do not work on JSF converter call.
Note that Protocols are bound to radio buttons in the view
Do you know how to workaround this ? I can't find someone who have the same issue as me.
applicationContext :
<bean id="protocol" class="foo.bar.Protocol" abstract="false"
lazy-init="default" autowire="byName" dependency-check="default" scope="session">
<aop:scoped-proxy />
</bean>
<bean id="protocolConverter" class="foo.bar.ProtocolConverter" abstract="false"
lazy-init="default" autowire="byName" dependency-check="default" scope="singleton">
<property name="protocolDAO" ref="protocolDAO" />
</bean>
view :
<h:selectOneRadio value="#{pingControler.ping.protocol}" converter="#{protocolConverter}">
<f:selectItems value="#{pingControler.allProtocolsSelectItems}" />
<a4j:support event="onchange" reRender="foo1,foo2" />
</h:selectOneRadio>
ping :
public class Ping {
// Fields
private Integer pingId;
private Protocol protocol;
...
}
pingControler :
private Ping ping;
public void init(ActionEvent event) {
ping = new Ping();
}
public void save(ActionEvent event) throws Exception {
if (ping.getPingId() == null) {
pingPersistent.addPing(ping);
} else {
pingPersistent.updatePing(ping);
}
}
I figured out (finally) how to workaround this. I'm not sure if this is the proper way, but it works.
I added this code :
private static <T> T initializeAndUnproxy(T entity) {
if (entity == null) {
throw new NullPointerException("Entity passed for initialization is null");
}
Hibernate.initialize(entity);
if (entity instanceof HibernateProxy) {
entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation();
}
return entity;
}
And i called it in my Converter like this :
#Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String value) {
Protocol protocol = protocolDAO.findById(new Integer(value));
return initializeAndUnproxy(protocol);
}
instead of this :
#Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String value) {
return protocolDAO.findById(new Integer(value));
}
By the way, i did a mistake when i though that $$EnhancedByCGLIB$$ necessarily means an hibernate proxy. I read somewhere else that it's a library and could be used by Spring dependency injection too for example. Just to let you know.
I hope this will help the few jsf 1.2 / hibernate 3.1 users remaining. Should i upvote myself ?

Why update method isn't calling?

I have a problem. When I click to update image on form, update method isn't calling. I see that in my output logs window. Only may update image in first row in my table.
When I updating first row:
Hibernate: update shoe_goods set description=?, image=?, in_stock=?,
name=?, price=?, size=?, web_store_id=? where id=?
When other rows - nothing.
I save my images in db as byte.
This is my method to display images:
Controller:
#RequestMapping(value = "/imageController/{id}")
#ResponseBody
public byte[] getImages(#PathVariable int id) {
return shoeGoodsService.getById(id).getImage();
}
JSP:
<img src="/imageController/${goods.id}" alt="Image" />
Code in DAO class:
#Override
public void update(ShoeGoods shoeGoods) {
sessionFactory.getCurrentSession().merge(shoeGoods);
sessionFactory.getCurrentSession().getTransaction().commit();
}
Code in Service class:
#Override
public void update(ShoeGoods shoeGoods) {
shoeGoodsDAO.update(shoeGoods);
}
Code in controller, when update method is call only for first row in table:
#RequestMapping(value="/upload_shoe_image", method = RequestMethod.POST)
public #ResponseBody ModelAndView handleFileUpload1(#RequestParam("file") MultipartFile file){
...
try {
ShoeGoods shoeGoods = shoeGoodsService.getById(goodsId);
shoeGoods.setImage(file.getBytes());
//not call always
shoeGoodsService.update(shoeGoods);
} catch (Exception e) {
e.printStackTrace();
}
...
}
In JSP:
<form id="send-image-form" method="POST" enctype="multipart/form-data"
action="/upload_shoe_image">
Edit: <input type="file" name="file">
<br />
Save: <input type="submit" id="save-image" value="Upload">
</form>

Unable to move from controller to view in Spring MVC

I am using Spring MVC framework for my project.
I am unable to get my code running from controller to view.
Sharing the important chunk of code here.....
Inside AdminController.java controller
System.out.println("controller returning");
return new ModelAndView("dataFrame_","frameData",dataString);
Inside dispatcher-servlet.xml
<bean name="/dataFrame.htm"
class="com.organization.dept.spec.proj.module.controller.DataFrameController" >
</bean>
<bean id="dataFrameViewResolver"
class="com.organization.dept.spec.proj.module.view.DataFrameViewResolver">
<property name="dataFrameView">
<bean class="com.organization.dept.spec.proj.module.view.DataFrameView" />
</property>
<property name="dataFramePrefix" value="dataFrame_"></property>
</bean>
inside DataFrameViewResolver.java
public class DataFrameViewResolver extends AbstractCachingViewResolver {
private String dataFramePrefix;
private View dataFrameView;
#Override
protected View loadView (String viewName, Locale locale) throws Exception {
View view = null;
if(viewName.startsWith(this.dataFramePrefix)){
view = dataFrameView;
}
return view;
}
and
public String getDataFramePrefix() {
return dataFramePrefix;
}
public void setDataFramePrefix(String dataFramePrefix) {
this.dataFramePrefix = dataFramePrefix;
}
public View getDataFrameView() {
return dataFrameView;
}
public void setDataFrameView(View dataFrameView) {
this.dataFrameView = dataFrameView;
}
}
inside DataFrameView.java ...
public class DataFrameView extends AbstractView {
#Override
protected void renderMergedOutputModel(Map map, HttpServletRequest request,HttpServletResponse response) throws Exception {
System.out.println("RenderMergeoutputModel"); //line 99
I was unable to get the above system.out.println i.e. was unable to execute my code till that line 99.
The localhost log files of tomcat revealed some exception java.lang.ClassNotFoundException: javax.servlet.jsp.jstl.core.Config
I put the jstl-1.2.jar in lib and this could just get me rid of exception however still was unable get sysout of DataFrameView of line 99.

Custom property editors do not work for request parameters in Spring MVC?

I'm trying to create a multiaction web controller using Spring annotations. This controller will be responsible for adding and removing user profiles and preparing reference data for the jsp page.
#Controller
public class ManageProfilesController {
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(UserAccount.class,"account", new UserAccountPropertyEditor(userManager));
binder.registerCustomEditor(Profile.class, "profile", new ProfilePropertyEditor(profileManager));
logger.info("Editors registered");
}
#RequestMapping("remove")
public void up( #RequestParam("account") UserAccount account,
#RequestParam("profile") Profile profile) {
...
}
#RequestMapping("")
public ModelAndView defaultView(#RequestParam("account") UserAccount account) {
logger.info("Default view handling");
ModelAndView mav = new ModelAndView();
logger.info(account.getLogin());
mav.addObject("account", account);
mav.addObject("profiles", profileManager.getProfiles());
mav.setViewName(view);
return mav;
}
...
}
Here is the part of my webContext.xml file:
<context:component-scan base-package="ru.mirea.rea.webapp.controllers" />
<context:annotation-config/>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>
...
/home/users/manageProfiles=users.manageProfilesController
</value>
</property>
</bean>
<bean id="users.manageProfilesController" class="ru.mirea.rea.webapp.controllers.users.ManageProfilesController">
<property name="view" value="home\users\manageProfiles"/>
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
However, when i open the mapped url, i get exception:
java.lang.IllegalArgumentException: Cannot convert value of type [java.lang.String] to required type [ru.mirea.rea.model.UserAccount]: no matching editors or conversion strategy found
I use spring 2.5.6 and plan to move to the Spring 3.0 in some not very distant future. However, according to this JIRA https://jira.springsource.org/browse/SPR-4182 it should be possible already in spring 2.5.1.
The debug shows that the InitBinder method is correctly called.
What am i doing wrong?
Update:
public class UserAccountPropertyEditor extends PropertyEditorSupport {
static Logger logger = Logger.getLogger(UserAccountPropertyEditor.class);
public UserAccountPropertyEditor(IUserDAO dbUserManager) {
this.dbUserManager = dbUserManager;
}
private IUserDAO dbUserManager;
public String getAsText() {
UserAccount obj = (UserAccount) getValue();
if (null==obj) {
return "";
} else {
return obj.getId().toString();
}
}
public void setAsText(final String value) {
try {
Long id = Long.parseLong(value);
UserAccount acct = dbUserManager.getUserAccountById(id);
if (null!=acct) {
super.setValue(acct);
} else {
logger.error("Binding error. Cannot find userAccount with id ["+value+"]");
throw new IllegalArgumentException("Binding error. Cannot find userAccount with id ["+value+"]");
}
} catch (NumberFormatException e) {
logger.error("Binding error. Invalid id: " + value);
throw new IllegalArgumentException("Binding error. Invalid id: " + value);
}
}
}
There are no errors logged from UserAccountPropertyEditor.
I don't think you want to be specifying the field argument to WebDataBinder.registerCustomEditor(). This intended to work alongside form-backing objects, and you're not using that.
Try the simpler 2-arg method instead, and it should work:
binder.registerCustomEditor(UserAccount.class, new UserAccountPropertyEditor(userManager));
binder.registerCustomEditor(Profile.class, new ProfilePropertyEditor(profileManager));

Resources