Using anchor tags in struts

Discussion in 'Java' started by krasicki, Dec 29, 2004.

  1. krasicki

    krasicki Guest

    I'm looking for the recipe to do the following:

    I have created a jsp struts page that contains a form. The page is
    called logon.jsp and it has a corresponding jsp page called done.jsp.

    If the button on the form is a success, I redirect to done.jsp. So far
    so good.

    If the button on the form encounters errors I return the appropriate
    error messages to logon.jsp and they display exactly to <html:errors/>.

    However, the next level of refinement has me puzzled.

    Within logon.html, I have created an errors section at the bottom of
    the page and I use an anchor tag, <a NAME="errors">, to identify its

    I have tried to map my 'failure' condition to logon.jsp#errors with no
    luck. The page is mapped to <whatever> no matter what
    combinatorials I've tried. And just to be clear, my jsp layout is
    designed so that the errors section is intentionally unobtrusive to the
    logon part of the page. IOW, I know that I can just display the errors
    higher on the page and so on. The point is that I want a space for
    verbose explanations that aren't disorientating to the user's

    Is this exercise possible in Struts?
    krasicki, Dec 29, 2004
    1. Advertisements

  2. krasicki

    Ryan Stewart Guest

    Not exactly sure what you're saying/asking. Do you mean you have an action
    mapping like:
    <action path="/logon" name="..." ...>
    <forward name="failure" path="index.jsp#errors"/>
    <forward name="success" path="done.jsp"/>

    ?? If so, that's fine. If you also, in your action, have a line like:
    return mapping.findForward("failure");

    in the case of a logon failure, then that's right too, and it's doing what
    you want. Ignore the fact that it shows "" in the address bar of
    your browser if that's what is bothering you. Have you tried manually
    navigating to "logon.jsp#errors"? Does it work as expected? This is all I
    can say right now. If you want a more specific answer, ask a more specific
    Ryan Stewart, Dec 29, 2004
    1. Advertisements

  3. krasicki

    krasicki Guest

    As I said the mappings work fine until I attempt to use an anchor.
    For example:
    <!-- Action Mappings --><br>
    <action name="loginFormBean" path="/login" <br>scope="request"
    <forward name="success" path="/Goodbye.jsp" redirect="true"><br>
    <forward name="failure" path="/Login.jsp" redirect="false"
    This works fine.<p>But once I change 'Login.jsp' to 'Login.jsp#errors',
    the anchor tag is ignored.
    krasicki, Dec 29, 2004
  4. krasicki

    Ryan Stewart Guest

    1) What's with all the markup in your action mapping?
    2) What causes you to believe the anchor tag is ignored?
    Ryan Stewart, Dec 29, 2004
  5. krasicki

    krasicki Guest


    1.) Ignore the markup, it's my bad - me, thinking that I needed it in
    google - this new format threw me a bit.

    2.) The anchor is ignored because the test I run expects the Logon jsp
    page to be rendered from where the anchor tag is located on that page.

    As I research this a bit more. It appears that there is no way of
    doing this - the anchor is stripped away and ignored - the browser's
    only interest is in rendering the page.

    Rather than slog through Struts source can anyone identify a method
    that can override Struts to acheive this effect?
    krasicki, Dec 29, 2004
  6. krasicki

    Ryan Stewart Guest

    Ah, right. I forgot about this. Supposedly it will work in some
    configurations if you set redirect="true" on the forward, but that loses the
    original request. The one thing I could think of would be to put the anchor
    name in your form action:
    <html:form action="">

    It's not a perfect fix, but it's not a perfect world.
    Ryan Stewart, Dec 29, 2004
  7. krasicki

    Sudsy Guest

    Half right. See below.
    You have to recognize that it's the browser which is scrolling to
    a named anchor. Unless you perform a redirect (in which case the
    browser will /know/ what target it's looking for) then you're SOL.
    Of course if you redirect then you lose everything in page and
    request scopes...
    Sudsy, Dec 29, 2004
  8. krasicki

    Wendy S Guest

    Are you opposed to a bit of JavaScript? I have a very long page in which I
    allow people to hide and show sections. Hiding or showing causes a round
    trip to the server, and I need to return them to the same section they were
    looking at. In the Action, I set:
    request.setAttribute( "anchor", "nameOfAnchor");

    Then at the bottom of the JSP (so it won't execute until the page has
    finished loading) I have:
    <c:if test="${anchor ne null}">
    document.location = "#<c:eek:ut value="${anchor}"/>";

    Since you want to do this only if there are errors, you could skip setting a
    request attribute, and instead test for the presence of errors and only
    write out the script if there are errors to display.

    Wendy S
    Wendy S, Dec 30, 2004
  9. krasicki

    krasicki Guest

    Ah, Wendy - a breath of fresh air. I had thought about a similar
    solution yesterday that I will try today.

    I think you have the right idea though and it deserves a wider
    audience. In investigating this phenomenon on Sun's site and
    elsewhere, it remains unresolved even though what you are presenting is
    precisely what the doctor ordered.

    Thanks - excellent thinking.
    krasicki, Dec 30, 2004
  10. krasicki

    Sudsy Guest

    Wendy S wrote:

    I've got to hand it to you, Wendy: that's a slick solution! It won't
    work if JavaScript is disabled/unavailable but it should certainly
    work in the majority of cases. Nice job of "thinking outside the box".
    Sudsy, Dec 30, 2004
  11. krasicki

    Wendy S Guest

    Well, feel free to re-post it wherever you think it will help!

    Thanks to you and Sudsy for the compliments. :)
    Wendy S, Dec 30, 2004
  12. krasicki

    krasicki Guest

    Fellow investigators - here's a variation on Wendy's theme that suits
    my purposes slightly better.
    I'll share it in the event that it's of interest to others.

    What I did is the following:

    In my loginFormBean, I have the following methods;

    public ActionErrors validate(
    ActionMapping mapping,
    HttpServletRequest request) {

    ActionErrors errors = new ActionErrors();
    // Validate the fields in your form, adding
    // adding each error to this.errors as found, e.g.

    checkEmpty(getDestination(), errors, "destination_missing");
    checkEmpty(getTrustedUsername(), errors, "username_missing");
    checkEmpty(getTrustedPassword(), errors, "password_missing");

    // This next error is where I test the javascript
    // After all, we only want to go to this anchor when I have an error
    or information
    // to give the user

    checkEmpty("",errors, "test");
    // if ((field == null) || (field.length() == 0)) {
    // errors.add("field", new
    // }
    return errors;


    private void checkEmpty(String param, ActionErrors errs, String msg) {
    if (param == null || param.trim().length() == 0) {
    errs.add(msg, new org.apache.struts.action.ActionError(msg));

    Then in my properties file I added;

    # Optional header and footer for <errors/> tag.
    destination_missing=<li>You forgot to mention which platform this
    login applies to.
    username_missing=<li>What is your username?
    password_missing=<li>Your password is?
    test=<script>document.location = "#aaa";</script>

    Notice my message is javascript that executes on demand.

    My jsp page looks something like:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
    <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
    <%@ page
    contentType="text/html; charset=ISO-8859-1"
    <META http-equiv="Content-Type" content="text/html;
    <META name="GENERATOR" content="IBM WebSphere Studio">
    <META http-equiv="Content-Style-Type" content="text/css">
    <meta http-equiv="Pragma" content="no-cache">
    <LINK href="theme/Master.css"
    rel="stylesheet" type="text/css">
    <BODY >
    // snip

    <p><html:form action="/"><b>
    <font face="Verdana">UserName:&nbsp;</font></b>
    <input type="TrustedUsername" name="trustedUsername"/>
    <br><b><font face="Verdana">Password:&nbsp;</font></b>
    <input type="TrustedPassword" name="trustedPassword" />



    // snip

    <a NAME="aaa"> </a>
    <%@ include file="InfoAndErrors.jspf"%>

    Then InfoAndErrors looks like:

    <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
    <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
    <br><b><font color="#CCCCCC">Information, errors, and
    further instructions:</font></b><html:errors/>

    Now, what I like about this is that the anchor is executed only when
    the code
    is instrumented to do so. This means I can use the Struts error
    facility for realtime
    debugging purposes by further tweaking the code a bit and employing the
    Struts <html:errors> facility to kick out debugging messages as

    I'm using WSAD 5.1.x and this seems to work fine in preliminary tests
    I'm doing.
    Your mileage may vary.
    krasicki, Dec 30, 2004
  13. krasicki

    krasicki Guest

    Oh, one last technical note. In my example I was just playing around
    with multiple error messages. On a true login screen a better practice
    is not to tell the person attempting a login exactly which input is

    Finally, thanks to everyone who responded - I think this is one of
    those tricky asides in Struts that needed clarification - our good deed
    for the day.
    krasicki, Dec 30, 2004
  14. krasicki

    cstockton Guest

    I use a non-struts solution. If I need to forward to an anchor, I set
    a request attribute in the Action

    request.setAttribute("anchor", anchor);

    then in the jsp, I check if an anchor is present and send a redirect:

    <logic:present name="anchor" scope="request">
    String anchor = (String)request.getAttribute("anchor");
    response.sendRedirect("mypage.jsp#" + anchor);

    This works, but exposes your jsp.

    cstockton, Jan 10, 2005
  15. krasicki

    javaguy Guest

    I've used this on my project, but have noticed interesting side

    Sometimes my pages have an additional section:


    <c:if test="${not empty myForm.pdf}">"myurl/somepath/<c:eek:ut value='${myform.pdf}'/>", "params");



    <c:if test="${not empty myForm.jumpto}">
    document.location="#<c:eek:ut value='${myForm.jumpto}'/>"

    If a PDF parameter is included, then when this form is rendered it pops
    up a new window with that PDF.

    Suppose I also include a "base" tag: <h:base/>. When the
    document.location is executed the PDF is displayed twice. You can
    juuusssttt quite see it reusing the window when using Windows Adobe
    Reader, but when on Linux (Firefox) you only have the ggv viewer then
    you get two separate popups. But without the "base" tag, only once.

    Patient: "Doctor, it hurts when I do this."
    Doctor: "Then don't to that!"

    I will not use the "base" tag for the time being, but I'm still looking
    for a more general solution.

    Thanks for your ideas
    javaguy, Mar 10, 2005
  16. krasicki


    Apr 17, 2013
    Likes Received:
    Wendy, thanks for your solution.....
    hharda9791, Apr 17, 2013
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.