Struts2 capture user input before the setter sees it - java

Part1:
I am trying to search a way to capture and format user input on an automated way. I have a lot of fields and formatting everything with following method becomes bulky:
<s:param name="value" value="thenumber == null ? '' : getText('{0,number,#,##0.00}',{thenumber})" />
Is there an efficient way to automate this?
Part2:
I want to capture and be able to process invalid user input before it gets passed to the correct setter, in this case setTheNumber(Double theNumber). Preferrably with tags from the page itself. Because inserting '10.00aaab' will throw me an error.
Creating a temporary String field for every number I need to set is an invalid option as I would need to create around ~170 setters for this with exception handling and string parsing.
Short: I want to hook own code between my Http post message and my java class setter.
Previously I used #TypeConversion annotation on the setters and getters but I can't use this anymore as my java class with all values is in another project that can't have dependencies to xwork2 packages.
Thanks in advance,

Related

JavaBeans: Can not read Variables from JavaBeans class

i got a simple programm that begins on an input form where the user fills in 3 numbers. The form action refers to a controller servlet where i store the data in the Bean class with the setter methods I have defined.
number.setNumber1(Double.parseDouble(request.getParameter("number1")));
Till now I stored the Number object in the request with
request.setAttribute("numbers", number);
and forwarded it to the output page where i could get it with ${numbers.biggestNumber ( getter-Method that simply determines the biggest Number) }. A tutorial i am using says I could also get the data directly from the Bean by using this piece of code:
<jsp:useBean id="num" scope="session" class="model.Numbers"/>
<c:out value="${num.biggestNumber}/>
but somehow the Bean uses another object of the Numbers-class. I see the advantage of this technique, because I dont have to put the Numbers object into the request. Can someone tell me how I can use the same Numbers object I stored the data before?
I already read that I shouldnt use "jsp:setProperty..." to store the data on the input page, but if i cant get the information i wrote manually to the Bean, I have to ask myself why I should use the JSP JavaBeans annotation at all.
I used the search function but could not find an answer suitable to my question, or maybe I am just not experienced enough to get them in a more advanced context... Any help would be welcome
if you are using this one,
request.setAttribute("numbers", number);
And using requestDispacher redirecting then at target page you can do likewise,
into JSP file :
<jsp:useBean id="numbers" scope="request" class="model.Numbers"/>
<c:out value="${numbers.biggestNumber}/>
Here,
you did with wrong scope=session, means you are putting value into 'request' scope and try to pull it from session is wrong.
also maintain name of attribute 'same' while putting/getting from scope. here, name="numbers" maintain while putting/getting
Okay my mistake was that I thought JavaBeans-Jsp-Tags would save time and code. Indeed I had to create a HttpSession-Object that stores the ID of the used JavaBean
HttpSession sess = request.getSession(true);
sess.setAttribute("number", number);
Now the JavaBean-Tag in my Output.jsp knows which object to use (the one created in the Input.jsp). As far as I do understand now, the only advantage of the JavaBean-Jsp-Tag above normal Parameters added to the Request is that I can use the Bean-Class in the whole Session and am not dependend on the Request-Object.

How to pass a field name to the global message in the properties file

I have the following message in my global-messages.properties file.
errors.integer=${getText(fieldname)} must be an integer.
which works fine with the validation.xml code, but I want to be able use the same message in my java action validation method with the addFieldError() method. My question is how to pass the fieldname to the message. If I use:
addFieldError("seqId", getText("errors.integer"));
I only get the "must be an integer." part of the message. I know I could change the message and use {0} instead of ${getText(fieldname)} but that is not an option because other code uses the message as it is.
First of all: You should really avoid using getText in properties because it is available only in some context.
Second: You should really avoid using fieldname in properties because it is validator specific field.
To achieve what you want, w/o modifying property file, you can create a fieldname property in your action with getter/setter and set its value before using addFieldError.
private String fieldname;
// getter/setter
// ...
fieldname = "seqId";
addFieldError("seqId", getText("errors.integer"));
Someone else showed me another way which worked which I thought I would share.
addFieldError("",getText("seqId")+ getText("errors.integer"));

Mapping the enum to spring form select in a different way

I have the enum set
public enum MyEnum {
A("AND"), //
I("INTER");
}
I have the spring form:select in my jsp page which populates the AND and INTER As I want , but while submitting the form it throws the exception , can't map String AND to enum type Status.
My Controller :
model.addAttribute("list",MyEnum.values);
**
But it works when I modify my enum and add one more value like ,
OR("ÖR") , now If I select OR from UI , it gets saved properly in the
database.But it won't work for A or I.
**
Note : Down voting to this question simply means that you have not read question carefully.I have already searched on stackoverflow. :)
thanks all for answering but I found the way , how to deal with this.
<form:options items="${mList}" itemLabel="name" />
Use spring form options in following way don't specify the itemValue field , spring will do it for you. :)
I suppose when spring converts your enum to select option it uses toString method on enum and you overrided it so it returns "AND" for A and "INTER" for I. When it converts selected option back to enum it probably uses valueOf but I'm not sure.
In any case you should try to implemend your own formatter for this field that will convert enum to String and back to enum correctly. Check this article: http://bthurley.wordpress.com/2012/10/25/enum-translations-in-spring-mvc/

Spring path binding: is it bound directly to the variable or does it invoke the constructor/setters?

I have a spring bound form (modelAttribute) which displays the user information.
The user's telephone number is displayed in a formatted manner but a requirement is that the number is saved to the database without any signs.
So in the getter method of my user object I format the telephone number according to the rules and in the setter I put the code to remove the special signs.
The formatting part works fine, but setter part where I remove the signs does not seem to occur.
In my constructor I also did:
setTelephoneNumber(TelephoneNumber);
So the constructor also invokes the setter.
I'm using Spring 3.0.4 and Spring-mvc.
Any input on this issue and how to resolve it would be appreciated.
edit:
controller section:
model.addAttribute("user", user);
JSP (shortened it a bit but this is the gist. submitUrl is due to a portal environment:
<form:form action="${submitUrl}" modelAttribute="user">
<form:input path="telephoneNumber"/>
</form>
Model telephoneNumber setter:
if(!StringUtils.isBlank(telephoneNumber)){
this.telephoneNumber = telephoneNumber.replaceAll("[^0-9]", "");
} else{
this.telephoneNumber= "";
}
And I think so because the value lands in the database with the formatting I used. (spacing)
Even if it is not the correct answer to your question:
I strongly recommend to do the formating in an other way then by setter getter
Spring 3.0 provideds something they called "type conversion"
spring blog with example
spring reference "Validation, Data Binding, and Type Conversion"
Using this would be much more cleaner.
Back to your question:
Spring path binding: is it bound directly to the variable or does it invoke the constructor/setters?
As fare I understand the Java Doc and some code snippets, Spring uses BeanWrapper (BeanWrapperImpl) to set the values of Beans (#see Reference: 5.4 Bean manipulation and the BeanWrapper). And BeanWrapperImpl behaves like the reference said:
uses setter and getter to access "simple" values.
It is exactly like the reference said in section "5.4.1 Setting and getting basic and nested properties": For an expression "name":
Indicates the property name
corresponding to the methods getName()
or isName() and setName(..)
So at least this answer your question, so I assume that the cause for your problem is some thing else.

Seam/Hibernate validator listener

We use a standard SEAM setup here ... complete with the validation system that uses hibernate.
Basically what happens is a user enters a value into an html input and seam validates the value they entered using the hibernate validation.
Works fine for the most part except here's my problem: We need to record the results of validation on each field and I can't figure out a good way to do it ... ideally it would be done through communicating with the seam/hibernate validation system and just recording the validation results but as far as I can tell there isn't a way to do this?
Has anyone done anything like this in the past? There are a couple nasty work arounds but I'd prefer to do it cleanly.
Just a quick overview of the process that we have happening right now for context:
1) user enters field value
2) onblur value is set with ajax (a4j:support) at this point the validators fire and the div is re-rendered, if any validation errors occured they're now visible on the page
What I'd like to have happen at step2 is a 'ValidationListener' or something similar is called which would allow us to record the results of the validation.
Thanks if anyone is able to help :o
You should be able to do it by creating a Bean that has a method observing the org.jboss.seam.validationFailed event. That method can then do whatever logging you want.
#Name("validationObserver")
public class ValidationObserver() {
#Observer("org.jboss.seam.validationFailed")
public void validationFailed() {
//Do stuff
}
}
The validationFailed event doesn't pass any parameters so you'll have to interrogate the FacesMessages or possibly the Hibernate Validation framework itself if you want to record what the error was.
I you are only using Hibernate for validation, you can use the Hibernate ClassValidator in the validationFailed() method, as recommended by Damo.
Example:
public <T> InvalidValue[] validateWithHibernate(T object) {
ClassValidator<T> validator = new ClassValidator(object.getClass());
InvalidValue[] invalidValues = validator.getInvalidValues(object);
return invalidValues;
}

Categories