340

I'm wondering if there is an enum type in some standard Java class library that defines symbolic constants for all of the valid HTTP response codes. It should support conversion to/from the corresponding integer values.

I'm debugging some Java code that uses javax.ws.rs.core.Response.Status. It works, but it only defines about half of the valid HTTP response codes.

17 Answers 17

353

I don't think there's one that's complete in the standard Java classes; HttpURLConnection is missing quite a few codes, like HTTP 100/Continue.

There's a complete list in the Apache HttpComponents, though:
org.apache.http.HttpStatus (replaced org.apache.commons.HttpClient.HttpStatus from Apache Http Client, which reached end of life)

Sign up to request clarification or add additional context in comments.

8 Comments

There's is no such a thing as "complete list", as status codes can be and do get extended.
@JulianReschke I think "complete" here should be taken to mean "conforms to all the codes outlined by the standard".
John: "the standard" does not define "all" the status codes. That's why there is a registry.
@Donal: again, not a good list. What's relevant is the IANA registry.
|
100

Well, there are static constants of the exact integer values in the HttpURLConnection class

2 Comments

thx! this works without any external dependencies. java.net.HttpURLConnection.HTTP_BAD_REQUEST
Good that it's part of the standard library but unfortunately it's incomplete - in the 400 range for example it cuts off at 415.
84

The Interface javax.servlet.http.HttpServletResponse from the servlet API has all the response codes in the form of int constants names SC_<description>. See http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletResponse.html

3 Comments

HttpServletResponse supports the RFC1945 and part of RFC2616 standards, but it's missing all of RFC2518. If you need a complete list, see HttpStatus as I mentioned.
HttpServletResponse is also missing the 418 response code defined in RFC 2324
Using HttpServletResponse in anything that runs outside a servlet is likely to lead to diamond dependency problems due to overlapping classes in different servlet artifacts.
23

If you're using Spring, the 3.x release has what your looking for: http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/http/HttpStatus.html

2 Comments

I would like to add that Springs org.springframework.http.HttpStatus (docs.spring.io/spring/docs/current/javadoc-api/org/…) enum, is the only one I could find that provides Java documentation with links to the complete list of status codes and their usage in each enum. If you are already using Spring then this would be the library to use.
It has 100 and 418. Pity that you have to call HttpStatus.XXX.value() to get int.
17

Here's an enum with status codes and their descriptions that (at time of writing) corresponds to the HTTP status code registry.

Note that the registry might get updated, and that sometimes unofficial status codes are used.

public enum HttpStatusCode {

    //1xx: Informational
    CONTINUE(100, "Continue"),
    SWITCHING_PROTOCOLS(101, "Switching Protocols"),
    PROCESSING(102, "Processing"),
    EARLY_HINTS(103, "Early Hints"),

    //2xx: Success
    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"),
    ALREADY_REPORTED(208, "Already Reported"),
    IM_USED(226, "IM Used"),

    //3xx: Redirection
    MULTIPLE_CHOICES(300, "Multiple Choice"),
    MOVED_PERMANENTLY(301, "Moved Permanently"),
    FOUND(302, "Found"),
    SEE_OTHER(303, "See Other"),
    NOT_MODIFIED(304, "Not Modified"),
    USE_PROXY(305, "Use Proxy"),
    TEMPORARY_REDIRECT(307, "Temporary Redirect"),
    PERMANENT_REDIRECT(308, "Permanent Redirect"),

    //4xx: Client Error
    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_TOO_LONG(413, "Payload Too Large"),
    REQUEST_URI_TOO_LONG(414, "URI Too Long"),
    UNSUPPORTED_MEDIA_TYPE(415, "Unsupported Media Type"),
    REQUESTED_RANGE_NOT_SATISFIABLE(416, "Range Not Satisfiable"),
    EXPECTATION_FAILED(417, "Expectation Failed"),
    MISDIRECTED_REQUEST(421, "Misdirected Request"),
    UNPROCESSABLE_ENTITY(422, "Unprocessable Entity"),
    LOCKED(423, "Locked"),
    FAILED_DEPENDENCY(424, "Failed Dependency"),
    TOO_EARLY(425, "Too Early"),
    UPGRADE_REQUIRED(426, "Upgrade Required"),
    PRECONDITION_REQUIRED(428, "Precondition Required"),
    TOO_MANY_REQUESTS(429, "Too Many Requests"),
    REQUEST_HEADER_FIELDS_TOO_LARGE(431, "Request Header Fields Too Large"),
    UNAVAILABLE_FOR_LEGAL_REASONS(451, "Unavailable For Legal Reasons"),

    //5xx: Server Error
    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"),
    INSUFFICIENT_STORAGE(507, "Insufficient Storage"),
    LOOP_DETECTED(508, "Loop Detected"),
    NOT_EXTENDED(510, "Not Extended"),
    NETWORK_AUTHENTICATION_REQUIRED(511, "Network Authentication Required");

    private final int value;
    private final String description;

    HttpStatusCode(int value, String description) {
        this.value = value;
        this.description = description;
    }

    public int getValue() {
        return value;
    }

    public String getDescription() {
        return description;
    }

    @Override
    public String toString() {
        return value + " " + description;
    }

    public static HttpStatusCode getByValue(int value) {
        for(HttpStatusCode status : values()) {
            if(status.value == value) return status;
        }
        throw new IllegalArgumentException("Invalid status code: " + value);
    }
}

Comments

13

Everyone seems to be ignoring the "enum type" portion of your question.

While there is no canonical source for HTTP Status Codes there is an simple way to add any missing Status constants you need to those provided by javax.ws.rs.core.Response.Status without adding any additional dependencies to your project.

javax.ws.rs.core.Response.Status is just one implementation of the javax.ws.rs.core.Response.StatusType interface. You simply need to create your own implementation enum with definitions for the Status Codes that you want.

Core libraries like Javax, Jersey, etc. are written to the interface StatusType not the implementation Status (or they certainly should be). Since your new Status enum implements StatusType it can be used anyplace you would use a javax.ws.rs.core.Response.Status constant.

Just remember that your own code should also be written to the StatusType interface. This will enable you to use both your own Status Codes along side the "standard" ones.

Here's a gist with a simple implementation with constants defined for the "Informational 1xx" Status Codes: https://gist.github.com/avendasora/a5ed9acf6b1ee709a14a

1 Comment

I really like this option of using the Response class, it allows you to have the int for the code, but also the reason phrase in a single object. Besides that, you are probaly already using javax, so you dont have to add anything to pom
7

Use javax.servlet.http.HttpServletResponse class

Example:

javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED //401
javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR //500

3 Comments

for client development, it's burdensome to include the entire servlet API just to pick up these codes.
It might be burdensome for some cases but I've found this good answer and I'm writing a servlet-based web app so it's good for me.
A duplicate answer, posted over three years later? Should be deleted.
7

If you are using Netty, you can use:

1 Comment

unfortunately this is no enum und therefore not usable in case statements(which makes me sad)
5

1) To get the reason text if you only have the code, you can use:

org.apache.http.impl.EnglishReasonPhraseCatalog.INSTANCE.getReason(httpCode,null)

Where httpCode would be the reason code that you got from the HTTP response.

See https://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/impl/EnglishReasonPhraseCatalog.html for details

2) To get the reason code if you only have the text, you can use BasicHttpResponse.

See here for details: https://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/org/apache/http/message/BasicHttpResponse.html

Comments

2

Also check out the Restlet Status class:

http://www.restlet.org/documentation/1.1/api/org/restlet/data/Status.html

1 Comment

Again; status codes are extensible, so there can't be a "complete" list, unless it's revised everytime a new status code is added to the IANA registry (iana.org/assignments/http-status-codes)
1

The best provider for http status code constants is likely to be Jetty's org.eclipse.jetty.http.HttpStatus class because:

  • there is a javadoc package in maven which is important if you search for the constant and only know the number -> just open the api docs page and search for the number
  • the constants contain the status code number itself.

Only thing I would improve: put the status code number in front of the text description in order to make auto-completion lookup more convient when you are starting with the code.

1 Comment

You can't place numbers in front due to Java naming rules but this doesn't matter. A good IDE will auto-complete even if the number shows up later in the name.
1

Please see the following enum from the Spring framework which provides all the HTTP response status code

HttpStatus.values()

Comments

0

pls try HttpStatus.ACCEPTED.value()

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
0

Yet another library to the list:

org.glassfish.grizzly.http.util.HttpStatus

public static final HttpStatus CONINTUE_100 = register(100, "Continue");
public static final HttpStatus SWITCHING_PROTOCOLS_101 = register(101, "Switching Protocols");
public static final HttpStatus WEB_SOCKET_PROTOCOL_HANDSHAKE_101 = register(101, "Web Socket Protocol Handshake");
public static final HttpStatus OK_200 = register(200, "OK");
public static final HttpStatus CREATED_201 = register(201, "Created");
public static final HttpStatus ACCEPTED_202 = register(202, "Accepted");
public static final HttpStatus NON_AUTHORATIVE_INFORMATION_203 = register(203, "Not-Authoritative Information");
public static final HttpStatus NO_CONTENT_204 = register(204, "No Content");
public static final HttpStatus RESET_CONTENT_205 = register(205, "Reset Content");
public static final HttpStatus PARTIAL_CONTENT_206 = register(206, "Partial Content");
public static final HttpStatus MULTIPLE_CHOICES_300 = register(300, "Multiple Choices");
public static final HttpStatus MOVED_PERMANENTLY_301 = register(301, "Moved Permanently");
public static final HttpStatus FOUND_302 = register(302, "Found");
public static final HttpStatus SEE_OTHER_303 = register(303, "See Other");
public static final HttpStatus NOT_MODIFIED_304 = register(304, "Not Modified");
public static final HttpStatus USE_PROXY_305 = register(305, "Use Proxy");
public static final HttpStatus TEMPORARY_REDIRECT_307 = register(307, "Temporary Redirect");
public static final HttpStatus PERMANENT_REDIRECT_308 = register(308, "Permanent Redirect");
public static final HttpStatus BAD_REQUEST_400 = register(400, "Bad Request");
public static final HttpStatus UNAUTHORIZED_401 = register(401, "Unauthorized");
public static final HttpStatus PAYMENT_REQUIRED_402 = register(402, "Payment Required");
public static final HttpStatus FORBIDDEN_403 = register(403, "Forbidden");
public static final HttpStatus NOT_FOUND_404 = register(404, "Not Found");
public static final HttpStatus METHOD_NOT_ALLOWED_405 = register(405, "Method Not Allowed");
public static final HttpStatus NOT_ACCEPTABLE_406 = register(406, "Not Acceptable");
public static final HttpStatus PROXY_AUTHENTICATION_REQUIRED_407 = register(407, "Proxy Authentication Required");
public static final HttpStatus REQUEST_TIMEOUT_408 = register(408, "Request Timeout");
public static final HttpStatus CONFLICT_409 = register(409, "Conflict");
public static final HttpStatus GONE_410 = register(410, "Gone");
public static final HttpStatus LENGTH_REQUIRED_411 = register(411, "Length Required");
public static final HttpStatus PRECONDITION_FAILED_412 = register(412, "Precondition Failed");
public static final HttpStatus REQUEST_ENTITY_TOO_LARGE_413 = register(413, "Request Entity Too Large");
public static final HttpStatus REQUEST_URI_TOO_LONG_414 = register(414, "Request-URI Too Long");
public static final HttpStatus UNSUPPORTED_MEDIA_TYPE_415 = register(415, "Unsupported Media Type");
public static final HttpStatus REQUEST_RANGE_NOT_SATISFIABLE_416 = register(416, "Request Range Not Satisfiable");
public static final HttpStatus EXPECTATION_FAILED_417 = register(417, "Expectation Failed");
public static final HttpStatus MISDIRECTED_REQUEST = register(421, "Misdirected Request");
public static final HttpStatus REQUEST_HEADER_FIELDS_TOO_LARGE = register(431, "Request Header Fields Too Large");
public static final HttpStatus INTERNAL_SERVER_ERROR_500 = register(500, "Internal Server Error");
public static final HttpStatus NOT_IMPLEMENTED_501 = register(501, "Not Implemented");
public static final HttpStatus BAD_GATEWAY_502 = register(502, "Bad Gateway");
public static final HttpStatus SERVICE_UNAVAILABLE_503 = register(503, "Service Unavailable");
public static final HttpStatus GATEWAY_TIMEOUT_504 = register(504, "Gateway Timeout");
public static final HttpStatus HTTP_VERSION_NOT_SUPPORTED_505 = register(505, "HTTP Version Not Supported");

Comments

0

You can use HttpStatusCode from AWS if you are developing for AWS services.

Just import software.amazon.awssdk.http.HttpStatusCode;

It has enum for all status codes:

eg.

HttpStatusCode.INTERNAL_SERVER_ERROR for 500

HttpStatusCode.OK for 200

Comments

0

Java still doesn't have it?

Oh well! Here's a quasi-enum. Remove the NotNull/Nullable references if so desired or replace their imports according to taste.

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;

// ---
// From https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
//
// You can write code like this:
//
/*
final var x = HttpStatusCode.fromCode(203);
        System.out.println(x); // "203"
        System.out.println(x.toStringWithText()); // "203 Non Authoritative Information"

final var y = HttpStatusCode.fromText("Non Authoritative Information").orElseThrow();
        System.out.println(y); // "203"
        System.out.println(y.toStringWithText()); // "203 Non Authoritative Information"

final var z = HttpStatusCode.fromText("Internal Server Error").orElseThrow();
        System.out.println(z); // "500"
        System.out.println(z.toStringWithText()); // "500 Internal Server Error"

        assert x.equals(HttpStatusCode.fromText("Non Authoritative Information").orElseThrow());
        assert x == HttpStatusCode.fromText("Non Authoritative Information").orElseThrow();
        assert x.equals(y);
        assert x == y;
        assert !x.equals(z);
        assert x != z;
 */
// ---

public final class HttpStatusCode {

    private static Map<Integer, String> codeToTextMap;
    private static Map<Integer, String> codeToTextMapUnofficials;
    private static Map<String, Integer> textToCodeMap;

    // This map grows as we request new instances via valueOf().
    // Access to it is synchronized in valueOf().

    private final static Map<Integer, HttpStatusCode> canonicals = new HashMap<>();

    static {
        Map<Integer, String> map = new HashMap<>();
        map.put(100, "Continue");
        map.put(101, "Switching Protocols");
        map.put(102, "Processing");
        map.put(103, "Early Hints");
        map.put(200, "OK");
        map.put(201, "Created");
        map.put(202, "Accepted");
        map.put(203, "Non Authoritative Information");
        map.put(204, "No Content");
        map.put(205, "Reset Content");
        map.put(206, "Partial Content");
        map.put(207, "Multi-Status");
        map.put(208, "Already Reported");
        map.put(226, "IM Used");
        map.put(300, "Multiple Choices");
        map.put(301, "Moved Permanently");
        map.put(302, "Found");
        map.put(303, "See Other");
        map.put(304, "Not Modified");
        map.put(305, "Use Proxy");
        map.put(307, "Temporary Redirect");
        map.put(308, "Permanent Redirect");
        map.put(400, "Bad Request");
        map.put(401, "Unauthorized");
        map.put(402, "Payment Required");
        map.put(403, "Forbidden");
        map.put(404, "Not Found");
        map.put(405, "Method Not Allowed");
        map.put(406, "Not Acceptable");
        map.put(407, "Proxy Authentication Required");
        map.put(408, "Request Timeout");
        map.put(409, "Conflict");
        map.put(410, "Gone");
        map.put(411, "Length Required");
        map.put(412, "Precondition Failed");
        map.put(413, "Payload Too Large");
        map.put(414, "URI Too Long");
        map.put(415, "Unsupported Media Type");
        map.put(416, "Range Not Satisfiable");
        map.put(417, "Expectation Failed");
        map.put(418, "I'm a teapot");
        map.put(421, "Misdirected Request");
        map.put(422, "Unprocessable Content");
        map.put(423, "Locked");
        map.put(424, "Failed Dependency");
        map.put(426, "Upgrade Required");
        map.put(428, "Precondition Required");
        map.put(429, "Too Many Requests");
        map.put(431, "Request Header Fields Too Large");
        map.put(451, "Unavailable For Legal Reasons");
        map.put(500, "Internal Server Error");
        map.put(501, "Not Implemented");
        map.put(502, "Bad Gateway");
        map.put(503, "Service Unavailable");
        map.put(504, "Gateway Timeout");
        map.put(505, "Http Version Not Supported");
        map.put(506, "Variant Also Negotiates");
        map.put(507, "Insufficient Storage");
        map.put(508, "Loop Detected");
        map.put(510, "Not Extended");
        map.put(511, "Network Authentication Required");
        HttpStatusCode.codeToTextMap = Collections.unmodifiableMap(map);
    }

    static {
        Map<Integer, String> map = new HashMap<>();
        map.put(218, "This is fine (Apache HTTP Server)");
        map.put(419, "Page Expired (Laravel Framework)");
        map.put(420, "Method Failure (Spring Framework), Enhance Your Calm (Twitter)");
        map.put(430, "Shopify Security Rejection (Shopify)");
        map.put(450, "Blocked by Windows Parental Controls (Microsoft)");
        map.put(498, "Invalid Token (Esri)");
        map.put(499, "Token Required (Esri)");
        map.put(509, "Bandwidth Limit Exceeded (Apache Web Server/cPanel)");
        map.put(529, "Site is overloaded (Qualys)");
        map.put(530, "Site is frozen (Pantheon), Origin DNS Error (Shopify)");
        map.put(540, "Temporarily Disabled (Shopify)");
        map.put(598, "Network read timeout error (Informal convention)");
        map.put(599, "Network Connect Timeout Error (Inofficial)");
        map.put(783, "Unexpected Token (Shopify)");
        HttpStatusCode.codeToTextMapUnofficials = Collections.unmodifiableMap(map);
    }

    static {
        // Note that we don't put the "unofficials" into the reverse map
        Map<String, Integer> reverseMap = new HashMap<>();
        HttpStatusCode.codeToTextMap.forEach((key, value) -> {
            var old = reverseMap.put(value.toLowerCase().replace(" ", ""), key);
            assert old == null;
        });
        HttpStatusCode.textToCodeMap = Collections.unmodifiableMap(reverseMap);
    }

    // ---
    // Some often used codes that you will use directly
    // ---

    public final static HttpStatusCode ok = fromCode(200);
    public final static HttpStatusCode unauthorized = fromCode(401);
    public final static HttpStatusCode forbidden = fromCode(403);
    public final static HttpStatusCode missing = fromCode(404);
    public final static HttpStatusCode moved = fromCode(301);
    public final static HttpStatusCode internal_server_error = fromCode(500);

    private final int code;
    private final int hashCode;
    private final String asString;
    private final String asStringWithText;

    // ---
    // Constructor is private because customers are expected to only call fromCode() and fromText().
    // ---

    private HttpStatusCode(int code) {
        if (code < 100 || code > 999) {
            throw new IllegalArgumentException("Code " + code + " is out of range [100,999]");
        }
        this.code = code;
        this.hashCode = Objects.hashCode(code);
        this.asString = String.valueOf(code);
        if (codeToTextMap.containsKey(code)) {
            this.asStringWithText = code + " " + codeToTextMap.get(code);
        } else if (codeToTextMapUnofficials.containsKey(code)) {
            this.asStringWithText = code + " " + codeToTextMapUnofficials.get(code);
        } else {
            this.asStringWithText = asString;
        }
    }

    // ---
    // Is there a text description for this instance?
    // ---

    public boolean existsText() {
        return codeToTextMap.containsKey(code) || codeToTextMapUnofficials.containsKey(code);
    }

    // ---
    // No surprises hash code based on the HTTP status code
    // ---

    @Override
    public int hashCode() {
        return hashCode;
    }

    // ---
    // toString() just returns the string-ified numeric code
    // ---

    @Override
    public @NotNull String toString() {
        return asString;
    }

    // ---
    // Equality is basically on code
    // ---

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            assert this.code == ((HttpStatusCode) obj).code;
            return true;
        } else {
            assert !(obj instanceof HttpStatusCode) || this.code != ((HttpStatusCode) obj).code;
            return false;
        }
    }

    // ---
    // Returns the string-ified numeric code and any existing text description that is associated to it
    // ---

    public @NotNull String toStringWithText() {
        return asStringWithText;
    }

    // ---
    // Try to find an official code (the unofficial code are disregarded)
    // that corresponds to the passed "desc" (the description in english)
    // Casing is disregarded, as are blanks.

    public static Optional<HttpStatusCode> fromText(@Nullable String desc) {
        if (desc == null) {
            return Optional.empty();
        } else {
            final String lookFor = desc.toLowerCase().replace(" ", "");
            final Integer res = textToCodeMap.get(lookFor);
            if (res == null) {
                return Optional.empty();
            } else {
                return Optional.of(fromCode(res)); // a new instance may be created
            }
        }
    }

    // ---
    // Obtain a canonical instance of HttpStatusCode.
    // If none exists for that code, it is created.
    // ---

    public static @NotNull HttpStatusCode fromCode(int code) {
        synchronized (canonicals) {
            final HttpStatusCode res = canonicals.get(code);
            if (res != null) {
                return res;
            } else {
                final HttpStatusCode res2 = new HttpStatusCode(code);
                canonicals.put(code, res2);
                return res2;
            }
        }
    }
}

Comments

-1

Another option is to use HttpStatus class from the Apache commons-httpclient which provides you the various Http statuses as constants.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.