/*
 * Copyright 2002-2020 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.http.codec.multipart;

import java.nio.file.Path;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.ContentDisposition;
import org.springframework.http.HttpHeaders;
import org.springframework.util.Assert;

Default implementations of Part and subtypes.
Author:Arjen Poutsma
Since:5.3
/** * Default implementations of {@link Part} and subtypes. * * @author Arjen Poutsma * @since 5.3 */
abstract class DefaultParts {
Create a new FormFieldPart with the given parameters.
Params:
  • headers – the part headers
  • value – the form field value
Returns:the created part
/** * Create a new {@link FormFieldPart} with the given parameters. * @param headers the part headers * @param value the form field value * @return the created part */
public static FormFieldPart formFieldPart(HttpHeaders headers, String value) { Assert.notNull(headers, "Headers must not be null"); Assert.notNull(value, "Value must not be null"); return new DefaultFormFieldPart(headers, value); }
Create a new Part or FilePart with the given parameters. Returns FilePart if the Content-Disposition of the given headers contains a filename, or a "normal" Part otherwise
Params:
  • headers – the part headers
  • content – the content of the part
Returns:Part or FilePart, depending on HttpHeaders.getContentDisposition()
/** * Create a new {@link Part} or {@link FilePart} with the given parameters. * Returns {@link FilePart} if the {@code Content-Disposition} of the given * headers contains a filename, or a "normal" {@link Part} otherwise * @param headers the part headers * @param content the content of the part * @return {@link Part} or {@link FilePart}, depending on {@link HttpHeaders#getContentDisposition()} */
public static Part part(HttpHeaders headers, Flux<DataBuffer> content) { Assert.notNull(headers, "Headers must not be null"); Assert.notNull(content, "Content must not be null"); String filename = headers.getContentDisposition().getFilename(); if (filename != null) { return new DefaultFilePart(headers, content); } else { return new DefaultPart(headers, content); } }
Abstract base class.
/** * Abstract base class. */
private static abstract class AbstractPart implements Part { private final HttpHeaders headers; protected AbstractPart(HttpHeaders headers) { Assert.notNull(headers, "HttpHeaders is required"); this.headers = headers; } @Override public String name() { String name = headers().getContentDisposition().getName(); Assert.state(name != null, "No name available"); return name; } @Override public HttpHeaders headers() { return this.headers; } }
Default implementation of FormFieldPart.
/** * Default implementation of {@link FormFieldPart}. */
private static class DefaultFormFieldPart extends AbstractPart implements FormFieldPart { private final String value; public DefaultFormFieldPart(HttpHeaders headers, String value) { super(headers); this.value = value; } @Override public Flux<DataBuffer> content() { return Flux.defer(() -> { byte[] bytes = this.value.getBytes(MultipartUtils.charset(headers())); return Flux.just(DefaultDataBufferFactory.sharedInstance.wrap(bytes)); }); } @Override public String value() { return this.value; } @Override public String toString() { String name = headers().getContentDisposition().getName(); if (name != null) { return "DefaultFormFieldPart{" + name() + "}"; } else { return "DefaultFormFieldPart"; } } }
Default implementation of Part.
/** * Default implementation of {@link Part}. */
private static class DefaultPart extends AbstractPart { private final Flux<DataBuffer> content; public DefaultPart(HttpHeaders headers, Flux<DataBuffer> content) { super(headers); this.content = content; } @Override public Flux<DataBuffer> content() { return this.content; } @Override public String toString() { String name = headers().getContentDisposition().getName(); if (name != null) { return "DefaultPart{" + name + "}"; } else { return "DefaultPart"; } } }
Default implementation of FilePart.
/** * Default implementation of {@link FilePart}. */
private static class DefaultFilePart extends DefaultPart implements FilePart { public DefaultFilePart(HttpHeaders headers, Flux<DataBuffer> content) { super(headers, content); } @Override public String filename() { String filename = this.headers().getContentDisposition().getFilename(); Assert.state(filename != null, "No filename found"); return filename; } @Override public Mono<Void> transferTo(Path dest) { return DataBufferUtils.write(content(), dest); } @Override public String toString() { ContentDisposition contentDisposition = headers().getContentDisposition(); String name = contentDisposition.getName(); String filename = contentDisposition.getFilename(); if (name != null) { return "DefaultFilePart{" + name() + " (" + filename + ")}"; } else { return "DefaultFilePart{(" + filename + ")}"; } } } }