Use time type? Who will not, is it a few classes under java.util? Do you have any questions about the few classes under java.sql and java.text? Struts can not handle it in the time, can you do? In practical applications, I found that Struts did handle even some simple times (I don't know if the method I used is not right, but Struts did not take into account). By the way, you can also understand how struts will put the request parameters in the form to the Actionform. This afternoon, colleagues told me that there is no problem with the class with java.util.date type attributes into the database, and there is no problem to delete this property. At that time, I thought that the requestProcessor was wrong in ProcessPopulate (), so it sets a breakpoint and tracked in this method. Of course, it first calls the ActionForm's RESET () method, then call the requestUtils.populate () method that actually handles Populate (pass the request parameter to an actionform). Requestutils's static method first processes the method of processing Multipart (ie, file uploads, etc.), then put all the requests in the HashMap called Properties and loops: names = request.getParameterNames (); while (Names .hasMoreElements ()) {String name = (String) names.nextElement (); String stripped = name;!! if (prefix = null) {if (stripped.startsWith (prefix)) {continue;} stripped = stripped.substring (Prefix.Length ());} if (suffix! = null) {if (! Stripped.endswith (SUFFIX)) {Continue;} stripped = stripped.substring (0, Stripped.Length () - suffix.length () );} If (ismultipart) {Properties.put (Stripped, MultipArtParameters.get (name));} else {property.put (Stripped, Request.GetParameterValues);}}
The actual handles them are below: bean /utils.populate (bean, proties); where beans are accepting data, and Properties is all requested keys - value pairs (keys and values are strings, HTTP protocols Features). Take a look at the static (class) method of beanutils, how to deal with: // loop throughties.keyset (). Iterator (); while (Names.hasNext ()) {// Identify The Property Name and Value (s) to be assigned string name = (string) name.next (); if (name == null) {Continue;} Object value = Properties.get (Name);
// Perform The Assignment for this property setProperty (bean, name, value);
} It is a loop all request parameters, and the actual work is handed over to the setProperty method. Oh, it took a long time, this helder originally a proxy. Is this method still a proxy? Calculate it has 180 lines of code. This should be a homemade, wrong! Don't be deceived by some people's appearance! Some people go to work for 16 hours a day, they can be dedicated, and they can be played 8 hours. This class is: one of more than 20 rows in one IF (log.isticraceenabled ()) {}. LOG illustrates this. Struts is used by Jakarta Commons logging packages. It uses the priority is: log4j (4 read FOUR seems to be more meaningful, probably the meaning of logger for java, I listen to the year log si j, I feel very awkward, Haha), Java 1.4 logging api, Simple logging. The function is in turn weakened. It is recommended to use Commons logging to use Commons logging in the business method called by Execute (), or you want to remove the thousand thousand system.out.println () You will feel that Commons logging is a good stuff. Its usage is: import org.apache.commons.logging.log; import org.apache.commons.logging.logfactory; private / protected static log log = logfactory.getlog (dispatchaction.class); if you use Dispatchction, Then you don't define the instance of the log, because it already has a protected Log instance, which can be used directly. How to use is: if (log.isinfoenabled ()) {log.info ("Some Information.");} Logging divides the message into 6 levels, debug, error, fatal, info, trace, warn. For example, you want to record a message, it is just to give the user a warning, you can use Warn. Why do you have a judgment before each log.info ()? Is it possible if INFO is not allowed if the LOG level is allowed? of course not. Its role is to improve efficiency. For example, a message is calculated to calculate and the number of natural numbers (this message may be rare). Direct log.info () int sum = 0; for (int i = 0; i <10000; i ) {SUM = i;} log.info ("The sum of form 1 to 10000 is:" _sum); if Log.info is not allowed, and then 10,000 sums of sums of sums of money. Of course, if your computer is so smart as Gauss, I will directly log.info () everything. Gossip less, go back to 180 BEANUTILS.SETPROPERTY () methods.
This method first processes the NESTED property, which is the request parameter of XXX.xxx. We only look at the process of processing simple properties. The following code is a bit long, but it only does one thing: convert the request parameters of the string to the type of ActionForm. For example: You have an Integer UseERAGE in Actionform; then there may be http: // localhost: 8080 / xxx.do? Userage = 21 in the HTTP request parameter. The passing is a string, the goal is the spectrote integer. First of all, it will certainly find the corresponding ActionForm according to the use of this Action, if this ActionForm is called Userage, then save this userage to Type, Type's definition is: class type = null; get TYPE The code is long, because it is because it considers a lot of situations, such as DynaActionForm.
// Convert the specified value to the required type object newvalue = null; if (IISAARRAY () && (Index <0)) {// scalar value inTo array if (value == null) {string value [] = new String [1]; VALUES [0] = (string) value; newValue = convertutils.convert (String []) Values, TYPE);} else if (value instanceof string) {string value [] = new String [1] VALUES [0] = (string) value; newValue = converTutils.convert (String []) Values, TYPE);} else if (value instanceof string []) {newValue = converTutils.convert (String []) Value , type);} else {newValue = value;}} else if (type.isArray ()) {// Indexed value into array if (value instanceof String) {newValue = ConvertUtils.convert ((String) value, type.getComponentType ()) } Else if (value instanceof string []) {newValue = converTutils.convert ((String []) value) [0], Type.getComponentType ());} else {newValue = value;}} else {// value into scalar if ((value instanceof String) || (value == null)) {newValue = ConvertUtils.convert ((String) value, type);} else if (value instanceof String []) {newValue = ConvertUtils.convert ((String []) Value) [0], TYPE);
Else IF (Value.Lookup (Value.getClass ())! = null) {newValue = ConvertUTILS.CONVERT (Value.Tostring (), TYPE); // Here is my program's break point} else {newValue = value;} } Finally: Call some method settings for PropertyUtils. The first case of the following code is index, that is, the parameters you have passed by Field [0] = 123 in the request parameters, the second is the MAP type, the pass is MAP (key) = value. The parameter, the most general is to call the third method. if (index> = 0) {PropertyUtils.setIndexedProperty (target, propName, index, newValue);} else if (! key = null) {PropertyUtils.setMappedProperty (target, propName, key, newValue);} else {PropertyUtils.setProperty Of course, it is also possible to track, but there is nothing to do with this topic. The approximate process is: setProperty () method calls the setnestedproperty () method (or agent), call setsimpleproperty (), finally calling your setXXXXX () method written in Actionform through java.lang.reflect package, such as SetUserage (Integer) Userage), etc.
Now said why you can't populate java.util.date type data. The key is ConvertUTILS.CONVERT (), that is, the place in the above comments. If this method returns an object of a java.util.date type, of course, there will be no problem later. But I found that the actual operation is that newValue is still a string type, so it is wrong when it is called setXXX through the Reflection. You may be strange ConvertUTILS package, even java.util.date does not support, I also feel unavoidable. I thought it was the incoherent, and then entered this class, it is indeed: / ** *
Utility methods for converting String scalar values to objects of the * specified Class, String arrays to arrays of the specified Class. The * actual {@link Converter} instance to be used can be registered for each * possible destination Class. Unless you override them , Standard * {@Link Converter} Instances Are Provided for All of the Following * Destination Classes: *
*
Java.lang.bigDecimal * java.lang.biginteger * boolean and java.lang.Boolean * byte and java.lang.byte * char and java.lang.class * double and java.lang.class * Double and java.lang.double * Float and java.lang.float * int ANDA.lang.integer * long and java.lang.long * short and java.lang.short * java.lang.string * java.sql.date * java.sql.time * Java.sql.timestamp *
*
*
For backwards compatibility, the standard Converters for primitive * types (and the corresponding wrapper classes) return a defined * default value when a conversion error occurs. If you prefer to have a * {@link ConversionException} thrown instead, replace the standard Converter * Instances with instances created with the zero-arguments constructor. for * example, to cause the convecers for integers to throw an exception on * Conversion Errors, you could do this:
*
* // No-args constructor gets the version that throws exceptions * Converter myConverter = * new org.apache.commons.beanutils.converter.IntegerConverter (); * ConvertUtils.register (myConverter, Integer.TYPE); // Native type * ConvertUTILS.REGISTER (MyConverter, Integer.class); // wrapper class *
*
* @Author craig R. McClanahan
* @Author Ralph Schaer
* @Author chris audley
* @version $ revision: 1.12 $ $ date: 2003/01/15 21:59:38 $
* /
In addition, it will be instant to be a string, org.apache.commons.beanutils.propertyUtils.SetProperty () also has the ability to process? So I wrote a small program test.
Public class setsimplepropertytest {
Public setsimplepropertytest () {
}
Public static void main (String [] args) {
SetsimplePropertyTest setsimplepropertytest1 = new setsimplepropertytest ();
String datestr = "2004-01-01 19:00:00";
Test.DataBean DataBean = New DataBean ();
Try {
Org.apache.commons.beanutils.propertyUtils.SetProperty (DATABEAN,
"ReceiveTime", DateStr);
}
Catch (Exception E) {
E.PrintStackTrace ();
}
System.out.println (DATABEAN.GETRECEIVETIME (). TOSTRING ());
}
Running is throwing anomalies and proves that the handling cannot be handled.
The problem found, how can I solve it? Of course, the easiest way is to use the Java.sql.DateTime, which can turn it, etc., more complicated method is to write a ConvertUTILS. Of course, if you have a String recently, then there is no problem, but if you want to store it into the database, you have to turn. Especially when using the DAO mode, we may have trouble with the beanutils.copyproperties () method to achieve a ActionForm to a DTO (or VO) object. There is also a better way to define the attribute to improve another getter / setter method for Struts. This method is to see the JSP page automatically generated by MiddleGen. For example: private java.util.date savedate; // Ordinary set / get method public void setsavedate (java.util.date savedate) {this.savedate = savedate;} public java.util.date getsavedate () {Return this. Savedate;} // Prepared for Struts, the format of the period assumes 2000-12-31 23:59:59 public void setsavedatesstring (string savedate) {java.text.dateFormat DateFormat = new java.text.SIMPLEDATEFORMAT ("YYYY -Mm-dd hh: mm: ss "); this.savedate = DateFormat.Parse (Savedate);} public string getsavedatesstring () {java.text.dateFormat DateFormat = New java.text.SIMPLEDATEFORMAT (" YYYY-MM-DD HH: mm: ss "); return DateFormat.Format (this.savedate);} then use in JSP: