001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.http.remote; 018 019import static java.lang.annotation.ElementType.*; 020import static java.lang.annotation.RetentionPolicy.*; 021 022import java.lang.annotation.*; 023 024/** 025 * REST proxy method-level <c>multipart/form-data</c> marker annotation. 026 * 027 * <p> 028 * Marks a {@link Remote}-proxy method whose request body is a {@code multipart/form-data} message (RFC 7578) 029 * assembled from the method's {@link org.apache.juneau.http.Part @Part}-annotated parameters — the 030 * Retrofit <c>@Multipart</c> pattern. Each {@code @Part} parameter contributes one part (a text field, a 031 * file/stream/byte-array upload, or a serialized bean); the engine adapts those parameters into the streaming 032 * {@link org.apache.juneau.http.entity.MultipartBody} and the {@code multipart/form-data} {@code Content-Type} 033 * (with its generated boundary) is applied automatically. 034 * 035 * <h5 class='figure'>Example:</h5> 036 * <p class='bjava'> 037 * <ja>@Remote</ja>(path=<js>"/api"</js>) 038 * <jk>public interface</jk> UploadService { 039 * <ja>@RemotePost</ja>(<js>"/upload"</js>) 040 * <ja>@Multipart</ja> 041 * String upload( 042 * <ja>@Part</ja>(<js>"title"</js>) String <jv>title</jv>, 043 * <ja>@Part</ja>(name=<js>"attachment"</js>, contentType=<js>"application/pdf"</js>) File <jv>report</jv>); 044 * } 045 * </p> 046 * 047 * <h5 class='section'>Body-mode exclusivity:</h5> 048 * <p> 049 * A method is either <i>multipart</i> ({@code @Multipart} + one or more {@link org.apache.juneau.http.Part @Part} 050 * parameters) or <i>single-body</i> ({@link org.apache.juneau.http.Content @Content}), never both. Declaring both 051 * on the same method — or declaring {@code @Multipart} with no {@code @Part} parameters, or a {@code @Part} 052 * parameter without {@code @Multipart} — is rejected at proxy-build time with an 053 * {@link IllegalArgumentException}. 054 * 055 * <h5 class='section'>Notes:</h5><ul> 056 * <li class='note'> 057 * <b>Escape hatch (Option B):</b> for advanced cases you can still hand-assemble a 058 * {@link org.apache.juneau.http.entity.MultipartBody} and pass it as a single 059 * {@link org.apache.juneau.http.Content @Content} body without {@code @Multipart}; that path is unchanged. 060 * <li class='note'> 061 * Honored by the next-generation engine (<c>RestClient.remote(...)</c>) only; the classic engine currently 062 * ignores this annotation. 063 * </ul> 064 * 065 * <h5 class='section'>See Also:</h5><ul> 066 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/NextGenRestClient">Next-Generation REST Client</a> 067 * <li class='extlink'><a class="doclink" href="https://www.rfc-editor.org/rfc/rfc7578">RFC 7578 — multipart/form-data</a> 068 * </ul> 069 * 070 * @since 9.2.1 071 */ 072@Documented 073@Target(METHOD) 074@Retention(RUNTIME) 075@Inherited 076public @interface Multipart { 077}