spring DefaultServerRequestBuilder 源码
spring DefaultServerRequestBuilder 代码
文件路径:/spring-webmvc/src/main/java/org/springframework/web/servlet/function/DefaultServerRequestBuilder.java
/*
* Copyright 2002-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.function;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.net.InetSocketAddress;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import jakarta.servlet.http.Part;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.converter.GenericHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.util.UriBuilder;
import org.springframework.web.util.UriComponentsBuilder;
/**
* Default {@link ServerRequest.Builder} implementation.
*
* @author Arjen Poutsma
* @since 5.2
*/
class DefaultServerRequestBuilder implements ServerRequest.Builder {
private final HttpServletRequest servletRequest;
private final List<HttpMessageConverter<?>> messageConverters;
private HttpMethod method;
private URI uri;
private final HttpHeaders headers = new HttpHeaders();
private final MultiValueMap<String, Cookie> cookies = new LinkedMultiValueMap<>();
private final Map<String, Object> attributes = new LinkedHashMap<>();
private final MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
@Nullable
private InetSocketAddress remoteAddress;
private byte[] body = new byte[0];
public DefaultServerRequestBuilder(ServerRequest other) {
Assert.notNull(other, "ServerRequest must not be null");
this.servletRequest = other.servletRequest();
this.messageConverters = new ArrayList<>(other.messageConverters());
this.method = other.method();
this.uri = other.uri();
headers(headers -> headers.addAll(other.headers().asHttpHeaders()));
cookies(cookies -> cookies.addAll(other.cookies()));
attributes(attributes -> attributes.putAll(other.attributes()));
params(params -> params.addAll(other.params()));
this.remoteAddress = other.remoteAddress().orElse(null);
}
@Override
public ServerRequest.Builder method(HttpMethod method) {
Assert.notNull(method, "HttpMethod must not be null");
this.method = method;
return this;
}
@Override
public ServerRequest.Builder uri(URI uri) {
Assert.notNull(uri, "URI must not be null");
this.uri = uri;
return this;
}
@Override
public ServerRequest.Builder header(String headerName, String... headerValues) {
for (String headerValue : headerValues) {
this.headers.add(headerName, headerValue);
}
return this;
}
@Override
public ServerRequest.Builder headers(Consumer<HttpHeaders> headersConsumer) {
headersConsumer.accept(this.headers);
return this;
}
@Override
public ServerRequest.Builder cookie(String name, String... values) {
for (String value : values) {
this.cookies.add(name, new Cookie(name, value));
}
return this;
}
@Override
public ServerRequest.Builder cookies(Consumer<MultiValueMap<String, Cookie>> cookiesConsumer) {
cookiesConsumer.accept(this.cookies);
return this;
}
@Override
public ServerRequest.Builder body(byte[] body) {
this.body = body;
return this;
}
@Override
public ServerRequest.Builder body(String body) {
return body(body.getBytes(StandardCharsets.UTF_8));
}
@Override
public ServerRequest.Builder attribute(String name, Object value) {
Assert.notNull(name, "'name' must not be null");
this.attributes.put(name, value);
return this;
}
@Override
public ServerRequest.Builder attributes(Consumer<Map<String, Object>> attributesConsumer) {
attributesConsumer.accept(this.attributes);
return this;
}
@Override
public ServerRequest.Builder param(String name, String... values) {
for (String value : values) {
this.params.add(name, value);
}
return this;
}
@Override
public ServerRequest.Builder params(Consumer<MultiValueMap<String, String>> paramsConsumer) {
paramsConsumer.accept(this.params);
return this;
}
@Override
public ServerRequest.Builder remoteAddress(InetSocketAddress remoteAddress) {
this.remoteAddress = remoteAddress;
return this;
}
@Override
public ServerRequest build() {
return new BuiltServerRequest(this.servletRequest, this.method, this.uri, this.headers, this.cookies,
this.attributes, this.params, this.remoteAddress, this.body, this.messageConverters);
}
private static class BuiltServerRequest implements ServerRequest {
private final HttpMethod method;
private final URI uri;
private final HttpHeaders headers;
private final HttpServletRequest servletRequest;
private final MultiValueMap<String, Cookie> cookies;
private final Map<String, Object> attributes;
private final byte[] body;
private final List<HttpMessageConverter<?>> messageConverters;
private final MultiValueMap<String, String> params;
@Nullable
private final InetSocketAddress remoteAddress;
public BuiltServerRequest(HttpServletRequest servletRequest, HttpMethod method, URI uri,
HttpHeaders headers, MultiValueMap<String, Cookie> cookies,
Map<String, Object> attributes, MultiValueMap<String, String> params,
@Nullable InetSocketAddress remoteAddress, byte[] body, List<HttpMessageConverter<?>> messageConverters) {
this.servletRequest = servletRequest;
this.method = method;
this.uri = uri;
this.headers = new HttpHeaders(headers);
this.cookies = new LinkedMultiValueMap<>(cookies);
this.attributes = new LinkedHashMap<>(attributes);
this.params = new LinkedMultiValueMap<>(params);
this.remoteAddress = remoteAddress;
this.body = body;
this.messageConverters = messageConverters;
}
@Override
public HttpMethod method() {
return this.method;
}
@Override
@Deprecated
public String methodName() {
return this.method.name();
}
@Override
public MultiValueMap<String, Part> multipartData() throws IOException, ServletException {
return servletRequest().getParts().stream()
.collect(Collectors.groupingBy(Part::getName,
LinkedMultiValueMap::new,
Collectors.toList()));
}
@Override
public URI uri() {
return this.uri;
}
@Override
public UriBuilder uriBuilder() {
return UriComponentsBuilder.fromUri(this.uri);
}
@Override
public Headers headers() {
return new DefaultServerRequest.DefaultRequestHeaders(this.headers);
}
@Override
public MultiValueMap<String, Cookie> cookies() {
return this.cookies;
}
@Override
public Optional<InetSocketAddress> remoteAddress() {
return Optional.ofNullable(this.remoteAddress);
}
@Override
public List<HttpMessageConverter<?>> messageConverters() {
return this.messageConverters;
}
@Override
public <T> T body(Class<T> bodyType) throws IOException, ServletException {
return bodyInternal(bodyType, bodyType);
}
@Override
public <T> T body(ParameterizedTypeReference<T> bodyType) throws IOException, ServletException {
Type type = bodyType.getType();
return bodyInternal(type, DefaultServerRequest.bodyClass(type));
}
@SuppressWarnings("unchecked")
private <T> T bodyInternal(Type bodyType, Class<?> bodyClass) throws ServletException, IOException {
HttpInputMessage inputMessage = new BuiltInputMessage();
MediaType contentType = headers().contentType().orElse(MediaType.APPLICATION_OCTET_STREAM);
for (HttpMessageConverter<?> messageConverter : this.messageConverters) {
if (messageConverter instanceof GenericHttpMessageConverter) {
GenericHttpMessageConverter<T> genericMessageConverter =
(GenericHttpMessageConverter<T>) messageConverter;
if (genericMessageConverter.canRead(bodyType, bodyClass, contentType)) {
return genericMessageConverter.read(bodyType, bodyClass, inputMessage);
}
}
if (messageConverter.canRead(bodyClass, contentType)) {
HttpMessageConverter<T> theConverter =
(HttpMessageConverter<T>) messageConverter;
Class<? extends T> clazz = (Class<? extends T>) bodyClass;
return theConverter.read(clazz, inputMessage);
}
}
throw new HttpMediaTypeNotSupportedException(contentType, Collections.emptyList(), method());
}
@Override
public Map<String, Object> attributes() {
return this.attributes;
}
@Override
public MultiValueMap<String, String> params() {
return this.params;
}
@Override
public Map<String, String> pathVariables() {
@SuppressWarnings("unchecked")
Map<String, String> pathVariables = (Map<String, String>) attributes()
.get(RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
if (pathVariables != null) {
return pathVariables;
}
else {
return Collections.emptyMap();
}
}
@Override
public HttpSession session() {
return this.servletRequest.getSession();
}
@Override
public Optional<Principal> principal() {
return Optional.ofNullable(this.servletRequest.getUserPrincipal());
}
@Override
public HttpServletRequest servletRequest() {
return this.servletRequest;
}
private class BuiltInputMessage implements HttpInputMessage {
@Override
public InputStream getBody() throws IOException {
return new BodyInputStream(body);
}
@Override
public HttpHeaders getHeaders() {
return headers;
}
}
}
private static class BodyInputStream extends ServletInputStream {
private final InputStream delegate;
public BodyInputStream(byte[] body) {
this.delegate = new ByteArrayInputStream(body);
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
throw new UnsupportedOperationException();
}
@Override
public int read() throws IOException {
return this.delegate.read();
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
return this.delegate.read(b, off, len);
}
@Override
public int read(byte[] b) throws IOException {
return this.delegate.read(b);
}
@Override
public long skip(long n) throws IOException {
return this.delegate.skip(n);
}
@Override
public int available() throws IOException {
return this.delegate.available();
}
@Override
public void close() throws IOException {
this.delegate.close();
}
@Override
public synchronized void mark(int readlimit) {
this.delegate.mark(readlimit);
}
@Override
public synchronized void reset() throws IOException {
this.delegate.reset();
}
@Override
public boolean markSupported() {
return this.delegate.markSupported();
}
}
}
相关信息
相关文章
spring AbstractServerResponse 源码
spring ChangePathPatternParserVisitor 源码
spring DefaultAsyncServerResponse 源码
spring DefaultEntityResponseBuilder 源码
spring DefaultRenderingResponseBuilder 源码
spring DefaultServerRequest 源码
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦