On 7/7/05, Rick Reumann <[EMAIL PROTECTED]> wrote: > Michael Jouravlev wrote the following on 7/7/2005 5:13 PM: > > > So, tokens better than nothing, like Yugo comparing to bike. But it is > > still a Yugo. (I am not selling Lexus here, merely a Corolla). > > Yes, it does sound like your approach to the whole 'back' issue problem > handles things in a much nicer fashion. I'll definitely have to look at > least how you handle it. (I might not buy the whole Corolla but would > like those fancy rims:)
Rick, first of all, I am grateful for warm reply. I highly value opinion of veteran users like you. But now, when I got your attention, I started to think "what if what I have is really not that good"? I wanted others to "get" and to appreciate my ideas (actually, most of these ideas are flying around and are used in other projects, but whatever). Now I feel like having a test in a college. ;) I want to try explain my approach to Back button here, before you start looking at the code. Quite a few people told me, that my approach is not using technology, it is bending technology and working against it, that it is not how people got used to do stuff. This is discouraging, but seems to be true. For example, in my Windows programming days I always payed attention to proper keyboard support, that all operations were available from keyboard, that all tabstops were correct, etc. But very fiew people use keyboard, when they learn how to move mouse around. They could care less how good keyboard support was. Same with web apps. Many (most?) developers and users do not care about Back button or Refresh, because they do not use them. They see the message "Do not click back button after check out" or "Do not click submit button again" and they do not do it. They do not realise that applicaiton they are using is not perfect, because they are not QA engineers, they do not click all buttons here and there, they just follow the path. So, some of my reasonings can seem irrelevant to many. I have an opinion on web apps. Let's put Ajax and Flash aside, and talk about "normal" web app. I see two different modes. First, is traditional "hyperdocument" mode, when you have pages, links, you follow link, get to another page; then you can go back to the previous page if needed. This mode works well for static or quasi-static pages, documents, online magazines, different hierarchical things like list of the goods in online store. This mode is usually stateful, at least in regards to what you see on your way there and back. Another mode is tied to application state. If you added goods to the cart in online store, then whenever you navigate to the cart, you should see its current content. Even if you use Back button, this is my opinion. Same, checkout process: when it finished, server changed its status, your cart is disposed, so if you go back, you should not see the cart and, what even worse, to have chance to submit it again. No, when you go back, you should see message that cart was disposed. So, this mode is usually stateful, and it keeps browser pages (view) synchronized with server (model). This is where I get strange looks. >From here I went a little further and thought, that there are objects/entities in an application, which are stateful, and can be rendered differently according to their current state. So, why would one want to be able to navigate to different pages of this object? It is more logical to navigate to the *object* itself, which renders itself differently depending on state. On the one hand, this approach still allows to bookmark an object, though not a particular page belonging to that object. On the other hand, you do not need to click Back several times to return from this object. Because if all pages are loaded from the same location (location == URL + parameters), then browser would consider these pages as one resource, and would put only one entry in the page history. This is like "single-page application". But this term is already used by Flash and Ajax apps, which do not reload page and load data in background. So I decided to call these objects "web islands". They are not so slick as Ajax because they are reloaded after each data submit. On the other hand, they are reloaded from the same location, thus logically correspond to one resource. I think this is kinda cool. But also this allows to protect users from double submit. For example, the wizard which you can see here: http://www.superinterface.com/strutsdialog/wizardaction.do is served from one location. So unless you use Opera, you will notice, that your Back button is not enabled while you use this wizard. And you cannot go back to previous wizard page using browser button. This wizard is a "web island". My email is getting too long, and have not had a beer yet... > > *AND* it allows to build almost fool-proof UI with better user experience. > > This part does interest me a lot. I hope you will not get too excited, I don't want to promise too much. The idea of two-phase processing (I like this new term, the old one is Redirect-after-Post) is to give a user more freedom in clicking buttons that he can reach to, at the same time trying to limit access to these buttons when possible ;) Say, you use Opera, which is the worst case for my stuff. Still, you get benefits because if you deliberately or by chance click Refresh button, nothing will happen, the result page will be simply reloaded. A user will not see nagging POSTDATA message (I HATE THEM, can i get the larger letters?), and application will not have to fight with resubmitted data. Going Back on Opera is kinda sucky, because even if you mark page with "no-cache, no-store", Opera does not reload a page. *And* it stores all pages in the history, even if they are loaded from the same location. Bummer. So, the only positive result with Opera is safe Refresh. Not much. So you still need to use tokens. Tokens is the whole other story, I prefer to use model state or timestamp for that. I think that model knows better is it possible to resubmit data or not. But this is not relevant here. For other browsers like MSIE or Firefox, things look much sleeker. They reload non-cached page if you go back, *and* they keep only one entry for each resource even if this resource responds with different content. In this case web islands work like a charm. Here is what you get: * If you respond with differnt content from the same location, then while you are at this location, you cannot go back to previous page from this location. This protects you from resubmitting the form from previous page. * You can freely refresh a page too. * You can go to another site, then navigate to web island *using address bar* and you will get your object in the same state in which it was left. This is not a particular win of redirect stuff, this is just because I store state on the server and I do not pass any state variables (freaking _viewstate) in the request/response. But with my pattern which includes redirect I just have to use server state. So, if you not like to store state in session, then my stuff is not for you... * If you click Back button, you return from web island as a whole. So, if you tried five times to log in, then you need only one click to go back, because there is only one entry in the page history (see above). > I'd love to be able to pull > your CRUDform out and use in a Swing app if I needed (possibly it can, I > don't have the code here at home right now). Um, don't think it would work. There is not much in that form... > > On the other hand I already have CRUDComboAction (not in current > > download), which combines both. I guess I need to replace former with > > latter ;-) > > Actually I think that would be a good idea. It definitely will make the > framework no chance of an 'addition' any more but I think that's a more > consistent approach to take. (I believe this is what WebWorks does and > is a similar approach to the backing bean concept in JSF?). Plus the > ActionForm is just sort of goofy anyway:) I just assume stick my single > VO in there anyway vs creating all those duplicate properties. Oh, I am sorry, you misunderstood me. I did not make a great thing combing action and action form. Er, no. What I did, is combined ItemListAction with CRUDAction, so I show list from the same location. It gives the usual benefits of web island. Basically, the whole thing, list and edit and view forms, and all operations, and everyting take one slot in page history. So, no going Back ever. You see the list - you cannot go back to the item you just edited. You see an item, you cannot go back to the list (only through buttons on the form). I will try to deploy it today or tomorrow. But I still have the idea of generic Action + Form combo, so I hope I will implement it too ;) > however I have this feeling (probably unfounded) that > companies are going to feel overwhelmed with the choices out there and > simply say "Screw it, I'll just go with an MS solution." The good thing that company I currently work at is about to have another web project and hopefully I will be able to use my own stuff. On the other hand, I am not sure how I can use it at work, and still keep it for myself and as opensource. I hope that putting it out to the sourceforge should help a bit. Thanks for warm reply, it is really encouraging ;) Michael. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]