Home > Contracting, Development, discourse, Java, JavaEE, programming > My HTTP Response Java Enumeration Type (Contracting;-)

My HTTP Response Java Enumeration Type (Contracting;-)

November 27th, 2013

Here is a HTTP Response Java Enumeration type from yesteryear.
In some client’s project, I have seen various constants like this:

final static int OK = 200
final static int OK_STRING = "200"

Which is absolutely awful and these constants are not consistently used in the code base. Worse of all, the code I have refactored will use literal constants.

assertEquals(200, webResponse.getStatusCode() );
assertEquals("404", someOtherResponse.getStatus() );

Even more worse, is the fact these bad coding practices appear in unit test code, if you are lucky to find any testing code at all. (It seems code should just work with no proof of measurement or check of behaviour ;-)

So here is my solution for clients:

// LICENSE GPL 3.0 Peter Pilgrim, Xenonique.co.uk, 2012
// http://www.gnu.org/licenses/gpl.html GNU PUBLIC LICENSE 3.0
package uk.co.xenonique.http.net;

/**
 * Implementation type HttpStatusCode
 *
 * (Only codes 400 to 417 and codes 500 to 524 implemented)
 *
 * @see "http://en.wikipedia.org/wiki/List_of_HTTP_status_codes"
 */
public enum HttpStatusCode {
    CONTINUE(100, "Continue"),
    SWITCHING_PROTOCOL(101, "Switching Protocols"),
    PROCESSING(102, "Processing"),

    OK(200, "OK"),
    CREATED(201, "Created"),
    ACCEPTED(202, "Accepted"),
    NON_AUTHORITATIVE_INFORMATION(203, "Non-Authoritative Information"),
    NO_CONTENT(204,  "No Content"),
    RESET_CONTENT(205, "Reset Content"),
    PARTIAL_CONTENT(206, "Partial Content"),
    MULTI_STATUS(207, "Multi-Status (WebDAV; RFC 4918"),
    ALREADY_REPORTED(208, "Already Reported (WebDAV; RFC 5842)" ),
    IM_USED(226, "IM Used (RFC 3229)"),

    MULTIPLE_CHOICES(300, "Multiple Choices"),
    MOVED_PERMANENTLY(301, "Moved Permanently"),
    FOUND(302, "Found"),
    SEE_OTHER(303, "See Other (since HTTP/1.1)"),
    NOT_MODIFIED(304, "Not Modified"),
    USE_PROXY(305, "Use Proxy (since HTTP/1.1)"),
    SWITCH_PROXY(306, "Switch Proxy"),
    TEMPORARY_REDIRECT(307, "Temporary Redirect (since HTTP/1.1)"),
    PERMANENT_REDIRECT(308, "Permanent Redirect (approved as experimental RFC)[12]"),

    BAD_REQUEST(400, "Bad Request"),
    UNAUTHORIZED(401, "Unauthorized"),
    PAYMENT_REQUIRED(402, "Payment Required"),
    FORBIDDEN(403, "Forbidden"),
    NOT_FOUND(404, "Not Found"),
    METHOD_NOT_ALLOWED(405, "Method Not Allowed"),
    NOT_ACCEPTABLE(406, "Not Acceptable"),
    PROXY_AUTHENTICATION_REQUIRED(407, "Proxy Authentication Required"),
    REQUEST_TIMEOUT(408, "Request Timeout"),
    CONFLICT(409, "Conflict"),
    GONE(410, "Gone"),
    LENGTH_REQUIRED(411, "Length Required"),
    PRECONDITION_FAILED(412, "Precondition Failed"),
    REQUEST_ENTITY_TOO_LARGE(413, "Request Entity Too Large"),
    REQUEST_URI_TOO_LONG(414, "Request-URI Too Long"),
    UNSUPPORTED_MEDIA_TYPE(415, "Unsupported Media Type"),
    REQUESTED_RANGE_NOT_SATISFIABLE(416, "Requested Range Not Satisfiable"),
    EXPECTATION_FAILED(417, "Expectation Failed"),

    INTERNAL_SERVER_ERROR(500, "Internal Server Error"),
    NOT_IMPLEMENTED(501, "Not Implemented"),
    BAD_GATEWAY(502, "Bad Gateway"),
    SERVICE_UNAVAILABLE(503, "Service Unavailable"),
    GATEWAY_TIMEOUT(504, "Gateway Timeout"),
    HTTP_VERSION_NOT_SUPPORTED(505, "HTTP Version Not Supported"),
    VARIANT_ALSO_NEGOTIATES(506, "Variant Also Negotiates (RFC 2295)"),
    INSUFFICIENT_STORAGE(507, "Insufficient Storage (WebDAV; RFC 4918)"),
    LOOP_DETECTED(508, "Loop Detected (WebDAV; RFC 5842)"),
    BANDWIDTH_LIMIT_EXCEEDED(509, "Bandwidth Limit Exceeded (Apache bw/limited extension)"),
    NOT_EXTEND(510, "Not Extended (RFC 2774)"),
    NETWORK_AUTHENTICATION_REQUIRED(511, "Network Authentication Required (RFC 6585)"),
    CONNECTION_TIMED_OUT(522, "Connection timed out"),
    PROXY_DECLINED_REQUEST(523, "Proxy Declined Request"),
    TIMEOUT_OCCURRED(524, "A timeout occurred")
    ;

    private int code;
    private String desc;
    private String text;

    HttpStatusCode(int code, String desc) {
        this.code = code;
        this.desc = desc;
        this.text = Integer.toString(code);
    }

    /**
     * Gets the HTTP status code
     * @return the status code number
     */
    public int getCode() {
        return code;
    }

    /**
     * Gets the HTTP status code as a text string
     * @return the status code as a text string
     */
    public String asText() {
        return text;
    }

    /**
     * Get the description
     * @return the description of the status code
     */
    public String getDesc() {
        return desc;
    }

}

On the other hand, if you work with JAX-RS (Jersey or RestEasy) in Java EE, you get these constants for free!

assertEquals(HttpStatusCode.getCode(), webResponse.getStatusCode() );
assertEquals(HttpStatusCode.asText(), someOtherResponse.getStatus() );

Please tell me, as a Java enterprise engineer, what you would prefer?

+PP+

  • Oliver Gierke
  • Jacek Jackowiak

    +1 for the teapot!

  • Richard_Warburton

    While your choice of an enumeration is a good one, its worth noting that if they just want a standard definition of the http status codes even without using JAX-RS the HttpServletResponse class provides definition for the common ones.

    http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletResponse.html

  • http://xenonique.co.uk/blog/ Peter Pilgrim

    You are absolutely correct there. The original constants were created pre Java SE 5, therefore they used integer constants instead of Enum. Maybe Java EE 8 or better will fix this one day.

    Because of Java frameworks like Play and others, maybe javax.servlet.* and javax.servlet.http.* has had it’s day or needs a rethink to direct REST principles.