Yet another reason frames are evil. The “normal” pattern for a Struts/Tiles app is that your application contains links that point to Struts actions. The action executes, and maps the result to an ActionForward that points to a Tiles template. The Tiles template then pulls in the pieces of the view (header, menu, content, etc) and sends the result to the user.
Now imagine the same thing with a frames application. In frames, the browser first pulls down the frameset in an HTML document, then reads from the HTML document where to retrieve the contents of the individual frames, in separate requests, from different URLs. So if you call the Struts action and then forward to the Tiles template, whatever data you may have stored in the request is completely useless – the request the data was placed in was used to grab the frame layout, and this new request to load your content doesn’t contain the information you wanted. (This does assume that you reload all frames with each request.)
So what are your options? Well, you could base your whole application on the premise that users will ALWAYS come in through the front page, that you will always change only one pane at a time. If you do this, your links can now point to a Struts action with a target of the frame the content will go in. Unfortunately, this means 1) No bookmarking, 2) you can’t switch to a non-frames layout without substantial redevelopment, and 3) if you want to change the content and menu with the same link, you have to resort to some wonky Javascript workaround.
The other option is similarly lame, more complex, and also not functional. You essentially have to split your application logic into 2 categories, data you want to read, and data you want to submit. On a submit, you still submit directly to a working struts action. If you want to populate data into the view, however, your initial Struts action has to be a forward to a Tiles definition, and you have to make the tile region point to the Struts action that fetches the data, then have that forward point to the actual JSP to be loaded. In this case, if you want to have an interaction that submits data and then includes information from that interaction on the response screen, you have to find a way to pass that data around rather than putting it in a request.
Frames were broken the day they arrived. The way they completely hose dynamic web pages is a further indictment of their uselessness.
… or you can use another framework (like RIFE) that allows you to automatically decorate pages with frames with the content frame in the frameset still receiving the original request data. The fact that the frames are added behind the scenes makes frames bookmarkable again.
Frames have their uses. They were designed long before Struts came around and, thus, not with frameworks like Struts in mind. I tend to think of frames as more of a deprecated type of technology rather than an ‘evil’ one. On the other hand, I do use frames in my work. Not for visual formatting, but for persisting client-side objects between page refreshes (such as a non-visual applet in a hidden frame). Of course, I typically do these types of things in a controlled environment also (such as internal corporate applications) where I don’t have to program to the LCD and can control things like removing the address bar and whatnot. For the outside world, I’d probably agree that frames aren’t the way to go.
I am currently working on this problem as well. What I’ve come up with is when the initial frame layout is set up, all of those framed URLs have the token in the URL they’re requesting. Once they have that token, that the key to the session data even though it’s all sessionless. I have this working, but I haven’t built the real app with it yet. I don’t think that this is a bad solution, nor do I think it’s a great one.