Uploaded image for project: 'Struts 2'
  1. Struts 2
  2. WW-4750

Why JSONValidationInterceptor return Status Code 400 BAD_REQUEST instead of 200 SUCCESS

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Minor
    • Resolution: Not A Problem
    • Affects Version/s: 2.5.10
    • Fix Version/s: 2.5.12
    • Component/s: Plugin - JSON
    • Environment:

      Jdk 1.7, Windows 10, jQuery 1.7.2

    • Flags:
      Important

      Description

      Since I have made the upgrade of my Struts 2.5.8 to 2.5.10, all my POST Ajax call via jQuery with the parameter "struts.enableJSONValidation=true" return status code 400 Bad Request when my validation on server side is wrong.

      And I have an issue in the caller jQuery.

      Failed to load resource: the server responded with a status of 400 (Bad Request)

      Before in 2.5.8 and all previous versions the status code was 200.

      What is the reason of this changes because jQuery doesn't understand this and it's problematic. I see this WW-4728 but in this bug it was not mention that the status code has to be changed.

      Please provide example in the documentation if the reason of the change is a specific reason

      Thank you in advance for your help.

      Best regards,

        Activity

        Show
        cn42 Christoph Nenning added a comment - Note that this affects showcase app: https://github.com/apache/struts/blob/master/apps/showcase/src/main/webapp/WEB-INF/validation/ajaxFormSubmit.jsp And wiki: https://cwiki.apache.org/confluence/display/WW/AJAX+Validation
        Hide
        lukaszlenart Lukasz Lenart added a comment -

        Now I have connected the dots It is possible to set this back to "200" just by defining a param validationFailedStatus i.e.

        <interceptor-ref name="jsonValidation">
          <param name="validationFailedStatus">200</param>
        </interceptor-ref>
        

        Now I wonder if this should be reverted to "200" by default ...

        Show
        lukaszlenart Lukasz Lenart added a comment - Now I have connected the dots It is possible to set this back to "200" just by defining a param validationFailedStatus i.e. <interceptor-ref name= "jsonValidation" > <param name= "validationFailedStatus" > 200 </param> </interceptor-ref> Now I wonder if this should be reverted to "200" by default ...
        Hide
        cn42 Christoph Nenning added a comment -

        Now I wonder if this should be reverted to "200" by default ...

        Well, in our company we've been already through the pain to change our JS validation stuff. If it is reverted back we will have that pain agian ...

        On the other hand: other users might not have been affected so far (because they update lazily) and we could avoid pain for them...

        Show
        cn42 Christoph Nenning added a comment - Now I wonder if this should be reverted to "200" by default ... Well, in our company we've been already through the pain to change our JS validation stuff. If it is reverted back we will have that pain agian ... On the other hand: other users might not have been affected so far (because they update lazily) and we could avoid pain for them...
        Hide
        lukaszlenart Lukasz Lenart added a comment -

        Sorry for that Anyway, using "200" as a status code for validation errors isn't a good practise, in most case it should be "40x"

        Show
        lukaszlenart Lukasz Lenart added a comment - Sorry for that Anyway, using "200" as a status code for validation errors isn't a good practise, in most case it should be "40x"
        Hide
        walkn COMBEAU added a comment -

        Is my issue related to my jQuery version ? I don't think that's a jQuery issue.

        Why status code should be 400 when validation on server side is not correct.

        Explanation :
        A request posted to the struts action can be good with no errors but a business rules on the server side can throw "errors" if business rules are not "valid" and return some functionnal errors to the client side and the status code shoud be 200.

        Status code 400 means : The server cannot or will not process the request due to an apparent client error (e.g., malformed request syntax, too large size, invalid request message framing, or deceptive request routing).

        You can see it on : this site with the RFC2616

        Show
        walkn COMBEAU added a comment - Is my issue related to my jQuery version ? I don't think that's a jQuery issue. Why status code should be 400 when validation on server side is not correct. Explanation : A request posted to the struts action can be good with no errors but a business rules on the server side can throw "errors" if business rules are not "valid" and return some functionnal errors to the client side and the status code shoud be 200. Status code 400 means : The server cannot or will not process the request due to an apparent client error (e.g., malformed request syntax, too large size, invalid request message framing, or deceptive request routing). You can see it on : this site with the RFC2616
        Hide
        cn42 Christoph Nenning added a comment -

        In this case 'validation errors' means something like 'string too long' or 'invalid interger'. So it is about client side errors.

        I find it an improvement to have a distinct JS function to handle those validation errors instead of having if-blocks in success function.

        Show
        cn42 Christoph Nenning added a comment - In this case 'validation errors' means something like 'string too long' or 'invalid interger'. So it is about client side errors. I find it an improvement to have a distinct JS function to handle those validation errors instead of having if-blocks in success function.
        Hide
        lukaszlenart Lukasz Lenart added a comment -

        It isn't a jQuery issue.

        And regarding your explanation, you assume that there is a user that can read and understand the message, but what if the client isn't a human? what's the difference between "200 valid" and "200 invalid" then? and what's the difference between a server and an app running on it? when you deploy your app using a cloud, there is no the server, the same for self-hosted apps - from a client perspective there is no difference if "400" was posted by a server or by an app.

        10.4.1 400 Bad Request
        
        The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
        
        Show
        lukaszlenart Lukasz Lenart added a comment - It isn't a jQuery issue. And regarding your explanation, you assume that there is a user that can read and understand the message, but what if the client isn't a human? what's the difference between "200 valid" and "200 invalid" then? and what's the difference between a server and an app running on it? when you deploy your app using a cloud, there is no the server, the same for self-hosted apps - from a client perspective there is no difference if "400" was posted by a server or by an app. 10.4.1 400 Bad Request The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.
        Hide
        walkn COMBEAU added a comment -

        So, for me if on the client side it's a human that do the request he can look the status code and adapt his request till have a status 200.

        As mention in my screenshot, the status code 400 returned by the server throw an error in jQuery side. This is not my source code it's in the jQuery source code where you can see the error.

        But if you have some business rules validation on the server side because you have to check some datas with webservices or database or anything else you can't do this on the client side via JavaScript function. You can have many others errors that is not due to malformed syntax.

        In this case, it's not malformed syntax and 4xx shouldn't be return.

        Show
        walkn COMBEAU added a comment - So, for me if on the client side it's a human that do the request he can look the status code and adapt his request till have a status 200. As mention in my screenshot, the status code 400 returned by the server throw an error in jQuery side. This is not my source code it's in the jQuery source code where you can see the error. But if you have some business rules validation on the server side because you have to check some datas with webservices or database or anything else you can't do this on the client side via JavaScript function. You can have many others errors that is not due to malformed syntax. In this case, it's not malformed syntax and 4xx shouldn't be return.
        Hide
        lukaszlenart Lukasz Lenart added a comment -

        There is no rule to return "400" but it's a good practice, please see
        http://stackoverflow.com/questions/3290182/rest-http-status-codes-for-failed-validation-or-invalid-duplicate
        http://stackoverflow.com/questions/8944168/restful-service-how-to-respond-if-validation-failed

        The error is thrown in jQuery because you are missing JavaScript .error() handler to handle errors from server side. Also as I already posted you can revert to previous behaviour with this:

        <interceptor-ref name="jsonValidation">
          <param name="validationFailedStatus">200</param>
        </interceptor-ref>
        
        Show
        lukaszlenart Lukasz Lenart added a comment - There is no rule to return "400" but it's a good practice, please see http://stackoverflow.com/questions/3290182/rest-http-status-codes-for-failed-validation-or-invalid-duplicate http://stackoverflow.com/questions/8944168/restful-service-how-to-respond-if-validation-failed The error is thrown in jQuery because you are missing JavaScript .error() handler to handle errors from server side. Also as I already posted you can revert to previous behaviour with this: <interceptor-ref name= "jsonValidation" > <param name= "validationFailedStatus" > 200 </param> </interceptor-ref>
        Hide
        walkn COMBEAU added a comment -

        I have done the override to revert to the previous behaviour.

        For information, in my JavaScript file, I am using this : getJSON of jQuery.

        Show
        walkn COMBEAU added a comment - I have done the override to revert to the previous behaviour. For information, in my JavaScript file, I am using this : getJSON of jQuery.

          People

          • Assignee:
            Unassigned
            Reporter:
            walkn COMBEAU
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development