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; 018 019import static java.lang.annotation.ElementType.*; 020import static java.lang.annotation.RetentionPolicy.*; 021 022import java.lang.annotation.*; 023 024/** 025 * REST request <c>multipart/form-data</c> part annotation. 026 * 027 * <p> 028 * Identifies a method parameter on a {@link org.apache.juneau.http.remote.Remote}-proxy method (which must also be 029 * marked {@link org.apache.juneau.http.remote.Multipart @Multipart}) as a single part of a {@code multipart/form-data} 030 * request body — the Retrofit <c>@Part</c> pattern. The engine adapts each {@code @Part} parameter into the 031 * streaming {@link org.apache.juneau.http.entity.MultipartBody}. 032 * 033 * <h5 class='topic'>Accepted part-source types</h5> 034 * <p> 035 * The bound argument type determines how the part body is produced: 036 * <ul class='spaced-list'> 037 * <li>{@link CharSequence}/{@link String} (and other scalars such as numbers/booleans) — sent as a text field. 038 * <li><c><jk>byte</jk>[]</c> — sent verbatim (repeatable). 039 * <li>{@link java.io.File} — <b>streamed</b> from disk; the {@link #fileName()} defaults to the file's name. 040 * <li>{@link java.io.InputStream} — <b>streamed</b> (one-shot; makes the request body non-repeatable). 041 * <li>{@link java.io.Reader} — <b>streamed</b> as UTF-8 (one-shot; not drained during request building). 042 * <li>An {@link HttpBody} — used directly. 043 * <li>Any other object (a bean) — serialized with the client's default serializer (e.g. JSON). 044 * </ul> 045 * 046 * <p> 047 * A <jk>null</jk> argument contributes no part. 048 * 049 * <h5 class='figure'>Example:</h5> 050 * <p class='bjava'> 051 * <ja>@RemotePost</ja>(<js>"/upload"</js>) 052 * <ja>@Multipart</ja> 053 * String upload( 054 * <ja>@Part</ja>(<js>"title"</js>) String <jv>title</jv>, 055 * <ja>@Part</ja>(name=<js>"attachment"</js>, fileName=<js>"report.pdf"</js>, contentType=<js>"application/pdf"</js>) <jk>byte</jk>[] <jv>data</jv>); 056 * </p> 057 * 058 * <h5 class='section'>Notes:</h5><ul> 059 * <li class='note'> 060 * Valid only on a method also annotated {@link org.apache.juneau.http.remote.Multipart @Multipart}; a 061 * {@code @Part} parameter on a non-multipart method is rejected at proxy-build time. 062 * <li class='note'> 063 * Honored by the next-generation engine (<c>RestClient.remote(...)</c>) only; the classic engine currently 064 * ignores this annotation. 065 * </ul> 066 * 067 * <h5 class='section'>See Also:</h5><ul> 068 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/NextGenRestClient">Next-Generation REST Client</a> 069 * </ul> 070 * 071 * @since 9.2.1 072 */ 073@Documented 074@Target(PARAMETER) 075@Retention(RUNTIME) 076@Inherited 077public @interface Part { 078 079 /** 080 * The part (form-field) name. 081 * 082 * <p> 083 * When blank, falls back to {@link #value()}, then to the reflected parameter name (requires the 084 * <c>-parameters</c> compiler flag). 085 * 086 * @return The annotation value. 087 */ 088 String name() default ""; 089 090 /** 091 * A synonym for {@link #name()}. 092 * 093 * <p> 094 * Allows shortened notation when only the part name is specified: <c><ja>@Part</ja>(<js>"title"</js>)</c>. 095 * 096 * @return The annotation value. 097 */ 098 String value() default ""; 099 100 /** 101 * The filename advertised in the part's {@code Content-Disposition} header. 102 * 103 * <p> 104 * When blank, no {@code filename} is emitted — except for a {@link java.io.File} argument, whose filename 105 * defaults to {@link java.io.File#getName()}. 106 * 107 * @return The annotation value. 108 */ 109 String fileName() default ""; 110 111 /** 112 * The per-part {@code Content-Type} (e.g. {@code "application/pdf"}, {@code "application/json"}). 113 * 114 * <p> 115 * When blank, a sensible default is used based on the argument type (e.g. {@code text/plain; charset=UTF-8} for 116 * text fields, the serializer's media type for beans, {@code application/octet-stream} for binary sources). 117 * 118 * @return The annotation value. 119 */ 120 String contentType() default ""; 121}