1

Let me ask a question, maybe simple, but I am a newbie in Struts2.

I have this action method in ProfileAction action:

@Override
public String execute() throws Exception {
    HttpServletRequest request = ServletActionContext.getRequest();
    HttpSession session = request.getSession();
    String id = (String) session.getAttribute("id");
    if (id != null && !id.equals("") && !id.equals("0")) {
        return SUCCESS;
    }

    return "noSession";
}

And this in the XML:

    <action name="perfil" class="agenda.ProfileAction">
        <result name="success" type="tiles">/profile.tiles</result>
        <result name="noSession" type="tiles">/login.tiles</result>
    </action>        

    <action name="conexion" class="agenda.ProfileAction" method="login">
        <interceptor-ref name="jsonValidationWorkflowStack">
            <param name="validation.excludeMethods">init,input</param>
        </interceptor-ref>
        <result name="loginSuccess" type="tiles">/login/success.tiles</result>
        <result name="loginError" type="tiles">/login/error.tiles</result>
    </action>                

As you see, I have "noSession" result in default method, but when I run the page, it throws an exception because "input" result is required. When I replace "noSession" in the XML by "input", it works, but the side effect is that JSON validation does not work.

It seems that execute method is not being called. I have even place a throw exception and in fact, it is not called.

I am traying to call the action this way:

http://www.domain.com:8080/AgendaPlus/perfil

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
jstuardo
  • 3,901
  • 14
  • 61
  • 136

1 Answers1

2

You're almost certainly getting a validation or type conversion error.

When this happens, S2 will attempt to route you to the "input" result to re-fill the form.

Unrelated, but getting values out of the request like this completely negates a lot of the power of S2. Consider working through some tutorials/etc. and use the built-in conveniences.


One easy, human-readable way to look at the interceptor stack is to use the profiling interceptor. This can be configured to be the default, or set up on a per-action basis:

<action name="themes" class="test.ThemesAction">
  <interceptor-ref name="profiling">
    <param name="profilingKey">profilingKey</param>
  </interceptor-ref>
  <interceptor-ref name="defaultStack"/>
  <result>/WEB-INF/jsps/themes.jsp</result>
</action>

Make the request including a "profilingKey" parameter set to "true" and your logs will show:

2013-04-09 21:22:25,813 INFO  : [1959ms] - invoke: 
  [1959ms] - interceptor: exception
    [1959ms] - invoke: 
      [1959ms] - interceptor: alias
        [1959ms] - invoke: 
          [1959ms] - interceptor: servletConfig
            [1957ms] - invoke: 
              [1957ms] - interceptor: i18n
                [1957ms] - invoke: 
                  [1957ms] - interceptor: prepare
                    [1956ms] - invoke: 
                      [1956ms] - interceptor: chain
                        [1956ms] - invoke: 
                          [1956ms] - interceptor: debugging
                            [1956ms] - invoke: 
                              [1956ms] - interceptor: scopedModelDriven
                                [1956ms] - invoke: 
                                  [1956ms] - interceptor: modelDriven
                                    [1956ms] - invoke: 
                                      [1956ms] - interceptor: fileUpload
                                        [1956ms] - invoke: 
                                          [1956ms] - interceptor: checkbox
                                            [1956ms] - invoke: 
                                              [1956ms] - interceptor: multiselect
                                                [1956ms] - invoke: 
                                                  [1956ms] - interceptor: staticParams
                                                    [1955ms] - invoke: 
                                                      [1955ms] - interceptor: actionMappingParams
                                                        [1955ms] - invoke: 
                                                          [1955ms] - interceptor: params
                                                            [1954ms] - invoke: 
                                                              [1954ms] - interceptor: conversionError
                                                                [1954ms] - invoke: 
                                                                  [1954ms] - interceptor: validation
                                                                    [1897ms] - invoke: 
                                                                      [1897ms] - interceptor: workflow
                                                                        [1897ms] - invoke: 
                                                                          [7ms] - invokeAction: themes
                                                                          [1889ms] - executeResult: success
Dave Newton
  • 158,873
  • 26
  • 254
  • 302
  • I found that in a tutorial... I don't know what you mean, because I am not refilling anything... I am following tutorials step by step, and I am in the step that only shows a page, before actually submitting the form. – jstuardo Apr 09 '13 at 02:16
  • by the way... this problems occurs when I added Json Validation. Before validation, all worked as expected. – jstuardo Apr 09 '13 at 02:17
  • @jstuardo Nonetheless, it looks like validation or type conversion is running. – Dave Newton Apr 09 '13 at 03:16
  • The question will probably become "How do I return a sensible JSON string from the action when validation fails?" if so this should be useful: http://stackoverflow.com/questions/5427497/struts2-json-plugin-adding-actionmessages-actionerrors-and-fielderrors-to-res – Quaternion Apr 09 '13 at 03:28
  • I don't think so, because at first page load, JSON is not invoked at all. It should be act only at form submit, but of course I can be wrong. – jstuardo Apr 09 '13 at 15:17
  • Other fact I mentioned in my question. My execute method is not actually called, so the problem is reduced to why action is not ran. – jstuardo Apr 09 '13 at 15:23
  • ... @jstuardo Because validation or type conversion is failing. What makes you think when you execute an action that it will magically skip validation? – Dave Newton Apr 09 '13 at 15:53
  • because I have experience in either .NET framework or PHP frameworks like Symfony. When I first load the applicatio, validation should not be executed. What type conversion are you meaning? One fact I have seen at first is that programming with Struts is like working blind. I have not found any debugging tools that make me trace the program execution such as .NET or symfony do. – jstuardo Apr 09 '13 at 16:15
  • I have put a throw new Exception("pasoooo"); in execute method and logically I will expect the page to show an exception, but it does not. By launching configuration browser, I can see the action definition correctly, but it does npt allow me to trace the execution. – jstuardo Apr 09 '13 at 16:18
  • @jstuardo IF VALIDATION/TYPE CONVERSION FAILS THE ACTION WON'T RUN BECAUSE VALIDATION AND TYPE CONVERSION HAPPEN BEFORE THE ACTION RUNS. You can expect all you want, but in frameworks like S2 and Spring MVC type conversion and subsequent validation happen *before* your code, because the code depends on having valid data. You're using the same action for two URLs, but your validation is at the action level, so that's what will happen. – Dave Newton Apr 09 '13 at 16:19
  • I understand what you write, but it says nothing but a possible cause. You are assuming validationtype conversion fails, but how can I be sure it is as you say? I don't receive error message, exception, nothing telling in what part of the code is the problem. maybe the struts.xml, maybe web.xml, maybe the .java, or whatever. Please don't be ironic... maybe this is so obvious for you since you have experience, but in my case, this is the first Struts2 program. – jstuardo Apr 09 '13 at 17:56
  • @jstuardo Because I helped write and document the framework? There's no other reason for it to skip to the "input" result. Turn on `devMode`, turn up logging to DEBUG level, examine your assumptions, etc. Put a project on github and maybe someone will look at it, but you're getting a type conversion or validation error. – Dave Newton Apr 09 '13 at 18:02
  • Never mind.... I have solved the problem. I was implementing the logic of user validation. If user goes to profile page and he is not logged in, login page must load, otherwise, profile information should be shown. I followed the tutorial in http://www.javatpoint.com/struts-2-login-and-logout-example but I have only used one class for user validation and for getting the session. I separated the logic and it works, but.... validation does not work now.... how can i know if interceptor is being executed? – jstuardo Apr 09 '13 at 20:11
  • @jstuardo Logging and devmode? Knowing the interceptors that should be running and the circumstances under which they *wouldn't* run? – Dave Newton Apr 09 '13 at 20:15
  • I have devmode =true and logging enabled... but when log record should contain this trace? – jstuardo Apr 10 '13 at 00:51
  • @jstuardo The easiest/most-helpful way might be to use the "profiling" interceptor; moved rest of comment to answer for formatting. Note that since "workflow" is last, it'll still run through all your interceptors and only bomb out there. – Dave Newton Apr 10 '13 at 01:20
  • Where can I see that log? I am seeing Apache Tomcat log but nothing similar is shown. – jstuardo Apr 10 '13 at 13:02
  • @jstuardo Wherever you have your logging configured to log to. – Dave Newton Apr 10 '13 at 14:31
  • Thanks... that way I realized that interceptor get actually called and input result is invoked, but no error is shown and the form is submitted anyway. When I replaced json validation by normal client validation, it works. By logging you taught me, I saw that jsonValidation interceptor invokes workflow interceptor, and it invokes executeResult input, what is correct, So I am wondering why form is submitted and no error is shown. – jstuardo Apr 10 '13 at 19:23