Struts2 file upload errors - java

I am a using struts2 file upload and my action class contains 3 private fileds with getter and setters
private File myFile;
private String myFileFileName;
private String myFileContentType;
I have some douts to clarify
We are passing only the file as parameter and bind it to the myFile, So how the application getting the file name and content type?
whenever I use myFileVariableName + "FileName" (if the file variable is myFile then file name variable is myFileFileName, if file is xxx, then file name is xxxFileName), I am getting the output, if i make any change to this format (ie,myFileVariableName + "FileName"), It getting null. Is it mandatory to use this format? Can I change it to any name I desire? If so, then how?
To get the content type, I should use jst "contentType" or myfileVariableName + "contentType". Is it also mandatory?
I assume, if I use a separate bean to store my request variables, all the parameters is bind to that bean variable. But in the case of file upload only the file variable ie, myFile in this example only get and set in the bean. fileFileName and contentType are null. If I declare these variables directly in my action class, then I get the values, but whenever I use a separate bean, only File variable can get and set, and the other two are null. Why?
If I use ModelDriven, the the same case happening, I can only get File variable and the other two variables are null. why?
I am only extending the "struts-default" in my struts.xml and no separate config for file upload, since it dont show any effect in my questions.

Action class for the file upload, declare a File variable to store the user uploaded file, two String variables to store the file name and content type. The fileUpload interceptor will auto inject the uploaded file detail via set 'X' ContentType() and set 'X' FileName(), make sure the method name is spell correctly.
The file upload function is depends on the “fileUpload Interceptor“,
make sure it is included in the Action’s stack. The lucky is, the
default stack is already includes the “fileUpload Interceptor“.
The fields userImageContentType and userImageFileName are optional. If setter method of these fields are provided, struts2 will set the data. This is just to get some extra information of uploaded file. Also follow the naming standard if you providing the content type and file name string. The name should be ContentType and FileName.
For example if the file attribute in action file is private File
uploadedFile, the content type will be uploadedFileContentType and
file name uploadedFileFileName.
Get Set Behaviour in Struts 2 : Assign value to a variable, not property value.
For example,
public class SetTagAction extends ActionSupport{
private String msg;
public String setMsg(String msg) {
this.msg = msg;
}
<s:set var="msg" value="%{'this is a message'}" />
Many Struts 2 developers thought that the set tag var=”msg” will assign the value to the associated action class via setMsg() method.
This is wrong, the set tag will not call the setMsg() method, it will only assign the “value” to a variable named “msg“, not the action’s property value.

Related

Passing a variable to #Value annotation for reading specific property from properties file

In my Spring boot application, a specific value needs to be read from the properties file depending on a string value returned from another function. My properties file is as follows:
A=value_a
B=value_b
A function returns either A or B, and stores it in a String variable called stringValue . I am looking for doing something along the lines of the following:
#Value(stringValue)
String propertyValue
However, I get the following message on my IDE:
Attribute value must be constant
I have tried to convert stringValue to a static final variable, but to no avail.
I do know that I can pass a specific key to be read from the properties file, such as the following:
#Value("${A}")
String valueOfA
My question is whether I can pass a variable to the #Value annotation?
#Value annotations are resolved during startup, when Spring context is built. Since stringValue would not be available at this time, you can't use it for injection purposes.
An exception to this scenario would be if the bean with #Value annotation is prototype-scoped, in which case a new instance of it would be created any time it's requested. Still, stringValue would need to be available to the Spring context in order to be used at injection point.
Without seeing more code, it's not possible to give you any more detailed answer.
You can autowire Environment in your application and use it to read from the properties file as it is supposed to be at runtime.( This is assuming all files where your properties are have been added to environment).
I will be posting my answer with assumptions as you have not updated your question, with all information I requested.
So your code would be-
lets call your class where your making a call to a function called getValue to get value of stringValue- Example. Now lets assume you are making a call to the function getValue in a method in the class Example called doSomething().
class Example{
#Autowire
private Enviornment environment.
private String propertyValue
public void doSomething(){
String value=getValue()// this is where u know whether
its A or B.
propertyValue=environment.getProperty(value);
// do whatever u want know
}
Thanks for the help guys! I read the values from the properties file into a org.springframework.core.io.Resource object, and then used that to retrieve the specific value that I required. The following was how I structured my solution code:
#Value("classpath:config.properties")
private Resource propertiesfile;
I then declared a java.util.Properties object and read the values from the Resource object into it.
Properties properties = new Properties();
try{
properties.load(propertiesfile.getInputStream());
}catch(IOException e){
logger.error("Parsing error while reading properties file",e.toString());
}
Finally, based on the value in my stringValue variable, I read the corresponding value from the properties file
String propertyValue = properties.getProperty(stringValue);
if your variable is another environment variable you can try in this format.
#Value("${${stringvalue}}")
where stringvalue is the environment variable.

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"));

spring messages.properties uses variable name

Is there a way to use a title instead of a variable name when overriding Spring's default messages using the messages.properties file?
For example, I used this
typeMismatch.java.lang.Integer={0} must be a number.
to create the error message "firstName must be a number.", but I would prefer more readability, like "First Name must be a number.".
Is there any way to do this?
You can customize the property for a specific field of a specific class. Say your model attribute is named foo and it has a property named firstName then you can declare a custom error message for that specific field using:
typeMismatch.foo.firstName=First Name must be a number
You can see this page for more information.

Design Pattern Questions in Java

I have a Design pattern Question in Java/J2EE
Problem Statement::
Suppose there are 2 files as below
XYZ.properties file --> name = value pair
abc.xml file --> attribute=value pair.
Both the above files have <name,value> pairs.
The question is "Design a component/jsp page such that you can read,edit,save the name,value pairs of either a Property file or xml file.?"
So which Design pattern would you suggest i should be using in Java.?
The name,values pair are then fetched and displayed in another jsp page where i should be able to read,edit,save the name,value pairs such that
1>read operation results in reading the name,value pair
2>Edit operation results in editing the name,value pair
3>Save operation results in saving the value for the corresponding name,value pair in database and consequently updates either the property/xml file.
**My Initial Analysis** : i would use a Factory design pattern since i have 2 files which have name,value pairs and at run time decide which one to choose depending on the name of file invoked,Once done i would pass the parameters to jsp file for Read,edit and save operation.Save would save the name,value pair to Database but i dont know how will it update the corresponding value for that name in either the property/xml file as well.
Is my Understanding correct ? If not please provide a design/solution in java for the same,such that READ,EDIT,SAVE operation for pairs in either ".properties file" or ".xml file" are carried out?
This looks like homework.
Without giving away too much, Properties can read/write both .properties and .xml files, more info on http://download.oracle.com/javase/7/docs/api/java/util/Properties.html.
The Factory Pattern would do the job.
Create an abstract class with abstract read, modify, save methods and getter and setter for key and value
create two separate classes for .properties and .xml implementation who extend the abstract class.
Whenever you want to save check for the instance of the class and call the appropriate method.
I think Factory pattern is correct. Make abstracted getInstance(fileName), read, create, update, remove methods.
As a suggestion, you might want to return implemented instance after checking into the file content -- whther it's XML (by checking XML header or presence of root tag) or it's a properties file.
Ideally, I would create a MyFileFactory class that looks like this
public class MyFileFactory{
public static final MyFileFactory getInstance(String filename){
//read the file header or first line to guess what instance to call
int fileType = getFileType(fileName);
if(fileType == MyFileFactory.XML_FILE)
return new XMLFileEditor(fileName);
else
return new PropsFileEditor(fileName);
}
public abstract readFile();
public abstract writeToFile();
public abstract editFile();
}
have these classes to implement the methods
public class XMLFileEditor extends MyFileFactory{
...
private File f;
}
and
public class PropsFileEditor extends MyFileFactory{
...
private File f;
}
And I think you are good to go.
If you want to save in database as well as in the file:
writeToFile(String new_Node_or_property){
//parseNode converts the property or XML node to an object
MyNode node = MyNode.parseNode(new_Node_or_property);
MyFileDAO.insert(node);//write a code that parse
// write here code to append in the file based on what
// filetype implentation it is -- XML, .properties, YAML whatever
}

Get command object

I am writing a spring 2.5 application and in my jsp I'm writing my own tags.
It's about a list of objects...when I change the number of rows that list shows(a combobox), I am doing a submit on my form returning back to the view(obviosly with the new number of rows returned).
When listing with my own tags I need to get the properties from my command object.
I have access to the pageContext object but I can't figure where the command object is stored.
By default, the command object is stored under a "command" attribute (request or session scope depending on your configuration of the sessionForm property). You can change that by setting the commandName property on your controller and your command object will be included in the model under this name (and not the default "command").
Once in your tag code, you can use request.getAttribute("command") or, if sessionForm=true, session.getAttribute("command") to get access to your command object (assuming the default name "command"). If you changed the name of the command using the commandName property then use that instead of "command".
Usually you wouldn't care in what scope the command is, so having access to the pageContext object, you can do a pageContext.findAttribute("command") and that will look it up in all scopes.

Categories