|
16 | 16 |
|
17 | 17 | import org.httprpc.beans.BeanAdapter; |
18 | 18 | import org.httprpc.io.JSONDecoder; |
| 19 | +import org.httprpc.io.JSONEncoder; |
19 | 20 |
|
20 | 21 | import java.io.IOException; |
21 | 22 | import java.io.InputStream; |
|
34 | 35 | import java.util.Collections; |
35 | 36 | import java.util.Date; |
36 | 37 | import java.util.HashMap; |
| 38 | +import java.util.LinkedHashMap; |
37 | 39 | import java.util.List; |
38 | 40 | import java.util.Locale; |
39 | 41 | import java.util.Map; |
@@ -113,6 +115,9 @@ private static class TypedInvocationHandler implements InvocationHandler { |
113 | 115 | BiFunction<String, URL, WebServiceProxy> factory; |
114 | 116 |
|
115 | 117 | Map<String, ?> keys = Collections.emptyMap(); |
| 118 | + Map<String, ?> headers = Collections.emptyMap(); |
| 119 | + |
| 120 | + Object body = null; |
116 | 121 |
|
117 | 122 | TypedInvocationHandler(URL baseURL, Class<?> type, BiFunction<String, URL, WebServiceProxy> factory) { |
118 | 123 | this.baseURL = baseURL; |
@@ -170,18 +175,20 @@ public Object invoke(Object proxy, Method method, Object[] arguments) throws Thr |
170 | 175 |
|
171 | 176 | WebServiceProxy webServiceProxy = factory.apply(requestMethod.value(), url); |
172 | 177 |
|
| 178 | + webServiceProxy.setHeaders(headers); |
| 179 | + |
173 | 180 | Parameter[] parameters = method.getParameters(); |
174 | 181 |
|
175 | | - Map<String, Object> argumentMap = new HashMap<>(); |
| 182 | + Map<String, Object> argumentMap = new LinkedHashMap<>(); |
176 | 183 |
|
177 | 184 | for (int i = 0; i < parameters.length; i++) { |
178 | | - Parameter parameter = parameters[i]; |
179 | | - |
180 | | - argumentMap.put(parameter.getName(), arguments[i]); |
| 185 | + argumentMap.put(parameters[i].getName(), arguments[i]); |
181 | 186 | } |
182 | 187 |
|
183 | 188 | webServiceProxy.setArguments(argumentMap); |
184 | 189 |
|
| 190 | + webServiceProxy.setBody(body); |
| 191 | + |
185 | 192 | return BeanAdapter.adapt(webServiceProxy.invoke(), method.getGenericReturnType()); |
186 | 193 | } |
187 | 194 | } |
@@ -218,6 +225,8 @@ public String toString() { |
218 | 225 | private Map<String, ?> headers = emptyMap(); |
219 | 226 | private Map<String, ?> arguments = emptyMap(); |
220 | 227 |
|
| 228 | + private Object body; |
| 229 | + |
221 | 230 | private RequestHandler requestHandler = null; |
222 | 231 |
|
223 | 232 | private int connectTimeout = 0; |
@@ -343,6 +352,26 @@ public void setArguments(Map<String, ?> arguments) { |
343 | 352 | this.arguments = arguments; |
344 | 353 | } |
345 | 354 |
|
| 355 | + /** |
| 356 | + * Returns the request body. |
| 357 | + * |
| 358 | + * @return |
| 359 | + * A value representing the request body, or <code>null</code> for no body. |
| 360 | + */ |
| 361 | + public Object getBody() { |
| 362 | + return body; |
| 363 | + } |
| 364 | + |
| 365 | + /** |
| 366 | + * Returns the request body. |
| 367 | + * |
| 368 | + * @param body |
| 369 | + * A value representing the request body, or <code>null</code> if no body has been set. |
| 370 | + */ |
| 371 | + public void setBody(Object body) { |
| 372 | + this.body = body; |
| 373 | + } |
| 374 | + |
346 | 375 | /** |
347 | 376 | * Returns the request handler. |
348 | 377 | * |
@@ -441,7 +470,23 @@ public <T> T invoke() throws IOException { |
441 | 470 | public <T> T invoke(ResponseHandler<T> responseHandler) throws IOException { |
442 | 471 | URL url; |
443 | 472 | RequestHandler requestHandler; |
444 | | - if (method.equalsIgnoreCase("POST") && this.requestHandler == null) { |
| 473 | + if (body != null && this.requestHandler == null) { |
| 474 | + url = this.url; |
| 475 | + |
| 476 | + requestHandler = new RequestHandler() { |
| 477 | + @Override |
| 478 | + public String getContentType() { |
| 479 | + return "application/json"; |
| 480 | + } |
| 481 | + |
| 482 | + @Override |
| 483 | + public void encodeRequest(OutputStream outputStream) throws IOException { |
| 484 | + JSONEncoder jsonEncoder = new JSONEncoder(); |
| 485 | + |
| 486 | + jsonEncoder.write(body, outputStream); |
| 487 | + } |
| 488 | + }; |
| 489 | + } else if (method.equalsIgnoreCase("POST") && this.requestHandler == null) { |
445 | 490 | url = this.url; |
446 | 491 |
|
447 | 492 | requestHandler = new RequestHandler() { |
@@ -713,37 +758,13 @@ private static Object getParameterValue(Object argument) { |
713 | 758 | * An instance of the given type that adapts the target service. |
714 | 759 | */ |
715 | 760 | public static <T> T adapt(URL baseURL, Class<T> type) { |
716 | | - return adapt(baseURL, type, emptyMap()); |
717 | | - } |
718 | | - |
719 | | - /** |
720 | | - * Creates a type-safe web service proxy adapter. |
721 | | - * |
722 | | - * @param <T> |
723 | | - * The target type. |
724 | | - * |
725 | | - * @param baseURL |
726 | | - * The base URL of the web service. |
727 | | - * |
728 | | - * @param type |
729 | | - * The type of the adapter. |
730 | | - * |
731 | | - * @param headers |
732 | | - * A map of header values that will be submitted with service requests. |
733 | | - * |
734 | | - * @return |
735 | | - * An instance of the given type that adapts the target service. |
736 | | - */ |
737 | | - public static <T> T adapt(URL baseURL, Class<T> type, Map<String, ?> headers) { |
738 | 761 | return adapt(baseURL, type, (method, url) -> { |
739 | 762 | WebServiceProxy webServiceProxy = new WebServiceProxy(method, url); |
740 | 763 |
|
741 | 764 | if (method.equalsIgnoreCase("POST")) { |
742 | 765 | webServiceProxy.setEncoding(Encoding.MULTIPART_FORM_DATA); |
743 | 766 | } |
744 | 767 |
|
745 | | - webServiceProxy.setHeaders(headers); |
746 | | - |
747 | 768 | return webServiceProxy; |
748 | 769 | }); |
749 | 770 | } |
@@ -814,6 +835,65 @@ public static void setKeys(Object adapter, Map<String, ?> keys) { |
814 | 835 | getTypedInvocationHandler(adapter).keys = keys; |
815 | 836 | } |
816 | 837 |
|
| 838 | + /** |
| 839 | + * Returns the keys associated with an adapter instance. |
| 840 | + * |
| 841 | + * @param adapter |
| 842 | + * The adapter instance. |
| 843 | + * |
| 844 | + * @return |
| 845 | + * The keys associated with the adapter instance. |
| 846 | + */ |
| 847 | + public static Map<String, ?> getHeaders(Object adapter) { |
| 848 | + return getTypedInvocationHandler(adapter).keys; |
| 849 | + } |
| 850 | + |
| 851 | + /** |
| 852 | + * Sets the keys associated with an adapter instance. |
| 853 | + * |
| 854 | + * @param adapter |
| 855 | + * The adapter instance. |
| 856 | + * |
| 857 | + * @param headers |
| 858 | + * The keys to associate with the adapter instance. |
| 859 | + */ |
| 860 | + public static void setHeaders(Object adapter, Map<String, ?> headers) { |
| 861 | + if (headers == null) { |
| 862 | + throw new IllegalArgumentException(); |
| 863 | + } |
| 864 | + |
| 865 | + getTypedInvocationHandler(adapter).headers = headers; |
| 866 | + } |
| 867 | + |
| 868 | + /** |
| 869 | + * Returns the request body associated with an adapter instance. |
| 870 | + * |
| 871 | + * @param adapter |
| 872 | + * The adapter instance. |
| 873 | + * |
| 874 | + * @return |
| 875 | + * The request body associated with the adapter instance, or <code>null</code> |
| 876 | + * if no request body has been set. |
| 877 | + */ |
| 878 | + @SuppressWarnings("unchecked") |
| 879 | + public static <T> T getBody(Object adapter) { |
| 880 | + return (T)getTypedInvocationHandler(adapter).body; |
| 881 | + } |
| 882 | + |
| 883 | + /** |
| 884 | + * Sets the request body associated with an adapter instance. |
| 885 | + * |
| 886 | + * @param adapter |
| 887 | + * The adapter instance. |
| 888 | + * |
| 889 | + * @param body |
| 890 | + * The request body to associate with the adapter instance, or <code>null</code> |
| 891 | + * for no request body. |
| 892 | + */ |
| 893 | + public static void setBody(Object adapter, Object body) { |
| 894 | + getTypedInvocationHandler(adapter).body = body; |
| 895 | + } |
| 896 | + |
817 | 897 | private static TypedInvocationHandler getTypedInvocationHandler(Object adapter) { |
818 | 898 | if (!(adapter instanceof Proxy)) { |
819 | 899 | throw new IllegalArgumentException(); |
|
0 commit comments