All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cc.shacocloud.mirage.web.http.HttpHeaderMap Maven / Gradle / Ivy

package cc.shacocloud.mirage.web.http;

import cc.shacocloud.mirage.utils.HttpMethodUtils;
import cc.shacocloud.mirage.web.exception.HttpMediaTypeNotAcceptableException;
import cc.shacocloud.mirage.web.exception.InvalidMediaTypeException;
import io.vertx.core.MultiMap;
import io.vertx.core.http.HttpMethod;
import org.jetbrains.annotations.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;

import static io.vertx.core.http.HttpHeaders.*;

public class HttpHeaderMap implements MultiMap {

    private final MultiMap headerMap;

    public static final List MEDIA_TYPE_ALL_LIST = Collections.singletonList(MediaType.ALL);

    public HttpHeaderMap(MultiMap headerMap) {
        this.headerMap = headerMap;
    }

    /**
     * 返回媒体类型的身体,由指定 {@code Content-Type}首部
     */
    public MediaType getContentType() {
        String value = get(CONTENT_TYPE);
        return (StringUtils.hasLength(value) ? MediaType.parseMediaType(value) : null);
    }

    /**
     * 设置主体的{@linkplain MediaType},由{@code Content-Type}头指定。
     */
    public void setContentType(@Nullable MediaType mediaType) {
        if (mediaType != null) {
            Assert.isTrue(!mediaType.isWildcardType(), "内容类型不能包含通配符类型 '*'");
            Assert.isTrue(!mediaType.isWildcardSubtype(), "内容类型不能包含通配符子类型 '*'");
            set(CONTENT_TYPE, mediaType.toString());
        } else {
            remove(CONTENT_TYPE);
        }
    }

    /**
     * 返回主体的长度(以字节为单位),由{@code Content-Length}头指定。
     * 

* 当内容长度未知时返回-1。 */ public long getContentLength() { String value = get(CONTENT_LENGTH); return (value != null ? Long.parseLong(value) : -1); } /** * 设置主体的长度(以字节为单位),由{@code Content-Length}头指定。 */ public void setContentLength(long contentLength) { set(CONTENT_LENGTH, Long.toString(contentLength)); } /** * 获取可接受的媒体类型 * * @throws HttpMediaTypeNotAcceptableException 如果无法解析请求的媒体类型则抛出该例外 */ public List getAcceptableMediaTypes() throws HttpMediaTypeNotAcceptableException { List headerValues = getAll(ACCEPT); if (headerValues == null || headerValues.isEmpty()) { return MEDIA_TYPE_ALL_LIST; } try { List mediaTypes = MediaType.parseMediaTypes(headerValues); MediaType.sortBySpecificityAndQuality(mediaTypes); return !CollectionUtils.isEmpty(mediaTypes) ? mediaTypes : MEDIA_TYPE_ALL_LIST; } catch (InvalidMediaTypeException ex) { throw new HttpMediaTypeNotAcceptableException( "不能解析'Accept'头" + headerValues + ": " + ex.getMessage()); } } /** * 设置{@code Origin}头的(新)值。 */ public void setOrigin(@Nullable String origin) { setOrRemove(ORIGIN, origin); } /** * 返回{@code Origin}头的值。 */ @Nullable public String getOrigin() { return get(ORIGIN); } /** * 返回{@code Access-Control-Request-Method}请求头的值。 */ @Nullable public HttpMethod getAccessControlRequestMethod() { return HttpMethodUtils.resolve(get(ACCESS_CONTROL_REQUEST_METHOD)); } /** * 返回{@code Access-Control-Request-Headers}请求头的值。 */ public List getAccessControlRequestHeaders() { return getAll(ACCESS_CONTROL_REQUEST_HEADERS); } /** * 设置响应头{@code Access-Control-Allow-Origin}的(新)值。 */ public void setAccessControlAllowOrigin(@Nullable String allowedOrigin) { setOrRemove(ACCESS_CONTROL_ALLOW_ORIGIN, allowedOrigin); } /** * 设置响应头{@code Access-Control-Allow-Methods}的(新)值。 */ public void setAccessControlAllowMethods(List allowedMethods) { set(ACCESS_CONTROL_ALLOW_METHODS, StringUtils.collectionToCommaDelimitedString(allowedMethods)); } /** * 设置响应头{@code Access-Control-Allow-Headers}的(新)值。 */ public void setAccessControlAllowHeaders(List allowedHeaders) { set(ACCESS_CONTROL_ALLOW_HEADERS, String.join(",", allowedHeaders)); } /** * 设置响应头{@code Access-Control-Expose-Headers}的(新)值。 */ public void setAccessControlExposeHeaders(List exposedHeaders) { set(ACCESS_CONTROL_EXPOSE_HEADERS, String.join(",", exposedHeaders)); } /** * 设置响应头{@code Access-Control-Allow-Credentials}的(新)值。 */ public void setAccessControlAllowCredentials(boolean allowCredentials) { set(ACCESS_CONTROL_ALLOW_CREDENTIALS, Boolean.toString(allowCredentials)); } /** * 设置响应头{@code Access-Control-Max-Age}的(新)值。 */ public void setAccessControlMaxAge(long maxAge) { set(ACCESS_CONTROL_MAX_AGE, Long.toString(maxAge)); } /** * 当前连接是否 keep-alive */ public boolean isKeepAlive() { return KEEP_ALIVE.equals(get(CONNECTION)); } // ---------------- 工具方法------------------------------------ /** * 返回包含的键的集合视图 */ public Set keySet() { Set res = new HashSet<>(); this.iterator().forEachRemaining(entry -> res.add(entry.getKey())); return Collections.unmodifiableSet(res); } /** * 设置给定的头值,或删除头如果{@code null}。 * * @param headerName 标题名称 * @param headerValue 头值,或{@code null}表示none */ private void setOrRemove(CharSequence headerName, @Nullable CharSequence headerValue) { if (headerValue != null) { set(headerName, headerValue); } else { remove(headerName); } } // ------------------ MultiMap --------------------------------------------------- @Override public String get(CharSequence name) { return headerMap.get(name); } @Override public String get(String name) { return headerMap.get(name); } @Override public List getAll(String name) { return headerMap.getAll(name); } @Override public List getAll(CharSequence name) { return headerMap.getAll(name); } @Override public boolean contains(String name) { return headerMap.contains(name); } @Override public boolean contains(CharSequence name) { return headerMap.contains(name); } @Override public boolean isEmpty() { return headerMap.isEmpty(); } @Override public Set names() { return headerMap.names(); } @Override public MultiMap add(String name, String value) { return headerMap.add(name, value); } @Override public MultiMap add(CharSequence name, CharSequence value) { return headerMap.add(name, value); } @Override public MultiMap add(String name, Iterable values) { return headerMap.add(name, values); } @Override public MultiMap add(CharSequence name, Iterable values) { return headerMap.add(name, values); } @Override public MultiMap addAll(MultiMap map) { return headerMap.addAll(map); } @Override public MultiMap addAll(Map headers) { return headerMap.addAll(headers); } @Override public MultiMap set(String name, String value) { return headerMap.set(name, value); } @Override public MultiMap set(CharSequence name, CharSequence value) { return headerMap.set(name, value); } @Override public MultiMap set(String name, Iterable values) { return headerMap.set(name, values); } @Override public MultiMap set(CharSequence name, Iterable values) { return headerMap.set(name, values); } @Override public MultiMap setAll(MultiMap map) { return headerMap.setAll(map); } @Override public MultiMap setAll(Map headers) { return headerMap.setAll(headers); } @Override public MultiMap remove(String name) { return headerMap.remove(name); } @Override public MultiMap remove(CharSequence name) { return headerMap.remove(name); } @Override public MultiMap clear() { return headerMap.clear(); } @Override public int size() { return headerMap.size(); } @Override public Iterator> iterator() { return headerMap.iterator(); } @Override public String toString() { return "{\n" + headerMap + "}"; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy