Digester bug, comments and enhancements
Hi, It seems that Bugzilla didn't swallowed the incidents I opened yesterday (I can't find them in Bugzilla queries), so I post them again in the list. [1] Digester enhancement. = I have set up a ObjectPushRule class that allows to have the digester use existing objects, instead of creating new ones when it encounters a pattern. For instance, you have two containers containA and containB that need to collect objects when the digester encounters tags or . Now, you are able to write: containA = new ContainA(); containB = new ContainB(); // Put objects into containA digester.addObjectPush("*/a", containA); ... processing digester.addSetNext("*/a", "add"); // Put objects into containB digester.addObjectPush("*/b", containB); ... processing digester.addSetNext("*/b", "add"); and process an XML file with intermixed and tags: and have the containA object contain all the "a", and containB all the "b". In order to fit with the rest of the digester engine (and because the Digester is a final class), I've added a "addObjectPush" method. The code for this is at the end of the e-mail. [2] Digester bug === As the Digester class uses a lot of BeanUtils and PropertyUtils methods, would it be possible to correlate the Digester.setDebug() method to also call the BeanUtils.setDebug(). Also, I think that the documentation should be improved to mention that ALL the classes and the methods accessed by the Digester must be declared public. Consider the following short example: class A { int id; setId(int id) { this.id = id; } } class B extends A { String name; setName(name) { this.name = name; } } In order for the digester to digest the tag (with the appropriate rules), you must have: - setName public - setId public - class B public AND class A public If you forget to declare A public (as I did), you end up with a B object partially initialized: "name" attribute is OK, but not "id". And no error message or hint from the digester!!! If you set the BeanUtils.setDebug(), then you obtain a "CANNOT HAPPEN:" message printed by the "populate" method! It should be more pleasant to have that method raise an exception when this occurs to facilitate the debugging, instead of allowing a fuzzy situation... [3] Digester enhancement = In regard of the previous comment, could it be possible (after version 1.0 release) to parameterize the access control level of the digester, when accessing methods. I am presently working on a framework (not struts related) where I use the digester to initialize the state of the framework. Later, I will have clients classes built upon that framework. In order to do the initialization of my objects, the digester imposes on me to declare all the classes and setter methods as public. The risk is that later, I open a breach in my objects and the clients classes will be able to modify the state of the framework. I think it would be cool to have either: - a global flag to tell the digester that it can access private or protected classes when accessing the setter methods. - or better, on a rule by rule cases, define the access level authorized. Pierre Métras And now, the ObjectPushRule stuff: = ObjectPushRule.java== package org.apache.struts.digester; import org.xml.sax.AttributeList; /** * Rule implementation that pushes and existing object * onto the object stack. When the element is complete, the * object will be popped * * @author Pierre Métras * @version $Revision: 1.0 $ $Date: 2001/03/10 23:18:29 $ */ public final class ObjectPushRule extends Rule { // --- Constructors /** * Construct an object create rule with the specified class name. * * @param digester The associated Digester * @param object The object to push onto the stack */ public ObjectPushRule(Digester digester, Object object) { super(digester); this.object = object; } // - Instance Variables /** * The object put on top of the stack. */ private Object object = null; // - Public Methods /** * Process the beginning of this element. * * @param attributes The attribute list of this element */ public void begin(AttributeList attributes) throws Exception { digester.push(object); } /** * Process the end of this element. */ public void end() throws Exception { Object top = digester.pop(); if (digester.getDebug() >= 1) digester.log("Pop " + top.getClass().getName()); } /** * Clean up after parsing i
Re: Javascript + localized messages
Hi Denis, > I'm using the i18n support in Struts in my applications, and am trying to > localize my client-side Javascript validation messages using > . I've tried > >var msg=''; >alert(msg); > > and > >alert(); > > and many other combinations, none of which worked for me. Has anyone been > able to use with Javascript? It should work both forms. I've all my JavaScript messages localized that way. Check that you have set the locale init-param in your action servlet, in the web.xml file: action org.apache.struts.action.ActionServlet ... locale true ... Pierre Métras
Re: Spaces in URL's
Hi James, > I'm using Struts and I noticed a problem with my web application when I was > running under Netscape 4.0. I was getting different results than if I ran > under IE. It turns out that the reason is because my links have spaces in > the parameter values: > > http://foo.com/app/foo.do?parm=I have spaces&parm2=I do to > > I'm using the tag to generate the links. It seems that this > code should do some sort of URL encoding on the parameters, or am I just > doing something wrong? It doesn't seem to me that my property getter > should worry about URL encoding the property value. > Yes, that's a known problem, first reported by Mathias Kerkhoff (struts-dev, Nov 13, 2000): Struts uses indistinctly Beanutil.filter() that substitute HTML characters, but not URI or parameters characters. Solutions have been suggested, using java.net.URLEncoder or an ad-hoc class (by me, struts-dev, Dec 06, 2000), but I don't think the corrections have been applied.;-( So, for the time being, either you encode your URL and parameters yourself (change the link tag and others), either don't put sensible characters in the URLs (' ', &, %, #, etc). Pierre Métras
Re: mapping.getInput() returns null
Hi George, Two months ago, when moving to 1.0, I was stroke by this one too... Extract from Craig's response: > > > mapping.getInput() works OK if you have the "input" attribute set in > > > the corresponding action tag in struts-config.xml So your strut-config.xml should be: >type="edu.miami.ir.dmas.SignonAction" > name="signonForm" > scope="request" input="/jsp/mainMenu.jsp" > validate="false"> > > > if you want the user to go back to "mainMenu.jsp" in case of input error. Pierre Métras
Re: logic:iterate and table row renderering
Hi, Some previous thoughts can be found http://www.mail-archive.com/struts-user@jakarta.apache.org/msg00204.html and in the following posts. Pierre Métras - Original Message - From: "Ted Husted" <[EMAIL PROTECTED]> To: "Struts List" <[EMAIL PROTECTED]> Sent: Tuesday, December 19, 2000 5:27 AM Subject: Re: logic:iterate and table row renderering > On 12/19/2000 at 1:16 AM Wong Kok Wai wrote: > > I'm using the logic:iterate tag to render a table. Now I need to show > alternating colours for odd and even table rows. How do I achieve this > effect together with the logic:iterate tag? > > Inside the HTML that you are iterating, you might be able to call a > JavaScript to set the font color for each row, and have the JavaScript > toggle a variable to return one color then the other. > > Of course, this script would be processed at display-time by the > browser, rather than by Struts. > > > -- Ted Husted, Husted dot Com, Fairport NY USA. > -- Custom Software ~ Technical Services. > -- Tel 716 425-0252; Fax 716 223-2506. > -- http://www.husted.com/ > > >
Re: Idle timeout Handling
Hi Shiraz, Have a look at the interface javax.servlet.http.HttpSessionBindingListener. If your classes implement it, they will be called on valueUnbound() when a session timeout occurs. Hope that solve your problem. Pierre Métras > I have just started working with the struts framework and like it a lot. > I have a question about idletimeout handling. The only way i can handle it > now is to do an idle timeout check at the start of perform method of my > action classes. > I cannot rely on getSession(false) check as i wont get a null session in > case i have a > session scoped form asscoiated with the mapping. I can check for some > attribute say user > profile that i bind to the session in the Authenticating action class. > > Is there someother way idle timeouts can be handled then doing it repeatedly > in almost every action class? > > Appreciate any response. > > > Thanks, > Shiraz
When locale negociation should occur?
Hi, The locale negociation to display localized messages occurs in the ActionServlet. So, a Struts application will not display localized messages before the first action. How can we negociate the locale desired by the user with the very first page displayed? Do we need a tag, so we can write an index.jsp page like the following: But this is not good because we have a configuration flag in web.xml and a tag for the first page... Or should each localizing tag check if the negociation has already occured, instead of ActionServlet? What do you think? Pierre Métras
Re: multiple forms on an input page
Hi Mark, > How do you handle the situation where I have multiple forms on one input > page? > > The docs are geared toward a one-to-one relationship between form and form > bean. I also saw a suggestion on handling cases where a form spans multiple > pages. > > Is it necessarily bad practice to combine multiple forms on a page? I > probably could avoid it but I'm sure I've seen systems that do this so I > want to know how you can deal with it using Struts. Why should multiple forms on a single page be a problem with Struts? You can put all the forms you want in a page, even if the common use is a one-one relationship. (1) Either they refer to different actions, and you have code like the following: ... form1 ... form2 with a corresponding struts-config.xml to manage the two actions, eventually returning back to the same page to let the user select the other action: (2) Either they refer to the same action, and the previous case is seen as a particular case... Pierre Métras
Re: Baffled: classpath problem as usual?
Hi Laird, > ... > To debug, I've got it to the point where > ActionBase.createActionInstance() tries to create an instance of my > Action. The action.xml file is set up properly. The call to > newInstance() results in a ClassNotFoundException. > > Is there some magic setting I don't know about that I need to set? How > does Tomcat (3.2, which I'm using) know to look in my .war file's > WEB-INF/classes directory? Do I need to specify this somewhere? Do I > need to add it to the classpath (seems like I shouldn't have to)? The ClassNotFoundException indicates that Struts can't find your class along the application CLASSPATH, using the Java classloader. Check these points: - Your .java file defines the class as belonging to the package my.app.packages. - Your .class file is under /webapps/WEB-INF/classes/my/app/packages when unwarred. - You defined it in action.xml using the class full name. Pierre Métras
Re: Proposed Solution to Non-Serializable MessageResources Class
Amend the servlet specification document to completely specify the accepted behavior. And what about Java2 1.4 for ResourceBundle? - (Local to Struts) Write a MessageBundle class that supports the Serializable interface, or less clean (but that's a problem where not everybody is concerned) don't cache messages, so you don't need to have an application scope object. We can add an option attribute to activate this behavior for the BEA users meanwhile ;-) Ways to solve (2) - Add localization information in the struts-config.xml file. If one wants to overide ResourceBundle file search, we could have your proposed syntax with adapted rules. - That way, an application can ask the configuration which languages are supported. You can write a tag that lists the languages and change the default locale for the user. I'm in a hurry. More comments tonight. Pierre Métras
Re: Proposed Solution to Non-Serializable MessageResources Class
Hi Craig, I really don't think the XMLization of the message files is a good idea. - Putting all the messages in only one file is not judicious as the various sections are treated by different translators. It's far more easy to give each of them a different file. - Also, some languages can use different local character sets. The croatean message file will use a local character set that will be incompatible with the japanese one. Putting all them in a single file will not make the task easier. - Message bundles files are already used for localization of other softwares. So translators know how to handle them. I don't want the translators to use an XML editor to do the work they used to do with their prefered world processor or editor. - Property files have a syntax adapted for large blocks of text. You can use the escape character \ at the end of a line to break a sentence into multiple lines. I don't think that such a facility is offered under XML syntax. - And last, XML syntax is too much verbose and had no advantage here (translators are frequently paid for the word!). The real i18n problems with the message files (apart from their format) is how to track changes between revision, how to check for completeness between different locale files and how to break them into smaller files (inclusion). If you really want to include extra information, for instance the default locale or the xml:lang, just put them in the struts-config.xml file, where they are used to describe the configuration of the Struts application. But please, don't try to mix application configuration with application data... Pierre Métras > I propose to load the messages from an XML > file (so that you can declare the character set, and use an XML-based editor). > For the Struts example app, the file would look like this: > > > > "-//Apache Software Foundation//DTD Struts Messages 1.0//EN" > "http://jakarta.apache.org/struts/dtds/struts-messages_1_0.dtd"> > > > > ... > > > > The existing mechanism (MessageResources) would remain available in 1.0 for > backwards compatibility, but would be deprecated in favor of MessageBundle in > future versions. > > What do you think?
Re: Proposed Solution to Non-Serializable MessageResources Class
Hi again, To temper my previous post. Yes, you can define org.apache.struts.MessageBundle to correct the serialization problem under some servlet containers. No, don't change the syntax of the message files. Pierre Métras
Re: Mildly complex situation
Hi Erik, > Also, how do you experts handle the issue of localizable messages > involving a count, as in > > There are {0} messages waiting. > > If {0} is zero, I'd like it to read > > There are 0 messages waiting. > > If {0} is one, I'd like it to read > > There is 1 message waiting. > > If {0} is two or greater, I'd like it to read > > There are n messages waiting. > > Do I *have* to break down and use a scriplet just to pick the right > message from the bundle, one for n=1 and one for the other cases? Are > there going to be problems with that approach in other languages (I > would think so)? Should I be constructing this particular piece of text > in the preceding Action class, and passing it as a session or request > attribute? Message formatting goes through java.text.MessageFormat calls. You gain access to all the formatting power of messages resources, like conditional formats... Instead of a cut and paste from the javadoc, have a look at http://java.sun.com/j2se/1.3/docs/api/java/text/MessageFormat.html where there's an example that you can apply to your problem. And perhaps you'll be able to solve the first one, too. Pierre Métras
Re: hangs, cpu-busy ...
Hi Andris, > If anyone has some ideas about where I can start debugging this problem, > please let me know and I will be very grateful. Have you tried to look at the generated java file for your form? Have a look into the directory /tomcat/work/YourApp/YourJspFile.java... You'll be able to follow what the server is doing between your 2 trace points P1 and P2. Another interesting track is to check the logs into /tomcat/logs. And last, tomcat has frequently a strange behaviour in consequence of a syntax error in the XML tags. Check your form that you don't close inadvertently a tag (not found in your example). Pierre Métras
Re: 1.0 taglibs
Hi Matthew, > Am I right in thinking that classes that appear both in taglibs and taglibs. > packages are migrating to the taglibs. packages and will be deprecated in > taglibs? You are right... Use the taglibs.XXX tags for v1.0 Pierre Métras
Re: Question about localization
Hi, The present approach allows also to process parameters in the message string, which would not be possible with the preprocessor one. For instance, you place the Zip code after the city in the US, but before in France (and there's no need for a state). With the localized resource, you are able to write in your message bundles: # {0} is the city # {1} is the Zip code # {2} is the state MyAppMessages_en_US.property file myapp.address.city={0}, {2}, {1} MyAppMessages_fr_FR.property file myapp.address.city={1} {0} And have the correct formatting, depending on the locale (not so good example, but I haven't a better in mind where parameters are reversed) of the user. Pierre Métras
Re: Question about localization
Hi Andrew, > Although it is convenient and neat to place internationalised messages in > resource bundles and load them on the fly, would this not add a big > performance hit to a large/heavily loaded system ? > > In previous designs I have concluded that this may be a problem and proposed > designs based on a preprocessor to create multiple JSP files, one per source > file per language. The preprocessor would use resource bundles, but the file > reading and extraction would be done statically, not on the fly. Then the > running system just has to worry about serving pre-compiled JSPs, and not > doing expensive file operations. This is a lot more cumbersome, but if > performance is important to you I think it is worth considering. If you have or are developping such a preprocessor, I'm sure the Struts authors will be eager to include it in a future release... In the mean time, we're stuck with the dynamic approach. The burden added to the server is not that big, depending on the size of your application and the number of different languages you need to support. All messages are kept in a cache, so the penalty is paid by the first user asking for a language not already loaded. As always, this is a trade between cost (ease of coding) and performance. Depending on your wealth (and time), you'll write such a preprocessor or buy a CPU upgrade... Another solution is to form teams of local web programmers and have them code the application in their native language. Manual preprocessing ;-) Pierre Métras
Re: Struts tags vs. bean, logic, form, and template tags
Hi Mike, > In http://jakarta.apache.org/struts/index.html, I see docs for the bean, form, logic, and template tag libraries, yet in the > distribution there's also a struts tag library. Is this simply the conglomeration of those 4? The struts tag library is the incompatible version 0.5. It's here to ease transition to version 1.0. Tags are similar in functionalities, but with incompatible names. In fact, from my experience, you should remove it after you have updated all your forms, to be sure that no 0.5 tag remains. Pierre Métras
Re: Question about localization (2)
Hi again, I just forgot to speak about "native2ascii". Sometimes it helps, for "exotic" languages, to process your message file with native2ascii. It translates your localized characters to ASCII with Unicode escapes for characters > 127. Pierre Métras
Re: Question about localization
Hi Doug and others, > The server we're creating needs to be usable simultaneously by multiple > users in multiple languages. Our app uses Struts/JSP and the Model 2 > architecture. What is the "best practice" or the "correct" Java/Struts way > of accomplishing this? > > Is there a way to use the same JSP pages, or is it best to have multiple > contexts (/en/, /fr/, etc)? > Here is a brief presentation of what you can do with Struts to localize your application. With version 1.0, you can set the ActionServlet to do locale negociation. Just put in you web.xml file: locale true >From now, when a user connects to your application and he has defined a locale preference in his browser, Struts will set a locale in his user session. This locale is then used to select the appropriate message resource file when your application displays a message through the tag. Different users can simultaneously use different languages, but generally (with Struts framework), a user only uses one language at a time. If you want to give to your user the ability to change the locale used, you need to write a bit of code that changes the Locale in the user session. And now, all the pages will use that new locale when displayed. If you have to display pages that keep the same structure from one language to the other, then the simpler way to localize your application is to use the tag. Store all your strings in the appropriate resource file. Don't put formatting in your code, but in the message strings, and use parameters. For instance, taken from MessageFormat javadoc: "At {1,time} on {1,date}, there was {2} on planet {0,number,integer}." Have a look at the java.text.MessageFormat and java.util.ResourceBundle documentation for more info. In particular, don't forget to double the quotes ' in the messages (like ''. This one turned me crazy...). When you want to include HTML formatting in your message other than line breaks, it's the time to think to create different pages for the different languages. I haven't investigated it yet, but I think that a lighter solution that language contexts can be found with conditional include, using the new Struts template tags. Depending on the locale, you the corresponding localized page. This would allow a global framework for your application, but with various looks depending on the language selected by the user. Pierre Métras
Re: using tags within tag parameter field ?
Hi Jim, > > I apologize as this is a generic jsp question and not specific to struts, but > hopefully this is a simple one (at least, I give a struts example below). Is > it possible to use a tag as an rtexprvalue within another tag's parameter > field? For example (assuming 'mytag' can take a rtexprvalue for parameter > 'param'): > > "/> No. You can't use tags into tag attributes. But with a little effort, you can rewrite your tag to support a syntax like: Else, you're stuck with ver.1 for now. Pierre Métras
Re: Preprocessing for a jsp
Hi Andre, It seems there's no problem with your configuration files. Could you post the top of your exception trace? Pierre Métras
Re: How to dynamically initialize form:select ?
Hi Michael, > Or in other words: does struts allow for some convenient means > to initialize a page upon creation ? Some kind of PreAction ? I add a similar problem and requested for such a feature. Now, in Struts 1.0, you can use the ActionForm.reset(mapping, request) to fill your form with some values, before auto-population by Struts. Based on the request parameters or the mapping, you can detect if it's a first time initialization and do what you want. What can be disturbing is that Struts always comes after you and replaces your values with the request parameters values, but you shouldn't be concerned when you want initialization. If you're using version 0.5, bad luck! I did the move to 1.0 for that reason... Pierre Métras
Re: Preprocessing for a jsp
Hi Andre, > Looks like i made some wrong configuration in the xml-files, because i get > a java.lang.ClassCastException when the servlet is called. We need a little more information to help, because a Cast exception can occurs almost everywhere... Which version of Struts are you using? And give us an extract of your configuration file, with the stack dump. Pierre Métras
Re: When Oh When Do We Validate?
Hi Craig, > Pierre Métras wrote: > > > As my design seems to be the *bad* one, I think I will have to change my > > code (explode my actions in struts-config.xml to create action > > /doSomethingInit and /doSomethingValid, and attach an "input" value only to > > /doSomethingValid, change all my JSP forms with these URL, and in the move > > suppress the now unused "action" parameter...). And Craig will have to > > rollback the CVS :,-( > > I'm not convinced that it would need to be rolled back -- or at least not > completely. > > Independent of the actions versus sub-actions question on application > organization, you also pointed out a real problem -- in the Struts 1.0 code as > it was before this change, consider the following scenario: > * You declare your action to require a form bean > * Your form bean wants to do validation > * You forget to define an "input" parameter > in the action mapping > * Struts never calls your validate() method > * Your action method gets called, probably > assuming that validation was successful, > and relies on incorrect assumptions. That's what happened to me. My database was corrupted because I thought that the ActionForms information was valid when I forgot to add the "input" attribute to the . > > This seems like a Bad Thing for a framework to allow when the developer simply > forgets to update a configuration file :-(. > > As the code sits right this minute, processValdiate() performs the following > steps, where a "true" return says "go ahead and call the action". > (A) If there is no form bean, simply return true > (B) If the request was cancelled, simply return true > (higher level logic will skip the call to the action) > (C) Call the validate() method. If it returns no errors, > simply return true > -- from here on you know an error occurred -- > (D) If this is a multipart request, roll it back > (E) Was an input form defined? If not, throw > an error 500 (internal server error) to document > the mis-configuration problem. > (F) Do a RequestDispatcher.forward() to the input form, > and return false. > > >From what it sounds like, there are particular concerns about step (C) -- > validate() is always called -- and step (E) -- multipart requests are rolled > back on validation errors. I don't really have a problem with either one of > them, but others might. > > Can we come to agreement on what the recommended sequence of steps should be? In fact, I would move the question on another view. Should the tag be a descriptive or behavioral tag? Do we want to put in it information to define the Struts application (which classes are used, where to redirect errors, etc.) or must we tend to put into it relations between application organization? In my opinion, the first situation is encountered presently: we define in the tag the different files/classes related to that action. Tha's no more than grouping. The problem occurs when we decide to deduce a behavior from it: if the "input" attribute is not present, it infers that the programmer doesn't want to have validation... To justify this, I can imagine numerous use cases where one need or not validation, or even partial validation (depending on the mapping). My present conviction is that the validation is context dependant, and that the most flexible place to take the decision to validate or not is in the validate method itself, when the programmer can analyse the context (within the ActionForm, or analysing the request or mapping). So I vote for (C) and call validate all the time. And as I said in a previous post, if you provide one of a "mustRoolback" property in ActionForm (to allow local decisions) or a setRollback method in servlet (for global behavior), the programmer can decide in the "validate" method what following he wants: rollback upload or not. Again, I vote for (D) and let the programmer take the decision. Maybe, another adhoc solution is to add now an attribute to desactivate vali dation, like in the ol' time of ValidatingActionForm... As you said, we can introduce other more "workflow" tags in version 1.1 to allows the definition of a validation process from the struts-config.xml file... And then let Struts generate the ActionForm file, and why not, the JSP page? But that's another story... Pierre Métras.
Re: Moving from 0.5 to 1.0: an experience, and design comment
Hi Jean-Baptiste, > > This doesn't sound right to me at all. > I've always relied on the presence of the input field to perform validation or not, > and I think it's far more easier to switch validation on or off by setting this > entry rather than to do it in the code, using the mapping and or request. This is > just declarative vs programmative. > > Here's a typical usecase I have that, if I'm not missing something, would have to > be modified if you made such a change: > - The user clicks on a link to change his personal information > - The action is configured with an actionForm, but without input, so that the > action can have access to the form, retrieve the info from the database, populate > the form, and forward to a JSP page. At this step, the form is empty, or just > contains the key of the user we're interested in. > - The user modifies the information and submits the form. This action is configured > to use the same form class, but now has an input parameter, so that the information > the user submits is now validated. > > This design is used in a lot of cases, and I don't understand how validating the > form even if the input parameter is not there would help us, and I don't see what > it would add. > > Am I missing something? Now I understand the underlying problem, and I think I have reported some origins of it in my other messages on design with Struts. With version 0.5, one can decide easily if he wanted or not validation to occurs in the ActionForm: you only had to choose between ActionForm or ValidatingActionForm interfaces. With version 1.0, the two interfaces where merged in a single class ActionForm, and there was no simple way to discriminate between validation or not, apart from assigning a value to the "input" attribute. So the problem is really, when Struts decides (on what criterium) to call the validate function of ActionForm? Either programmative or declarative... With my design to group under one action corelated subactions, perhaps I have selected the wrong way to use Struts. To reproduce your use case: - The ActionForm is first called on a URL like "doSomething.do?action=Init". - Based on the request parameter (or the ActionForm property "action", if you defined it), I can decide to retrieve info from the database but to to abort the validation, even if the "input" attribute is defined. - Then I forward to "edit" that present a JSP page to the user. - When the user submit the form, I come back on the URL "doSomething.do?action=Valid". Taking the action request, I can decide to validate the whole form and redirect to the "input" page if an error occurs. As my design seems to be the *bad* one, I think I will have to change my code (explode my actions in struts-config.xml to create action /doSomethingInit and /doSomethingValid, and attach an "input" value only to /doSomethingValid, change all my JSP forms with these URL, and in the move suppress the now unused "action" parameter...). And Craig will have to rollback the CVS :,-( Am I alone to have fallen in that trap? Pierre Métras
Re: Moving from 0.5 to 1.0: an experience, and design comment
Hi Craig, > My thinking on multi-page forms is definitely not totally finished yet, but my > operating assumption has been that you'd have separate actions for each page, so > you could therefore direct errors back to the individual pages. The logical > "grouping" of the actions could happen by subclassing a common base class that > represented the shared logic. You would declare the same form bean for all of > these actions, and you'd store this bean in session scope. (As a side benefit, > you can also use "next" and "previous" logical forward names directly, without > having to calculate which page you are on in sequence, and then know what the > next and previous logical names are.) > > It is still messy, because the validation method (at least) needs to know what > fields came from what pages, and there is no convenient way to communicate that > information so that it only needs to be specified once. I think that a final > solution to this is probably going to need to wait for a 1.1 time frame, when we > can figure out how to deal with it cleanly. I believe that the current approach > works quite well for single page forms (with the outstanding issue of people > that want to deal with dynamic sets of properties, rather than fixed ones, which > will need to be a separate extension if we decide to support it). Thanks for your explanation. I've not yet played with multi-page forms, though the example I included had one. Your design allows to discriminate on the mapping for the validation call, and make local validation simpler. My design problem was to consider the ActionForm as the central element and to offer different views on it with the different forwards of a unique Action, instead of creating multiple ActionForm. I will wait for version 1.1 to change my code. Pierre Métras
Re: Moving from 0.5 to 1.0: an experience, and design comment
Hi Craig, > OK, now I see what you are after. I'm modifying the logic of processValidate() > to do the following basic steps: > * If there is no form bean, skip validation > * If the request was cancelled, skip validation > * Call the validate method: > * If no errors, continue normal request handling > by calling the action etc. > * (At this point, we know a validate error occurred) > * If this is a multipart request, roll it back > * If there is no input form defined, report an error 500 > because the application is mis-configured (a form bean > is defined, but no input page to return to) > > Does that sound right? Excellent. I think you should add an attribute to enable/disable automatic rollback for multipart forms (when someone upload a few MB file and it failed because his upload logon is invalid, that's cool to let him a second chance to enter the logon (in the "input" page) without resubmiting the file...) and it will be perfect. Pierre Métras
Re: Moving from 0.5 to 1.0: an experience, and design comment
Hi Craig, > > > > > mapping.getInput() works OK if you have the "input" attribute set in > > > the corresponding action tag in struts-config.xml > > > > Yes. I found that one later. I didn't investigate why it worked in version > > 0.5, perhaps due to new bugs that I introduced bugs when I rewrote my > > struts-config.xml file. > > > > Also, I suggested yesterday a change in the ActionServlet.performValidate > > method to the struts-dev list, for calling the ActionForm.validate even when > > the "input" attribute is not set. > > > > What would the controller servlet do if the validate() method returned errors in > this case? It doesn't know where to send the user back to (that's what the > input attribute is there to tell it), and there is no other current mechanism to > let the action that is called know that there were validation problems. Yes, the "input" attribute is necessary when the validation fails, but not when it succeeds! What I proposed is to generate a server error when "input" is not set, and that the servlet can't find the "input" for the action. That's a programming error not to have correctly defined the struts-config.xml file, that's to say have defined a validation method without a corresponding "input" form to display the errors. But when "input" is not defined and the validation doesn't fail, it seems to me that not calling "processValidate" (in fact existing at the beginning of the function) is a source of bugs. The presence of the "input" attribute is now the only mean to tell Struts that your ActionForm is in fact an (old) ValidatingActionForm. I rather prefer to have the call to "ActionForm.validate" occurs every time (and the default "validate" returns "true"), now that ActionForm are ValidatingActionForm, and let the coder decide if he needs validation when he redefines the "validate" method (and he can take a decision at that moment, as now he has access to the mapping and request parameters). Before deverting to a design comment, a documentation bug: The "input" attribute is declared mandatory if the "name" attribute is set, from the DTD. input Context-relative path of the input form to which control should be returned if a validation error is encountered. Required if "name" is specified, else not allowed. This check is not done, and I don't think we need it. Now, a long comment on design with Struts... In fact, my opinion is not definitely set, when studying the Struts example, and perhaps due to a design deviation...: >From that extract, the check for validation will only occur on the "saveSubscription" action only. A user can change his subscription information, but defer the validation to the moment when that info is saved to database. This behavior can be interesting for multipages forms, but should we define it in the configuration file or in the "validate" method? The example uses a "N Action - 1 ActionForm" design that allows to define an "input" attribute for each Action error processing, where I used a "1 Action - 1 ActionForm" one in my application: I've used and definition as a way to group related JSP pages, for instance, editing and displaying a user subscription. Selecting between the different sub-actions is done using a URL like "/subscription.do?action=init". All treatments concerning the subscription process are centralized in the "SubscriptionAction" class. A problem with such a design is that when an error occurs, you can't redirect to a default error page (it depends on the subaction you were performing)... In that case, I would think that the "validate" function should decide which error forward should be used: validate() - local validation on page 1 data if error, forward to errorPage1 - local validation on page 2 data if error, forward to errorPage2 - global validation if error, forward to inputPage Comments? Have others "missed" the original Struts design? Now is not the time to change version 1.0 API, just before release (and now that my application runs without it). But is it a desired extension for 1.1? Pierre Métras
Re: Moving from 0.5 to 1.0: an experience
Hi Luke, > mapping.getInput() works OK if you have the "input" attribute set in > the corresponding action tag in struts-config.xml Yes. I found that one later. I didn't investigate why it worked in version 0.5, perhaps due to new bugs that I introduced bugs when I rewrote my struts-config.xml file. Also, I suggested yesterday a change in the ActionServlet.performValidate method to the struts-dev list, for calling the ActionForm.validate even when the "input" attribute is not set. Pierre Métras
Formless actions
Hi, I have to code a menu. Depending on the user interaction, different features will be executed. These features are Struts actions *.do URL with associated JSP files for the views. The menu is included on all the forms. Should I use an Action class to manage the menu processing, knowing that no input form will be associated with it? So the mapping will look like: Using the Struts design has the advantage that the foward mapping allows to use logical names for the features. This indirection level allows to add or modify a feature without impacting the others (just place a ). On the other side, Struts mechanic is a bit heavy for a servlet whose role will be to forward to another feature based on a request parameter, that's to say a big sequence of if-else. Subsidiary question: I have a menu option that is used to switch the language used for display, and then return to the calling feature. Can the menu know from which feature it is called, without having to add another parameter in the request? Is the Referer header available in that case? Any opinion welcome. Pierre Métras
Re: Difference between action.xml and struts-config.xml
Hi Koen, Use the struts-config.xml if you want to create a new application. It's the new version 1.0 file format used by struts. For compatibility with version 0.5, Struts can read the old action.xml file. The version you choose to use is defined in web.xml: action org.apache.struts.action.ActionServlet config /WEB-INF/struts-config.xml ... Pierre Métras - Original Message - From: "De Smet Koen" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Friday, November 24, 2000 8:05 AM Subject: Difference between action.xml and struts-config.xml > Hello, > > We're looking at struts for a few days now and it looks good, but I was > wondering the following: > > What's the difference between action.xml and struts-config.xml for the > action mapping? I see that in both files you nearly define the same things. > > Can somebody explain us the difference please? > > Thanks, > > > Koen De Smet > The Capital Markets Company > T +32 3 740 11 96 > F +32 3 740 10 01 > Mobile +32 497 51 88 51 > e-mailmailto:[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]> > webhttp://www.capco.com/ <http://www.capco.com/> > > > > The information in this email is confidential and is intended solely > for the addressee(s). > Access to this email by anyone else is unauthorised. If you are not > an intended recipient, you must not read, use or disseminate the > information contained in the email. > Any views expressed in this message are those of the individual sender, > except where the sender specifically states them to be the views of > The Capital Markets Company. > > http://www.capco.com > *** > >
Re: logic:equal help ?!?
Title: logic:equal help ?!? Hi Michael, That's a classic: rule true Remove the / from your opening tag and everything will work as expected. The XML parser is not smart enough to complain that it encountered a closing tag without opening... But take care that the comparison will try to check for String comparison, and not the boolean true... Pierre Métras - Original Message - From: Laufer, Michael To: 'Struts' Sent: Friday, November 24, 2000 6:41 AM Subject: logic:equal help ?!? Hi, I've just started with the logic-library of the Struts framework I'm using the following code to create a dynamic html-table: true No I'm facing the following problem: my rule true code seems not to work correctly. My impression is that it doesnt compare the property "isActive" with the value "true".Because I'm always getting the text "rule true" in my table. Am I using the equal-tag not correctly or am misunderstanding here something terribly ?? Any help would be appreciated. Thanks in advance. Mike
Moving from 0.5 to 1.0: an experience
Hi, This post is quite long but it traces the situations I encountered when moving from Struts version 0.5 to 1.0Beta. I hope it can be of help for others having to do the move. It took me 2 days to port a small application (46 java, 20 jsp files) clearing sometimes the code to benefit from new features when I was debugging a file. I have some work left to check that all features are running like before, but I think the most tedious part of the work is gone. Pierre Métras PS: I include my version of LinkTag.java to support JavaScript events, too. Though not HTML 4.0 conformant, I hope it will find a path in version1.0;-) ~From 0.5 to 1.0B Binaries = - Download tomcat 3.2B7 - Download Struts 2000-11-20 - Susbtitute to existing files and directories. Java files == ActionForm beans --- - Change "class X implements ActionForm" to "class X extends ActionForm". - Change "class X implements ValidatingActionForm" to "class X extends ActionForm". ValidatingActionForm beans - - Change "import org.apache.struts.ValidatingActionForm" to "import org.apache.struts.ActionForm". - In validating classes, change "validate" method to return an ActionErrors instead of String[]. Clean the code accordingly. Add "import org.apache.struts.ActionErrors; import org.apache.struts.ActionError;" On ActionForm - Change checkboxes processing in "reset" method. Usually, just set to null the corresponding property. - Add reference to ActionMapping for "reset" method: "import org.apache.struts.ActionMapping". Action --- - Class "ActionBase" is now deprecated. Change to "Action" - Change "MessageResources resources = getResources(servlet);" to "MessageResources resources = getResources();". This change could have been flagged deprecated to ease the transition... - "ActionMapping.getInputForm" is now deprecated. Use "getInput" in place. - "BeanUtils.getPropertyValue" changed to "PropertyUtils.getProperty". - "ActionMapping.getFormAttribute" changed to "ActionMapping. - ATTENTION: "Action.perform" has lost its servlet argument. If you miss the change, your source will compile but your "perform" method will never called! The symptom: an empty page in your browser. The old "perform" signature should at least exist with a deprecated signal to ease the transition form 0.5 to 1.0 code. - The code can be cleaned here with the new classes and methods ActionError, ActionForm.reset... For instance, if you have a menu Action class, the perform method will only have to do the switch to return the mapping. You don't need anymore to retrieve ActionForm instance attributes (was it from session or from request?) and initialize their fields (and don't forget to set the attribute again): all this can be done in one place, the ActionForm.reset method. First run == At that point, everything compiles. Copy the class files to the server. Start Struts. Wow, there's new traces while the action.xml file is processed. - 404: /index.jsp not found! OK. Right access on directory tomcat/work is not set properly. - org.apache.jasper.compiler.CompileException: Attribute onMouseOut invalid according to the specified TLD has not yet been modified to include JavaScript events handlers (I have to modify the TLD file a generate a personalized struts.jar). Hope this will be done in final v1.0. It couldn't have run at the first shot. Ok, now let's look at the JSP... JSP - Change <%@taglib uri="struts" prefix="s" %> to <%@taglib uri="struts-form" prefix="sf" %>, etc. - Update to the appropriate or or ... - Change every JavaScript event handler to use lower case: "onMouseOut" becomes "onmousout" now! Mama mia... - org.apache.jasper.compiler.ParseException: Unterminated user-defined tag: ending tag not found or incorrectly nested Argh! The LinkTag in org.apache.struts.taglib.form is brand new and different from the one in org.apache.struts.taglib. Well, I have to patch it again and regenerate the struts.jar. - org.apache.jasper.JasperException: Unable to compile class for JSP: java.lang.NullPointerException Oops! I forgot to move the LinkTag from "org.apache.struts.taglib" to "org.apache.struts.taglib.form". Not a really usefull error message from tomcat! - Change to , to , to ... But now with , an exception is thrown if the value is null. In version 0.5, would have returned false... So, don't forget to enclose the tests in ... Test ... - Change to I would suggest using a filter="html", instead of any arbitrary value as suggested in the documentati
Re: Chaining controllers and passing parameters
Hi Craig, > You can actually include parameters in the request URI of the forward, but these > wouldn't really be dynamc. On the other hand, request attributes are still > maintained even if you forward to a "subfunction." I'll do that for now. Having them in the forward was a way to hide the mechanics behind that: a request parameter or looking and pre-instancing the callee ActionForm or something else... > One of the ideas I've been thinking about (for a Struts 1.1 timeframe) is to > support a more "workflow" oriented mechanism for defining actions. The thought > would be that an application developer would decompose the business functions of > the application into discrete "tasks", and then glue them together with > "scripts" defined in the struts config file. Struts could then include a > standard Action that executes the script -- the net effect would be to reduce > (or possibly eliminate) the need to write Action classes yourself. In such an > environment, chaining functions together would become as simple as writing the > appropriate tasks into a config file. > > Does this sound like an interesting direction to pursue? I'm definitely interested in that idea and I would like you to developp on that subject after the release of version 1.0. I can't think of a simple "script" definition with a semantic rich enough that would lend to Action classes disappearance. Even identifying the discrete "tasks" seams a challenge to me. It just reminds me of the today definition of a "logon" action and the proposal of the inclusion of the tag into the libraries... Pierre Métras
Re: Struts User list Archives.
Hi Wes, Start from here http://archive.covalent.net/jakarta/struts-user/2000/10/0009.xml Pierre Métras - Original Message - From: Wes Goggan To: '[EMAIL PROTECTED]' Sent: Wednesday, November 22, 2000 2:12 PM Subject: Struts User list Archives. Hello, I just subscribed to the Struts user list and would like to know where the archives are. I am particularly interested in information on how to get Struts to work with Weblogic 5.1 Thanks, Wes
Chaining controllers and passing parameters
Hi, How can we chain controllers and pass parameters in the MVC model? Let's start with my understanding of the Struts model. In a theorical world, we should have a sequence of events from the user on the view that generate actions on the controller side, which display a new view, and loop... A controller is called with a "*.do" URL, that forwards to a "forward". But a forward can be a JSP page (a view), or another controller (a URL like "/subfunction.do?action=Init", look into the example struts-confi.xml) that in turn look for a view... A mapping is the association of a controller and multiple forwards. An ActionForm is used to manage data between the various forward: passing data from the controller to the view. Each view expects one associated ActionForm (declared in the tag). But passing data from controller to controller is not that easy, because the calling controller don't know a priori the ActionForm type expected by the callee. A solution is to pass request parameters, but forwards don't have parameters... Do we need a setParameter(String name, String value) method in ActionForward in order to write: perform(...) { ... ActionForward forward = mapping.findForward("result"); forward.setParameter("action", "initChain"); return forward; } How other do that? Pierre Métras
Re: Re[2]: thought on design
Hi Neg, > PM> if (!validA(fieldA)) > PM> { > PM> errors.add("fieldA", new ActionError("classX.fieldA.notValid")); > PM> } > PM> ... > PM> return result; > PM> } > > How would it be written to browser? > As "fieldA" - ? > Or i18n can be applied to field name too? "fieldA" is a constant key to map errors in the ActionErrors collection, so you can decide what to do with them. "classX.fieldA.notValid" is a key to find the appropriate error message in your resource file (i18n applied). There's no way for now to render the error to the browser. What is missing is something like that would display the associated error message on your form. You can try to write it and propose your code for 1.0 inclusion... Pierre Métras
Re: thought on design
Neg wrote: > Now the strings that the validate function returns should identify which > parameter has failed validation, perhaps in say this format... > > parametername/error.text.key > Have a look at the new ActionError and ActionErrors classes in version 1.0. Though there's not yet an accompanying tag to display specific errors, they do what you've described: You have to write your "validate" method like this: public ActionErrors validate(ActionMapping mapping, javax.servlet.http.HttpServletRequest request) { ActionErrors errors = new ActionErrors(); if (!validA(fieldA)) { errors.add("fieldA", new ActionError("classX.fieldA.notValid")); } ... return result; } > When processValidate calls validate on the ActionForm, it can check to see > if any of the failed validations are on the same page as the one that was > just submitted. If so, redisplay the form with the errors *for just this > page*. > > If there are no errors on this page, then there is a choice of 2 things > depending on what the user requested. > > 1) If the user has requested 'submit the whole form', then take the user > back to the page with errors in it. > > 2) If the user has request to move to a different page in the form, then > allow them to do this and if the page they are moving to has validation > errors, then display them. I've not tried it, but when the "processValidate" fails, it tries to return to the input form, setting the errors in the request. From there, you should be able to take this kind of decision. You can find which fields have errors and decided then on which page you want to redirect the user. Just like the discussion on global/local validation, I don't think you can factorize a general behavior for error processing. Suppose -- that's a crazy example -- that you have a login form with 2 pages: one for the login name and the other one for the password. If the validation fails, should the code decide to present the login or the password page? Only you can take the decision to include business rules like "the user must clear the password if he wants to change his login name". Pierre Métras
Re: getting servlet context attributes within action
Hi Jim, As a general rule, use only locale variables in your Action class as there's only one instance but numerous threads wanting to access the methods and properties. >From your code, it seems you're using version 1.0 of Struts. The servlet will be set via the "setServlet" method when needed, so keep the default method. You just have to write your specialized "perform" processing. And in that code, the "servlet" property is set, so you can write: public class LoginAction extends Action { public ActionForward perform(ActionMapping mapping, ActionForm form, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws java.io.IOException, javax.servlet.ServletException { // Obtain the connection to the DB ConnectionPool pool = (ConnectionPool) servlet.getServletContext().getAttribute("com.hotu.intra.db.DB"); ... Pierre Métras - Original Message - From: "Jim Newsham" <[EMAIL PROTECTED]> To: "struts-user" <[EMAIL PROTECTED]> Sent: Tuesday, November 21, 2000 9:47 PM Subject: getting servlet context attributes within action > > > Hi, > > I'm trying to set up a global resource as described in the Struts User > Guide (under the heading "An Aside: Accessing Relational Databases"), > by creating it in a startup servlet and attaching it to the servlet > context as an attribute. Within my Action class, how do I retrieve the > attribute? I tried calling Action.getServlet() as shown in the code > snippet below, but this seems to return null. > > > public class LoginAction extends Action { > > private DB db; > > // constructor sets up db access > public LoginAction() > throws ApplicationException { > super(); > > Servlet servlet = getServlet(); // this is returning null ! > ServletConfig config = servlet.getServletConfig(); // this is line > 29 > ServletContext context = config.getServletContext(); > this.db = (DB) context.getAttribute("com.hotu.intra.db.DB"); > //this.db = (DB) > getServlet().getServletConfig().getServletContext().getAttribute("com.hotu.i ntra.db.DB"); > > if (db == null) { > throw new ApplicationException(ApplicationException.DB_INIT_ERR); > } > } > > > > } > > /caucho.com/http/host/: java.lang.NullPointerException > at com.hotu.intra.LoginAction.(LoginAction.java:29) > at java.lang.Class.newInstance0(Native Method) >at java.lang.Class.newInstance(Class.java:237) > at > org.apache.struts.action.ActionServlet.processActionCreate(ActionServlet.jav a:1263) > > at > org.apache.struts.action.ActionServlet.process(ActionServlet.java:1232) > at > org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:435) at > javax.servlet.http.HttpServlet.service(HttpServlet.java:115) >at javax.servlet.http.HttpServlet.service(HttpServlet.java:83) > at > com.caucho.server.http.Invocation.service(Invocation.java:236) > at > com.caucho.server.http.CacheInvocation.service(CacheInvocation.java:142) > > at > com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:211) >at > com.caucho.server.http.HttpRequest.handleConnection(HttpRequest.java:145) > > at > com.caucho.server.TcpConnection.run(TcpConnection.java:139) > at java.lang.Thread.run(Thread.java:484) > > > > > Thanks in advance, > > Jim Newsham > >
Session tracking problem?
Hi, I'm testing the transition to Struts v1.0. Is there a known problem with the session tracking with Struts (last night build) + tomcat 3.2B7? When I disable cookies on IE5.5 (prompt to accept cookies) and start my application, I observe the following behavior: [1] Firts page Proposed cookie JSESSIONID=9w07jwaxv1 (refused, of course) used for a menu in the page encode the cookie:
Re: Formating data for display
Hi Mario, I would think the best place would be in resource files to contain the format to use, and put specific code in ActionForm beans. As messages in resource files are already processed by java.text.MessageFormat, you don't need a special tag to display a localized currency, for instance: In your English property file, write amount.value=The amount is {0, number, currency} and use it with to display The amount is $123.45 when the user use an English locale. Your ActionForm bean can contain the code to parse locale dependant formats, based on the user locale, and pass it to your business objects in an independant format (converting the currencies values to DM, for instance). Pierre Métras - Original Message - From: <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Monday, November 20, 2000 4:13 AM Subject: Formating data for display > Hello all, > > after playing a while with struts i have a little question. Where is the > best place to put the formating code for the data, e.g. to formate date > and currency values. A special tag, the form bean + action class or the > model beans ???. > > The example application contains no hints in this direction. > > Any suggestion are welcome. > > bye > Mario >
Re: checkbox-problems ?
Title: checkbox-problems ? Hi Michael, That's a normal behavior. When you first check your check box, your browser sends the value to your Struts application, and it modify the corresponding property in your ActionForm. Next time, when you uncheck the checkbox, no value is transmitted by the browser (empty values in HTML forms are not transmitted), and your ActionForm property keeps set (if you haven't removed it, but generally you don't if you want to display the other properties...). In Struts v1.0, there's a reset method that is called just before initializing the form. From that method, you can decide to reset all the checkboxes to their value from a database, for instance. If you're using v0.5, search in the mailing list for different solutions (but incompatible with v1.0). Pierre Métras - Original Message - From: Laufer, Michael To: 'Struts' Sent: Monday, November 20, 2000 3:10 AM Subject: checkbox-problems ? Hi, I have a problem with JSP and using Struts-checkboxes: my code-fragement: my problem seems to appear with the -tag whenever I redirect my request to the JSP again, the checkbox is set, it doesn't matter, if it was checked before or not. Is there anything I'm missing ?? Any help would be appreciated. Thanks in advance, Mike
Re: encodeURL tag
Hi Martin, You should be right in the terminology. I derived the name of the tag from the javax.servlet.http.HttpServletResponse method: public java.lang.String encodeURL(java.lang.String url) // Encodes the specified URL by including the session ID in it, or, if encoding is not needed, returns the URL unchanged. But I don't mind to change it to ... Pierre Métras - Original Message - From: "Martin Cooper" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Friday, November 17, 2000 12:23 AM Subject: Re: encodeURL tag > Pierre, > > Isn't this URL rewriting? Shouldn't the tag be called rewriteURL instead of > encodeURL? > > Unless I'm mistaken, URL encoding is when you encode special characters in a > URL, like turning spaces into %20, etc., and URL rewriting is when you > modify the URL to embed the session ID. > > -- > Martin Cooper > Tumbleweed Communications > > - Original Message - > From: "Pierre Métras" <[EMAIL PROTECTED]> > To: <[EMAIL PROTECTED]> > Sent: Thursday, November 16, 2000 11:18 AM > Subject: encodeURL tag > > > > Hi all, > > > > Here is a very simple tag. It's role is to add session encoding to its > > parameter if the client browser doesn't support cookies. > > > > In the majority of cases, you don't need it because and > do > > it already. I had the need for it when my application opens a new window > > from JavaScript to present messages to the user: > > > > > > window.open('<s:encodeURL href="error.do?action=1243" />'); > > > > > > Add the following declaration to your struts.tld file: > > > > > > encodeURL > > org.apache.struts.taglib.EncodeURLTag > > EMPTY > > Encodes the URL given as parameter, adding session > information > > if necessary > > > > href > > true > > true > > > > > > > > Hope this helps. > > > > Pierre Métras > > > > > > > > >
Re: Using buttons for forwarding
Hi Nikolaus, If you want a graphical button, just do: Else create a small form that contains your button. If you're working for IE (doesn't work with NS), you can put your button without a form and redirect with a link as in the previous sample or with JavaScript code. Pierre Métras - Original Message - From: Nikolaus Rumm To: [EMAIL PROTECTED] Sent: Thursday, November 16, 2000 5:51 PM Subject: Using buttons for forwarding Hello, for design reasons I would like to use a button instead of a text-hyperlink to forward/redirect a request to another action/jsp-page. The struts:button tag is only valid inside a form and IMHO not intended for this use. Is there any workaround available ? Regards Nikolaus
encodeURL tag
Hi all, Here is a very simple tag. It's role is to add session encoding to its parameter if the client browser doesn't support cookies. In the majority of cases, you don't need it because and do it already. I had the need for it when my application opens a new window from JavaScript to present messages to the user: window.open('<s:encodeURL href="error.do?action=1243" />'); Add the following declaration to your struts.tld file: encodeURL org.apache.struts.taglib.EncodeURLTag EMPTY Encodes the URL given as parameter, adding session information if necessary href true true Hope this helps. Pierre Métras EncodeURLTag.zip
Re: Some thoughts on / problems with Struts (mostly tag related)
Hi I support most of the points raised by Matthias, as I encountered the same problems/interrogations. And everyone who have tried to extend Struts tags or implement forms created by designers have surely encountered them... > Automatic bean creation ! > Multiple select > form-tags and nested properties ! > name attribute in form tags !! If version 1.0 has to be incompatible with version 0.5, now is the time to take that sort of decision > Generating id= in the html output ! > form "method=get" will not work in every container > styleClass attribute ! > (defaults) values in form tags ! I don't apply totally for this one as I don't want to have localised values stored in forms, even initializations. > code bloat due to unneccessary extension of BodySupport !! > tags that work with collection of presentation things ! I would add that the tag can't be used due to bad design. Solutions have been suggested for the past months... > Standard HTML attributes !! > > Matthias > Pierre Métras
Re: Scripting variable from ?
Hi Vandana, For very simple cases where I need to reuse the string, mainly related with JavaScript event handling, I put it in a JavaScript variable and I am able to reuse it from a JavaScript event: var msg='<struts:message key="hello.world" />'; But that's not really clean. So I have developped an helper class to pick messages in the resource file, and I can use it everywhere JSP code is accepted: " /> I don't think you can rely on a custom tag as recursion into attributes is not permitted. Pierre Métras - Original Message - From: "Vandana Gupta/Raleigh/IBM" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Friday, November 10, 2000 4:08 PM Subject: Scripting variable from ? > Hi, > > Is it possible to get a String from ApplicationResources.properties using > struts:message and put it into a scripting variable to be used later in > the jsp?? > > I wished to do the following: > > > > where mytag is a custom tag. > This does not work for a custom tag though it works for a normal HTMl tag. > > I tried > =/> > > also. but that didn't work either. So I thought I would assign what is > returned by struts:message to a variable say "name" and substitute it using > jsp expression as : > > > > Now the problem is how do I get the value in a variable?? > Any help would be greatly appreciated. > Thanks, > Vandana > > >
Debug page
Hi, (sorry for those whose browser don't support HTML e-mail, but tables get scrambled...) In case others have a similar need to debug request and response properties and see HTTP headers, here is a simple test page (test.jsp) that shows major attributes. Either call it directly or have it defined in an action.xml. Better use is to have a conditional include of this code in your struts pages and have it activated by a request parameter (for instance, when you call http://myserver:8080/myapp/mypage.do?debug=true). No more need to telnet your server... Following is a sample of the result when called as http://pluton:8080/myapp/test.do?action=Init Pierre Métras Struts Test page Requestorg.apache.tomcat.facade.HttpServletRequestFacade@44cbbe Authentication type null Character Encoding null Content Length -1 Content Type null Context Path /myapp Locales [0]fr[1]fr_CA Method GET Path Info null Path Translated null Protocol HTTP/1.1 Query string action=Init Remote Addr 10.0.0.1 Remote Host 10.0.0.1 Remote User null Requested Session Id dtfc20pp61 Request URI /myapp/test.jsp Scheme http Server Name pluton Server Port 8080 Servlet Path /test.jsp Requested Session Id from cookie? true Requested Session Id from URL? false Requested Session Id valid? true Secure? false Parameters Parameter Values action [0]: Init Cookies Name Value Path Date userId 27 null -1 CookieTest testValueForCookie null -1 JSESSIONID dtfc20pp61 null -1 Headers Header Value Date User-Agent [0]: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0) --> Compilation error under Tomcat 3.2 B6 Cookie [0]: userId=27; CookieTest=testValueForCookie; JSESSIONID=dtfc20pp61 --> Compilation error under Tomcat 3.2 B6 Accept [0]: */* --> Compilation error under Tomcat 3.2 B6 Host [0]: pluton:8080 --> Compilation error under Tomcat 3.2 B6 Accept-Encoding [0]: gzip, deflate --> Compilation error under Tomcat 3.2 B6 Accept-Language [0]: fr,fr-ca;q=0.8,fr-be;q=0.7,fr-lu;q=0.5,fr-mc;q=0.3,fr-ch;q=0.2 --> Compilation error under Tomcat 3.2 B6 Connection [0]: Keep-Alive --> Compilation error under Tomcat 3.2 B6 Responseorg.apache.tomcat.facade.HttpServletResponseFacade@778255 Buffer Size 8192 Character Encoding 8859_1 Locale en test.zip
Re: Problem with cookie
Hi Craig, The problem was on my side. I wrote a debugging page to see the request headers and saw that the default MaxAge for a cookie is -1, that means non persistent. I forced the MaxAge to a positive value and now my cookie is stored. By the way, when writing the debugging page, I trapped an "IllegalArgumentException: can't find message associated to key: httpDate.pe" when I called request.getDateHeader(header). Pierre Métras - Original Message - From: "Craig R. McClanahan" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Wednesday, November 08, 2000 8:45 PM Subject: Re: Problem with cookie > Pierre Métras wrote: > > > Hi Craig, > > > > I'm running Tomcat 3.2 B6 on linux. > > > > I've seen your reference to the 3.1 bug in the Tomcat list, but I thought it > > concerned redirecting instead of forwarding. > > > > There was also a bug related to includes in 3.2 (not forwards) that I was > actually thinking of. > > I just ran some simple tests against the current Tomcat 3.2 code (lots of bug > fixes since beta 6), and the cookie is carried through the forward correctly. > I've got to go catch an airplane in a few minutes, but tomorrow I will try it > specifically with a Struts-based example to ensure that Tomcat is really fixed. > > Your test case is doing things correctly, and it is supposed to work. > > > > > Is there a tool that can be used to see the response headers? I've tried > > telneting on port 8080 and GETing the JSP file or the Struts action, but my > > Windows telnet client fails with a socket error. > > > > I use telnet for this. The only secret is you have to send a carriage return > (Ctrl+M) and newline (Ctrl+J) at the end of a line like: > > GET /myapp/testit.do HTTP/1.0 > > before the socket read times out. > > > > > Pierre Métras > > > > Craig > > > > > > - Original Message - > > From: "Craig R. McClanahan" <[EMAIL PROTECTED]> > > To: <[EMAIL PROTECTED]> > > Sent: Wednesday, November 08, 2000 7:24 PM > > Subject: Re: Problem with cookie > > > > > What servlet container are you running? There was a bug in Tomcat 3.1 > > that > > > caused cookies (and other headers) set before a > > RequestDispatcher.forward() to > > > get wiped out, but this was fixed in 3.2. You are doing things correctly. > > > > > > In general, action classes in Struts will never generate any output going > > to > > > the response, so they will not be causing the response to be committed > > (unless > > > you were to call response.flushBuffer(), which you should *not* do before > > a > > > forward). Therefore, it's entirely legal to set HTTP headers, as well as > > > cookies, in the action class ahead of the forward. > > > > > > Craig > > > > > > > > > Pierre Métras wrote: > > > > > > > Hi all, > > > > > > > > In the perform() function of my class, derived from ActionBase, I have > > the > > > > following code to set a cookie: > > > > > > > > public ActionForward perform(ActionServlet servlet, > > > > ActionMapping mapping, > > > > ActionForm form, > > > > HttpServletRequest request, > > > > HttpServletResponse response) > > > > throws IOException, ServletException > > > > { > > > > ... > > > > Cookie cookie = new Cookie("userId", > > > > String.valueOf(userContext.getId())); > > > > response.addCookie(cookie); > > > > session.removeAttribute(mapping.getFormAttribute()); > > > > return mapping.findForward("result"); > > > > } > > > > > > > > It seems the cooky is never set. > > > > > > > > What's cool with open project is that you can look at the sources. > > Poking > > > > into the code, I found that the mapping ends with something like: > > > > > > > > RequestDispatcher rd = > > > > getServletContext().getRequestDispatcher(path); > > > > rd.forward(request, response); > > > > > > > > But the javadoc for RequestDispatcher says "forward should be called > > before > > > > the response has been committed to the client (before response body > > output > > > > has been flushed). If the response already has been committed, this > > method > > > > throws an IllegalStateException. Uncommitted output in the response > > buffer > > > > is automatically cleared before the forward". > > > > > > > > So my question is: "how can I add a cookie to the response?". > > > > Either I add it and flush the response, then I should raise an > > > > IllegalStateException. Either I add it without commiting and then the > > > > response buffer (with all the headders?) is cleared before the forward. > > > > > > > > Pierre Métras > > > > > > > >
Re: Problem with cookie
Hi Craig, I'm running Tomcat 3.2 B6 on linux. I've seen your reference to the 3.1 bug in the Tomcat list, but I thought it concerned redirecting instead of forwarding. Is there a tool that can be used to see the response headers? I've tried telneting on port 8080 and GETing the JSP file or the Struts action, but my Windows telnet client fails with a socket error. Pierre Métras - Original Message - From: "Craig R. McClanahan" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Wednesday, November 08, 2000 7:24 PM Subject: Re: Problem with cookie > What servlet container are you running? There was a bug in Tomcat 3.1 that > caused cookies (and other headers) set before a RequestDispatcher.forward() to > get wiped out, but this was fixed in 3.2. You are doing things correctly. > > In general, action classes in Struts will never generate any output going to > the response, so they will not be causing the response to be committed (unless > you were to call response.flushBuffer(), which you should *not* do before a > forward). Therefore, it's entirely legal to set HTTP headers, as well as > cookies, in the action class ahead of the forward. > > Craig > > > Pierre Métras wrote: > > > Hi all, > > > > In the perform() function of my class, derived from ActionBase, I have the > > following code to set a cookie: > > > > public ActionForward perform(ActionServlet servlet, > > ActionMapping mapping, > > ActionForm form, > > HttpServletRequest request, > > HttpServletResponse response) > > throws IOException, ServletException > > { > > ... > > Cookie cookie = new Cookie("userId", > > String.valueOf(userContext.getId())); > > response.addCookie(cookie); > > session.removeAttribute(mapping.getFormAttribute()); > > return mapping.findForward("result"); > > } > > > > It seems the cooky is never set. > > > > What's cool with open project is that you can look at the sources. Poking > > into the code, I found that the mapping ends with something like: > > > > RequestDispatcher rd = > > getServletContext().getRequestDispatcher(path); > > rd.forward(request, response); > > > > But the javadoc for RequestDispatcher says "forward should be called before > > the response has been committed to the client (before response body output > > has been flushed). If the response already has been committed, this method > > throws an IllegalStateException. Uncommitted output in the response buffer > > is automatically cleared before the forward". > > > > So my question is: "how can I add a cookie to the response?". > > Either I add it and flush the response, then I should raise an > > IllegalStateException. Either I add it without commiting and then the > > response buffer (with all the headders?) is cleared before the forward. > > > > Pierre Métras > >
Problem with cookie
Hi all, In the perform() function of my class, derived from ActionBase, I have the following code to set a cookie: public ActionForward perform(ActionServlet servlet, ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { ... Cookie cookie = new Cookie("userId", String.valueOf(userContext.getId())); response.addCookie(cookie); session.removeAttribute(mapping.getFormAttribute()); return mapping.findForward("result"); } It seems the cooky is never set. What's cool with open project is that you can look at the sources. Poking into the code, I found that the mapping ends with something like: RequestDispatcher rd = getServletContext().getRequestDispatcher(path); rd.forward(request, response); But the javadoc for RequestDispatcher says "forward should be called before the response has been committed to the client (before response body output has been flushed). If the response already has been committed, this method throws an IllegalStateException. Uncommitted output in the response buffer is automatically cleared before the forward". So my question is: "how can I add a cookie to the response?". Either I add it and flush the response, then I should raise an IllegalStateException. Either I add it without commiting and then the response buffer (with all the headders?) is cleared before the forward. Pierre Métras
Re: The Struts question
Hi Struts uses a structure like: /yourapplication JSP pages... other directories /WEB-INF /classes /lib One of the reasons, if I understand correctly, is that the server will never answer to requests for files under the WEB-INF directory. For instance, if you put into the web.xml file, as initialization argument, the password used to connect to your database, nobody can try to obtain that file with a request like http://yourserver/yourapplication/WEB-INF/web.xml This architecture doesn't depend on the OS: WEB-INF is private to the application; files and directories upper are public. With your structure, you have to manage the permissions for the files and directories (OS specific), and someone can obtain your sources if he knows that they are stored in the /Src directory (and you forgot to apply correct permissions or your OS doesn't support it). But all this must be justified in the specifications for servlets containers... Pierre Métras - Original Message - From: <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Wednesday, November 08, 2000 3:15 PM Subject: The Struts question > Hi There: > I get a question regarding for the struts structure. > > We have existing web based software have our own structures. > > Root > >Bin > > Classes (Class files) > > Docs > > Src > > Web (JSP pages) > > Runtime > > Conf (Configuration files) > > Lib (Library) > > Logs > > But the struts will ask some structures like this. > > Root > > WEB-INF > > Classes > > Jsp > > Lib > > Session > > (JSP pages) > > META-INF > > The question comes down is, we want to use struts in our system, but we don' > t want to change our system structures. I recognize the struts pickup the > web.xml like default configuration files from WEB-INF directory, and > hardcode action.xml in action.java. If anybody has similar condition like > this, please help. > > I really looking forward to use this MVC structure in our software. > > Thanks > >
and usage
Hi, Can I use the tag, combined with or to generate a checkbox list or select options from 2 coupled arrays or collections (one for values, the other for display)? This question is cited in the Old TODO, but has someone a reasonable solution? For instance, can I remove the JSP code from the following extract and substitute an instead? <% String[] languageCodes = preferencesForm.getLanguageCodes(); String[] languageNames = preferencesForm.getLanguageNames(); for (int i = 0; i < languageCodes.length; i++) { %> <% out.print(languageNames[i]); } %> Then, is it possible to know where we are in the iteration to manage line breaks (in the checkbox sample) or row coloring (in a table)? Pierre Métras
Multibox
Hi, Has someone an example how to use the tag, and particularly how to define the getter method? Pierre Métras
Re: Can't obtain quote characters from struts message file
Hi Jean-Pierre, At least we are two on Earth with this behavior, so I can consider it normal. Neither the javadoc on Properties nor PropertyResourceBundle cite that you must double the quote character to have it retrieved from a file (ie displayed on the HTML). The PropertyResourceBundle even have an example where a quote appears: s4=Der disk '{1}' a {0} a {2}. and it's not doubled. And you can try as I did to store and load a Property file and see that in that case, single quotes work... Well, I have a solution. I can now focus on more important bugs. Pierre Métras - Original Message - From: "Jean-Pierre Schnyder" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Thursday, November 02, 2000 3:41 AM Subject: RE: Can't obtain quote characters from struts message file In all the .properties files I use for handling internationalization in Java with RessourceBundle's, like in file dispErrorMsg_fr_CH.properties for example, I always double the quote character, otherwise, the quote is not displayed to the user. Here's an example, if this is not clear: data0001 = Enregistrement pour l''ID {0} non trouvé dans la base de données ! The need to double the quote is not a bug I think and is not related in any manner to STRUTS. It's the way it works in the world of Java ! Jean-Pierre -Original Message- From: Pierre Métras [mailto:[EMAIL PROTECTED]] Sent: mercredi, 1. novembre 2000 22:54 To: [EMAIL PROTECTED] Subject: Can't obtain quote characters from struts message file Hi, I posted this problem one month ago but I've only found a strange solution. Are other having such a behavior? My tomcat+struts web application reads message tag strings from a property file. In the default message file, that contains French sentences for the moment, when the messages contains quotes ( ' ), these quotes disapear on the HTML page. I traced the problem to the function reading the messages from the property file. For instance, "l'émission" is read as "lémission". I have tried to escape the quote as in "l\'émission", according to the Properties class documentation. I even run native2ascii on the property file and all accentuated characters have been translated to Unicode escape, but the problem still persist. I created a test property file and stored it to disk, and the property are really stored as the would do: test=l'0u00E9mission without any escape for the quote. When I read the property file from the test program, I obtain the expected result. But that's not the behavior I have in the web application... As a last test, I tried to double the quote as in "l''émission" (that's two quotes, and not a double-quote). And then it worked! I have "l'émission" on the displayed HTML page. Can someone explain this? Pierre Métras
Can't obtain quote characters from struts message file
Hi, I posted this problem one month ago but I've only found a strange solution. Are other having such a behavior? My tomcat+struts web application reads message tag strings from a property file. In the default message file, that contains French sentences for the moment, when the messages contains quotes ( ' ), these quotes disapear on the HTML page. I traced the problem to the function reading the messages from the property file. For instance, "l'émission" is read as "lémission". I have tried to escape the quote as in "l\'émission", according to the Properties class documentation. I even run native2ascii on the property file and all accentuated characters have been translated to Unicode escape, but the problem still persist. I created a test property file and stored it to disk, and the property are really stored as the would do: test=l'0u00E9mission without any escape for the quote. When I read the property file from the test program, I obtain the expected result. But that's not the behavior I have in the web application... As a last test, I tried to double the quote as in "l''émission" (that's two quotes, and not a double-quote). And then it worked! I have "l'émission" on the displayed HTML page. Can someone explain this? Pierre Métras
Re: Found my problem. Was: JRun: Missing resources attribute org.apache.struts.action.MESSAGE
Look at the archive, particularly http://archive.covalent.net/jakarta/struts-user/2000/08/0139.xml Pierre Métras - Original Message - From: "Moore, Mark A" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Friday, October 27, 2000 1:16 PM Subject: Found my problem. Was: JRun: Missing resources attribute org.apache.struts.action.MESSAGE > The answer to my version of this problem is: struts.jar >MUST< be in your > webapp lib directory. Classpath searching does not work as expected if you > put the jar in, for example, in your jre lib/ext directory. Nothing was > being found in WEB-APPS/classes until I moved the jar. > > Also, struts apps, at least under JRun 3, >MUST< be initialized at startup > or the init method, and hence the initApplication method, will not be run. > > Are there logical explanations for this that are not apparent to the > uninitiated? > > Thanks > > Mark > * > The information in this email is confidential and may be legally privileged. > It is intended solely for the addressee. Access to this email by anyone else > is unauthorized. > > If you are not the intended recipient, any disclosure, copying, distribution > or any action taken or omitted to be taken in reliance on it, is prohibited > and may be unlawful. When addressed to our clients any opinions or advice > contained in this email are subject to the terms and conditions expressed in > the governing KPMG client engagement letter. > * >
Re: Exception in startup servlet?
As a reminder for future generations... I finally solved my startup malformed UTF-8 exception. The guilty character was a "é" forgotten in action.xml, and not in web.xml as I initially thought. Linux RH was configured to use a French Canadian keyword mapping, and the Debian has a US one. Morality of the story: ALWAYS use a header in ALL XML files! If some strange characters happens to get lost in the files, at least they will be digested by the parser... Pierre Métras - Original Message ----- From: "Pierre Métras" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Friday, October 27, 2000 12:16 AM Subject: Exception in startup servlet? > Hi all, > > I've move my application from the development PC to a test server. In the > move, I decided to do some little adjustments in software versions: > Struts 2000-08-08=> Struts 0.5 with my patches > Tomcat 3.1 => Tomcat 3.2 B6 > Linux RedHat 6.1 => Debian 2.2 with today updates > Xerces 1.1.3 => Xerces 1.2.1 > Sun Java JDK 1.3 beta=> JDK 1.3 final > > The whole setup was mainly OK. I can start tomcat and run the sample > applications. > The problem occurs when I put my struts application in the webapps directory > and start again tomcat. I get the following exception when I restart tomcat: > org.xml.sax.SAXParseException: Character conversion error: "Malformed > UTF-8 char -- is an XML encoding declaration missing?" (line number may be > too low). > > > Some strange things: > > - I have put xerces.jar both in myapp/WEB-INF/lib (for struts usage). > - There's no tomcat.log file generated! > - When transfered by FTP (either ascii or binary transfer) from RedHat to > Debian, my web.xml file caught ^M characters at the end of lines, that I > removed with vi. I processed it with native2ascii, in case... Other files > don't seem to have this strange disease. > > I checked many time all the xml files I could have used. I even added a > in web.xml. > It seems to relate to the startup process, and indeed I have a startup > servlet... Tomorow, I will type again web.xml if I can't find the reason for > that exception. > > Has someone encountered such a thing? How can I recognize a malformed UTF-8 > character? > > Pierre Métras > > > Full Exception > --- > admin@archibald:~$ /usr/local/tomcat/bin/startup.sh > Using classpath: > .:/usr/local/tomcat/lib/ant.jar:/usr/local/tomcat/lib/jasper.jar:/usr/local/ > tomcat/lib/jaxp.jar:/usr/local/tomcat/lib/parser.jar:/usr/local/tomcat/lib/s > ervlet.jar:/usr/local/tomcat/lib/test:/usr/local/tomcat/lib/webserver.jar:/u > sr/local/jdk1.3/lib/tools.jar > admin@archibald:~$ 2000-10-26 09:40:39 - ContextManager: Adding context > Ctx( /examples ) > 2000-10-26 09:40:39 - ContextManager: Adding context Ctx( /admin ) > Starting tomcat. Check logs/tomcat.log for error messages > 2000-10-26 09:40:39 - ContextManager: Adding context Ctx( ) > 2000-10-26 09:40:39 - ContextManager: Adding context Ctx( /test ) > 2000-10-26 09:40:39 - ContextManager: Adding context Ctx( /myapp ) > Parse Fatal Error at line 1 column -1: Character conversion error: > "Malformed UTF-8 char -- is an XML encoding declaration missing?" (line > number may be too low). > org.xml.sax.SAXParseException: Character conversion error: "Malformed UTF-8 > char -- is an XML encoding declaration missing?" (line number may be too > low). > at com.sun.xml.parser.InputEntity.fatal(InputEntity.java:976) > at com.sun.xml.parser.InputEntity.fillbuf(InputEntity.java:948) > at com.sun.xml.parser.InputEntity.peek(InputEntity.java:779) > at com.sun.xml.parser.Parser.peek(Parser.java:2710) > at com.sun.xml.parser.Parser.maybeXmlDecl(Parser.java:981) > at com.sun.xml.parser.Parser.parseInternal(Parser.java:478) > at com.sun.xml.parser.Parser.parse(Parser.java:284) > at javax.xml.parsers.SAXParser.parse(SAXParser.java:155) > at javax.xml.parsers.SAXParser.parse(SAXParser.java:77) > at org.apache.struts.digester.Digester.parse(Digester.java:748) > at > org.apache.struts.action.ActionServlet.initMapping(ActionServlet.java:619) > at > org.apache.struts.action.ActionServlet.init(ActionServlet.java:291) > at javax.servlet.GenericServlet.init(GenericServlet.java:258) > at > org.apache.tomcat.core.ServletWrapper.doInit(ServletWrapper.java:317) > at org.apache.tomcat.core.Handler.init(Handler.java:215) > at > org.apache.tomcat.core.ServletWrapper.init(ServletWrapper.java:296) > at > org.apache.
Exception in startup servlet?
Hi all, I've move my application from the development PC to a test server. In the move, I decided to do some little adjustments in software versions: Struts 2000-08-08=> Struts 0.5 with my patches Tomcat 3.1 => Tomcat 3.2 B6 Linux RedHat 6.1 => Debian 2.2 with today updates Xerces 1.1.3 => Xerces 1.2.1 Sun Java JDK 1.3 beta=> JDK 1.3 final The whole setup was mainly OK. I can start tomcat and run the sample applications. The problem occurs when I put my struts application in the webapps directory and start again tomcat. I get the following exception when I restart tomcat: org.xml.sax.SAXParseException: Character conversion error: "Malformed UTF-8 char -- is an XML encoding declaration missing?" (line number may be too low). Some strange things: - I have put xerces.jar both in myapp/WEB-INF/lib (for struts usage). - There's no tomcat.log file generated! - When transfered by FTP (either ascii or binary transfer) from RedHat to Debian, my web.xml file caught ^M characters at the end of lines, that I removed with vi. I processed it with native2ascii, in case... Other files don't seem to have this strange disease. I checked many time all the xml files I could have used. I even added a in web.xml. It seems to relate to the startup process, and indeed I have a startup servlet... Tomorow, I will type again web.xml if I can't find the reason for that exception. Has someone encountered such a thing? How can I recognize a malformed UTF-8 character? Pierre Métras Full Exception --- admin@archibald:~$ /usr/local/tomcat/bin/startup.sh Using classpath: .:/usr/local/tomcat/lib/ant.jar:/usr/local/tomcat/lib/jasper.jar:/usr/local/ tomcat/lib/jaxp.jar:/usr/local/tomcat/lib/parser.jar:/usr/local/tomcat/lib/s ervlet.jar:/usr/local/tomcat/lib/test:/usr/local/tomcat/lib/webserver.jar:/u sr/local/jdk1.3/lib/tools.jar admin@archibald:~$ 2000-10-26 09:40:39 - ContextManager: Adding context Ctx( /examples ) 2000-10-26 09:40:39 - ContextManager: Adding context Ctx( /admin ) Starting tomcat. Check logs/tomcat.log for error messages 2000-10-26 09:40:39 - ContextManager: Adding context Ctx( ) 2000-10-26 09:40:39 - ContextManager: Adding context Ctx( /test ) 2000-10-26 09:40:39 - ContextManager: Adding context Ctx( /myapp ) Parse Fatal Error at line 1 column -1: Character conversion error: "Malformed UTF-8 char -- is an XML encoding declaration missing?" (line number may be too low). org.xml.sax.SAXParseException: Character conversion error: "Malformed UTF-8 char -- is an XML encoding declaration missing?" (line number may be too low). at com.sun.xml.parser.InputEntity.fatal(InputEntity.java:976) at com.sun.xml.parser.InputEntity.fillbuf(InputEntity.java:948) at com.sun.xml.parser.InputEntity.peek(InputEntity.java:779) at com.sun.xml.parser.Parser.peek(Parser.java:2710) at com.sun.xml.parser.Parser.maybeXmlDecl(Parser.java:981) at com.sun.xml.parser.Parser.parseInternal(Parser.java:478) at com.sun.xml.parser.Parser.parse(Parser.java:284) at javax.xml.parsers.SAXParser.parse(SAXParser.java:155) at javax.xml.parsers.SAXParser.parse(SAXParser.java:77) at org.apache.struts.digester.Digester.parse(Digester.java:748) at org.apache.struts.action.ActionServlet.initMapping(ActionServlet.java:619) at org.apache.struts.action.ActionServlet.init(ActionServlet.java:291) at javax.servlet.GenericServlet.init(GenericServlet.java:258) at org.apache.tomcat.core.ServletWrapper.doInit(ServletWrapper.java:317) at org.apache.tomcat.core.Handler.init(Handler.java:215) at org.apache.tomcat.core.ServletWrapper.init(ServletWrapper.java:296) at org.apache.tomcat.context.LoadOnStartupInterceptor.contextInit(LoadOnStartup Interceptor.java:130) at org.apache.tomcat.core.ContextManager.initContext(ContextManager.java:480) at org.apache.tomcat.core.ContextManager.init(ContextManager.java:440) at org.apache.tomcat.startup.Tomcat.execute(Tomcat.java:197) at org.apache.tomcat.startup.Tomcat.main(Tomcat.java:237) 2000-10-26 09:40:45 - PoolTcpConnector: Starting HttpConnectionHandler on 8080 2000-10-26 09:40:45 - PoolTcpConnector: Starting Ajp12ConnectionHandler on 8007
Re: Problem with optional form fields
Craig McClanahan wrote: > It might make sense to skip calling the setIntProperty() field at all if the > input is a zero-length string. JSP follows this rule when you specify > something like , so this > would be more consistent with JSP as well. > > What do you think? It might create side effects, like with checkboxes where a non checked button is not sent to the server. Imagine that the user has entered a value in a field, but that field must be empty for the form to be validated. When struts redisplays the form with the errors, the user empties the field. With your proposal, struts will never transmit the empty field to the bean and the validation will always fail... In that particular case, the "" <==> 0 translation creates the whole problem. The ActionForm bean should really use String in order to distinguish between empty and 0 value. Then, after validation (the validation could have to convert the field value in order to check its content), the conversion should occur when the definitive values are transfered to the business object. Pierre Métras
Re: Support for ComboBox
Hi Gigen > Is there an archive available for this list that can be searched ? > http://archive.covalent.net > I have a requirement wherein I need to populate a ComboBox from a > Database.Wanted to know if struts has any kind of support available in > order to achieve the same. Right from the box, no. You'll have to write a bean that reads your data from the database and put it in two arrays (one for values, other for labels) or collections. Then, you can use the and tags to create the combobox and populate the option from the arrays. The main idea of struts is to separate presentation (your combobox) from the data, so the need for an intermediate bean (the controller) to manage them. Pierre Métras
Re: Dynamic form and checkboxes
Thanks. I drop a look at the source of MultiboxTag but I can't understand how to use it (must I include it in an tag?), and it seems it has never been used in struts example or test suite. Has someone already used it? Pierre - Original Message - From: "Aur Gal" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Thursday, October 19, 2000 1:28 PM Subject: RE: Dynamic form and checkboxes > I'm not sure but I think in this case you would use the struts:multibox. > > -Original Message- > From: Pierre [mailto:[EMAIL PROTECTED]] > Sent: Thursday, October 19, 2000 12:15 PM > To: [EMAIL PROTECTED] > Subject: Dynamic form and checkboxes > > > Subject: Dynamic form and checkboxes > > Hi, > > I forgot to follow the 'dynamic form' thread when the subject was hot, and > now I can't retrieve the posts to pick some ideas... > > Here is my 'dynamic form' problem. I must create a form with a collection of > checkboxes to allow the user to choose various options. The checkboxes will > be generated by an application tag, the number and types depending on the > user > profile. > > How can I have a dynamical ActionForm class to manage all these checkboxes? > Should I create a *big* class with all setOptionNNN/getOptionNNN functions, > in > order to support all checkboxes combination or can I write generic get/set > functions using indexed properties? Or is there a better alternative... > > Thanks for any hint. > Pierre Metras >