This week's book giveaway is in the OCMJEA forum.
We're giving away four copies of OCM Java EE 6 Enterprise Architect Exam Guide and have Paul Allen & Joseph Bambara on-line!
See this thread for details.
The moose likes Struts and the fly likes Getting values from properties in validate-using multiple message-resources in struts Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCM Java EE 6 Enterprise Architect Exam Guide this week in the OCMJEA forum!
JavaRanch » Java Forums » Frameworks » Struts
Bookmark "Getting values from properties in validate-using multiple message-resources in struts" Watch "Getting values from properties in validate-using multiple message-resources in struts" New topic
Author

Getting values from properties in validate-using multiple message-resources in struts

lavi mendonca
Ranch Hand

Joined: Apr 24, 2002
Posts: 53
Hi,

I am using multiple resource bundle/ properties files in my application.In struts-config.xml, I am using multiple message-resources tags with appropriate value for the attribues - key and parameter.
e.g. in struts-config.xml

<message-resources parameter="appln.application1"/>

<message-resources key="TEST_1" parameter="com.companyname.test.ApplicationResources1" null="true"/>

<message-resources key="TEST_2" parameter="com.companyname.test.ApplicationResources2" null="true"/>

In my Action class, I am able to retrieve the values from the resource bundle properties file using the code:

MessageResources messageResources = getResources(request, "TEST_1);
ActionErrors actionErrors = new ActionErrors();
actionErrors.add("error", new ActionMessage("error.missing.key", messageResources.getMessage("label.username")));
saveErrors(request, actionErrors);

I have 3 questions:
a. Is the code above correct ?

b. If i mention the resource bundle in web.xml, am i still alowwed to specify other resource bundle properties files in struts-config.xml. Will struts be able to read all of them (given the correct bundle to read) ?

c. In validate method of ActionForm, I want to retrieve the values from one of my module specific properties file (e.g. ApplicationResources2) so that i can create ActionErrors object. Am not sure how this can be done in the validate method of my class which extends ActionForm?

Any help would be geatly appreciated.

Thanks.
Merrill Higginson
Ranch Hand

Joined: Feb 15, 2005
Posts: 4864
If all the messages for a given JSP are in the same resource bundle, you don't even have to worry about it in your Action or ActionForm classes. Just build the messages as you normally would. Then in your JSP specify a bundle attribute in either the html:errors or html:messages tag.

If are using different bundles for different messages in the same JSP, the method you're using to retrieve the message value is OK, but the constructor for ActionMessage that you showed us is wrong. Just pass the actual message as the first parameter, and false as the second parameter to indicate that this is not a resource message, but a literal String.


Merrill
Consultant, Sima Solutions
lavi mendonca
Ranch Hand

Joined: Apr 24, 2002
Posts: 53
Thanks Merill, But i did not understand your reply. I do not want to set/ get the error in JSP. What i am looking for is a way to create Action Errors in the validate method of my ActionForm class which extends Struts's ActionForm class. In this formbean class, I need a way to specify my module specific resource property file and then use the key to create the ActionError object, so that finally in my jsp, i can be able to retrieve it.

Thanks again.
Merrill Higginson
Ranch Hand

Joined: Feb 15, 2005
Posts: 4864
The recommended way to retrieve and display Struts error messages in a JSP is with either a <html:errors> tag or a <html:messages> tag. If you're doing it any other way, you're probably working too hard. It's best if the ActionMessage contains only the message key, rather than the text. This gives maximum flexibility in a multi-language environment. It is only when the message is actually about to be displayed and the user locale has been determined that the translation is made.

Since both of the above tags accept a bundle attribute, you can specify which MessageResource the tag will use to translate the message keys.

If you still insist on creating ActionMessage objects with the text rather than the key, it's possible to do that in the validate method of an ActionForm. Since the request object is passed in as a parameter, you can do it like this:

[ June 27, 2008: Message edited by: Merrill Higginson ]
lavi mendonca
Ranch Hand

Joined: Apr 24, 2002
Posts: 53
Hi Merrill - Thanks again for your help. I now understand your point. But just to be sure,that i completely understand, can you please confirm the following:

a. If i mention the default resource bundle in web.xml, am i still allowed to specify other resource bundle properties files in struts-config.xml under messages-resource tag. Will struts be able to read all of them (given the correct bundle to read from the request object) ?

b. say in struts-config.xml, i have the following code:
<message-resources key="TEST_1"
parameter="com.companyname.test.ApplicationResources1" null="true"/>
<message-resources key="TEST_2"
parameter="com.companyname.test.ApplicationResources2" null="true"/>

Pls. confirm if this is the correct way of retrieving the resource bundle names TEST_1 from Action class as well as ActionForm class

MyAction extends struts Action class
execute method:
MessageResources resource = getResources(request, "TEST_1);
ActionErrors actionErrors = new ActionErrors();
actionErrors.add(ActionErrors.GLOBAL_ERROR ,
new ActionError("error.missing.key");
// or actionErrors.add("firstName",
new ActionError("error.missing.key");
saveErrors(request, actionErrors);

& in MyFormAction extending struts ActionForm class, in validate method
MessageResource resource = (MessageResources)
request.getAttribute("TEST_1");
ActionErrors actionErrors = new ActionErrors();
actionErrors.add(ActionErrors.GLOBAL_ERROR ,
new ActionError("error.missing.key");
// or actionErrors.add("firstName",
new ActionError("error.missing.key");

Q - Where is the MessageResources object (resource retrieved from request)i.e TEST_1 being used here ?


Thank You..
Merrill Higginson
Ranch Hand

Joined: Feb 15, 2005
Posts: 4864
Originally posted by lavi per:
a. If i mention the default resource bundle in web.xml, am i still allowed to specify other resource bundle properties files in struts-config.xml under messages-resource tag. Will struts be able to read all of them (given the correct bundle to read from the request object) ?

We need to clear up a misconception: A Java ResourceBundle and a Struts MessageResources object are NOT the same thing. They serve similar functions, but they are different objects and are referenced differently. Specifying a resource bundle in your web.xml file affects JSTL tags only, and has no affect whatever on Struts tags. Similarly, MessageResources declared in the struts-config.xml file affect Struts tags and have no effect on JSTL tags.

Having said this, the answer to your question is yes. You can declare a resource bundle in web.xml and use it for JSTL tags and you can also declare a MessageResources object in struts-config.xml and use it for Struts tags and the two will not interfere with each other.

Originally posted by lavi per:
Pls. confirm if this is the correct way of retrieving the resource bundle names TEST_1 from Action class as well as ActionForm class

If you're putting only the message key in the message, there's no need to get the MessageResources object at all. The translation is done by Struts in the JSP, not in your code, so why do you even need the MessageResource object?

One suggestion: the ActionError class is deprecated in later version, so you should use ActionMessage instead. The ActionErrors class is still used, but not ActionError.
Originally posted by lavi per:
Q - Where is the MessageResources object (resource retrieved from request)i.e TEST_1 being used here ?

The MessageResources object is needed only if you plan to translate the message keys yourself. Since it looks like you're taking my advice and just passing the message keys to the JSP, you don't need this object at all and can remove this code.
[ June 28, 2008: Message edited by: Merrill Higginson ]
lavi mendonca
Ranch Hand

Joined: Apr 24, 2002
Posts: 53
Hi Merrill,

Thanks again for all your help and patience. I really appreciate it.
I am currently using Struts 1.1 with JSP (No JSTL). To reconfirm my understanding, I would like to go through the following points and have them confirmed as well as have you look at point 6 (question), so that I can easily use them in my current project.

In order to specify my module specific resource bundle or any module specific property file (containing key-value information) in addition to the one specified in web.xml (Applicationresources.properties) and then read it in my jsp file using struts html:error or html:messages tags, I should be doing the following

1. In struts-config, add the following
<message-resources key="TEST_1" parameter="com.companyname.test.ApplicationResources1" null="true"/>

<message-resources key="TEST_2" parameter="com.companyname.test.ApplicationResources2" null="false"/>

Please confirm?
-----------------------------------------------------------

2. The properties files as specified in the struts-config file (messages-resource tag) can be kept in any location as long as they available in the classpath.
Please confirm?

-----------------------------------------------------------
3. In ActionForm, in validate method, do either of the following (here i don't need to specify the key (either TEST_1 or TEST_2)

ActionErrors actionErrors = new ActionErrors();

// using ActionError, if you want to display all error messages at the top of the page
actionErrors.add(ActionErrors.GLOBAL_ERROR , new ActionError("error.missing.key");

// using ActionError, if you want to display individual error messages next to the field , where e.g firstName is a property/ field of the ActionForm class
actionErrors.add("firstName", new ActionError("error.missing.key");


//using ActionMessage, if you want to display all error messages at the top of the page
ActionErrors actionErrors = new ActionErrors();
actionErrors.add(ActionMessages.GLOBAL_MESSAGE , new ActionMessage("error.missing.key");

// using ActionMessage if you want to display individual error messages next to the field, where e.g firstName is a property/ field of the ActionForm class
ActionErrors actionErrors = new ActionErrors();
actionErrors.add("firstName" , new ActionMessage("error.missing.key");


Please confirm?

-----------------------------------------------------------

4. In Action class, in execute method, here i don't need to specify the key (either TEST_1 or TEST_2)

ActionErrors actionErrors = new ActionErrors();

// using ActionError, if you want to display all error messages at the top of the page
actionErrors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.missing.key");

// using ActionError, if you want to display individual error messages next to the field , where e.g firstName is a property/ field of the ActionForm class
actionErrors.add("firstName",new ActionError("error.missing.key");

//using ActionMessage, if you want to display all error messages at the top of the page
ActionErrors actionErrors = new ActionErrors();
actionErrors.add(ActionMessages.GLOBAL_MESSAGE , new ActionMessage("error.missing.key");

// using ActionMessage if you want to display individual error messages next to the field, where e.g firstName is a property/ field of the ActionForm class
ActionErrors actionErrors = new ActionErrors();
actionErrors.add("firstName" , new ActionMessage("error.missing.key");

saveErrors(request, actionErrors);


Please confirm?

-----------------------------------------------------------

5. In my java file, if I just want to retrieve the value corresponding to a key from "TEST_1" bundle. Please confirm?

MessageResource resource = (MessageResources) request.getAttribute("TEST_1");

String value = messageResources.getMessage("label.somekey");

-----------------------------------------------------------
6. In my jsp file

a. If I just want to display any message from the property fle
<bean:message bundle="TEST_1" key="some.message.key"/>
Please confirm?

b. If I want to display the error message in the jsp page
Q - ?? how can i specify the resource bundle i.e key="TEST_1" or "TEST_2" here ?? and how do I then display the error messages using both html:error tag as well as html:messages tag. Please help ?

-----------------------------------------------------------

Thanks once again for everything,
Merrill Higginson
Ranch Hand

Joined: Feb 15, 2005
Posts: 4864
Originally posted by lavi per:

In order to specify my module specific resource bundle or any module specific property file (containing key-value information) in addition to the one specified in web.xml (Applicationresources.properties) and then read it in my jsp file using struts html:error or html:messages tags, I should be doing the following

1. In struts-config, add the following
<message-resources key="TEST_1" parameter="com.companyname.test.ApplicationResources1" null="true"/>

<message-resources key="TEST_2" parameter="com.companyname.test.ApplicationResources2" null="false"/>

Please confirm?

I was confused earlier by your statements regarding declaring the resource bundle in the web.xml file. Earlier I thought you were referring to declaring a bundle for use in JSTL tags, but now I realize you're referring to declaring a Struts MessageResources. The web.xml file is not the place to declare any Struts MessageResources. This is how it was done in Struts 1.0, but not in 1.1. The way to declare a default MessageResources is in the struts-config.xml file. Do it the same way you did the others, except without specifying a key attribute. Example:

Your other entries are correct.
Originally posted by lavi per:
2. The properties files as specified in the struts-config file (messages-resource tag) can be kept in any location as long as they available in the classpath.
Please confirm?

Yes, that's correct, but the recommended place to put them is in WEB-INF/classes. Also, if you specify com.companyname.test, you must make sure the file is in the folder WEB-INF/classes/com/companyname/test.
Originally posted by lavi per:
3. In ActionForm, in validate method, do either of the following (here i don't need to specify the key (either TEST_1 or TEST_2)

ActionErrors actionErrors = new ActionErrors();

// using ActionError, if you want to display all error messages at the top of the page
actionErrors.add(ActionErrors.GLOBAL_ERROR , new ActionError("error.missing.key");

// using ActionError, if you want to display individual error messages next to the field , where e.g firstName is a property/ field of the ActionForm class
actionErrors.add("firstName", new ActionError("error.missing.key");


//using ActionMessage, if you want to display all error messages at the top of the page
ActionErrors actionErrors = new ActionErrors();
actionErrors.add(ActionMessages.GLOBAL_MESSAGE , new ActionMessage("error.missing.key");

// using ActionMessage if you want to display individual error messages next to the field, where e.g firstName is a property/ field of the ActionForm class
ActionErrors actionErrors = new ActionErrors();
actionErrors.add("firstName" , new ActionMessage("error.missing.key");


Please confirm?

Since you're using Struts 1.1, you should always use ActionError. If you were using a later version, you would use ActionMessage. Otherwise, your code is correct. Is there a reason why you're using such an outdated version of Struts?

Originally posted by lavi per:
4. In Action class, in execute method, here i don't need to specify the key (either TEST_1 or TEST_2)

ActionErrors actionErrors = new ActionErrors();

// using ActionError, if you want to display all error messages at the top of the page
actionErrors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.missing.key");

// using ActionError, if you want to display individual error messages next to the field , where e.g firstName is a property/ field of the ActionForm class
actionErrors.add("firstName",new ActionError("error.missing.key");

//using ActionMessage, if you want to display all error messages at the top of the page
ActionErrors actionErrors = new ActionErrors();
actionErrors.add(ActionMessages.GLOBAL_MESSAGE , new ActionMessage("error.missing.key");

// using ActionMessage if you want to display individual error messages next to the field, where e.g firstName is a property/ field of the ActionForm class
ActionErrors actionErrors = new ActionErrors();
actionErrors.add("firstName" , new ActionMessage("error.missing.key");

saveErrors(request, actionErrors);

Please confirm?

Yes, this is correct.
Originally posted by lavi per:
5. In my java file, if I just want to retrieve the value corresponding to a key from "TEST_1" bundle. Please confirm?

MessageResource resource = (MessageResources) request.getAttribute("TEST_1");

String value = messageResources.getMessage("label.somekey");

Yes, that's correct. If you're creating a multi-language site, you would also pass in a locale as a parameter to this method.
Originally posted by lavi per:
6. In my jsp file

a. If I just want to display any message from the property fle
<bean:message bundle="TEST_1" key="some.message.key"/>
Please confirm?

Yes, that's correct.
Originally posted by lavi per:
b. If I want to display the error message in the jsp page
Q - ?? how can i specify the resource bundle i.e key="TEST_1" or "TEST_2" here ?? and how do I then display the error messages using both html:error tag as well as html:messages tag.

Read the heading "Displaying Messages" in this link. If you want to use the default MessageResources, just don't specify a bundle attribute. If you want to use one of the alternate resources, specify bundle="TEST_1"
[ June 29, 2008: Message edited by: Merrill Higginson ]
lavi mendonca
Ranch Hand

Joined: Apr 24, 2002
Posts: 53
Thanks again Merrill for all your help especially considering that its a weekend. I will be trying this out at work tomorrow and will get back about the progress.

Its an ongoing project which started with Struts 1.1 and generally all the error messages are stored in the default *.properties file as specified in web.xml. But with my module as well as going forward, they want a separate properties file listing all the error messages specific to my module/ modules.

Thanks again and I will keep you posted,
lavi mendonca
Ranch Hand

Joined: Apr 24, 2002
Posts: 53
Hi Merrill - I tried the code you suggested and its working fine... Thank you once again for all your help and support. I really appreciate it.

Regards.
Merrill Higginson
Ranch Hand

Joined: Feb 15, 2005
Posts: 4864
Lavi,

You're most welcome. Good luck on your project.
lavi mendonca
Ranch Hand

Joined: Apr 24, 2002
Posts: 53
Hi,

Its been a while since this post, but i have run into a requirement wherein, i have a list of form fields that accepts user's inputs.(Search page). Once the user fills in the details and clicks Submit, the same page is displayed with the results of the search. Now this page contains the form fields (search fields) at the top with Submit button and results (with a radio button besides each row) at the bottom of the page with a Go button. If the user clicks on Go button without selecting any record via the radio button, I need the error message to be displayed just above the records/ results. Currently, it is displayed at the top of the page where i have placed the html:errors tag.

I am planning to have 2 properties on my formbean (ActionForm) corresponding to the radio element that user may select and another hidden field which will be populated on submit (via javascript) with the value of the radio element selected earlier. This hidden field will be placed on top of the results section And then in my validate method of the ActionForm, i will check that if this hidden field contains no value, then create an ActionError object passing the hidden field as the first parameter like the code below so that on validation errors, the error message is displayed next to the hidden field element.

ActionErrors actionErrors = new ActionErrors();
actionErrors.add("userId", new ActionError("error.missing.key");

Please let me know if this is the best way or is there some other better way to get the same results.
Any help/ inputs would be greatly appreciated.

Thanks.
Merrill Higginson
Ranch Hand

Joined: Feb 15, 2005
Posts: 4864
You don't need JavaScript or hidden fields to do this. Simply have each radio button use the same property name. You can then use either the Struts Validator Framework or an overridden validate() method to check whether the property is null, and if so display an error message.

Also, please don't post a new question in an existing thread (even one you started) that does not relate to the original thread. For the sake of making it easier for someone to search the forum for answers, it's better to ask the question in a new thread.
 
Consider Paul's rocket mass heater.
 
subject: Getting values from properties in validate-using multiple message-resources in struts