restTemplate重定向问题 cookie问题
最近在做一個轉(zhuǎn)發(fā)功能,zuul + ribbon + resttemplate 進行路由、負(fù)載、轉(zhuǎn)發(fā)的功能
基本準(zhǔn)備就緒,在微信自動登陸那遇到了一個坑,ribbon?系統(tǒng)用resttemplate?轉(zhuǎn)發(fā)A系統(tǒng)的資源,在微信自動登陸的地方,A系統(tǒng)重定向到微信的地址,類似下面的代碼
redirect:https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx3290f3d5****&redirect_uri=http://***.com/weixin/wxAuthRedirect?redirectUrl=http%3A%2F%2F192.168.10.116%3A8081%2Finternal%2Fpage%2Fuser%2Flogin_wx&response_type=code&scope=snsapi_userinfo&state=state#wechat_redirect
結(jié)果resttemplate 自動重定向到本地的地址,如下所示:
http://192.168.10.116:**/connect/oauth2/authorize**仔細(xì)思考了下,大概就是resttemplate 的重定向問題,查了查資料,找到一個類HttpComponentsClientHttpRequestFactory,RestTemplate初始化提供了這個類的參數(shù)
/*** Create a new instance of the {@link RestTemplate} based on the given {@link ClientHttpRequestFactory}.* @param requestFactory HTTP request factory to use* @see org.springframework.http.client.SimpleClientHttpRequestFactory* @see org.springframework.http.client.HttpComponentsClientHttpRequestFactory*/public RestTemplate(ClientHttpRequestFactory requestFactory) {this();setRequestFactory(requestFactory);}HttpComponentsClientHttpRequestFactory繼承自ClientHttpRequestFactory,這個類的子類有HttpComponentsClientHttpRequestFactory和SimpleClientHttpRequestFactory
找到SimpleClientHttpRequestFactory,有如下方法:
第一種方式:
/*** Template method for preparing the given {@link HttpURLConnection}.* <p>The default implementation prepares the connection for input and output, and sets the HTTP method.* @param connection the connection to prepare* @param httpMethod the HTTP request method ({@code GET}, {@code POST}, etc.)* @throws IOException in case of I/O errors*/protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {if (this.connectTimeout >= 0) {connection.setConnectTimeout(this.connectTimeout);}if (this.readTimeout >= 0) {connection.setReadTimeout(this.readTimeout);}connection.setDoInput(true);if ("GET".equals(httpMethod)) {connection.setInstanceFollowRedirects(true);}else {connection.setInstanceFollowRedirects(false);}if ("POST".equals(httpMethod) || "PUT".equals(httpMethod) ||"PATCH".equals(httpMethod) || "DELETE".equals(httpMethod)) {connection.setDoOutput(true);}else {connection.setDoOutput(false);}connection.setRequestMethod(httpMethod);}可以看到setInstanceFollowRedirects,get請求是可以重定向的,其他方法禁止了重定向,于是建個SimpleClientHttpRequestFactory的子類,禁用重定向。
于是乎 NoRedirectClientHttpRequestFactory.java
import java.io.IOException; import java.net.HttpURLConnection;import org.springframework.http.client.SimpleClientHttpRequestFactory;public class NoRedirectClientHttpRequestFactory extends SimpleClientHttpRequestFactory {@Overrideprotected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {// TODO Auto-generated method stubsuper.prepareConnection(connection, httpMethod);// 禁止自動重定向connection.setFollowRedirects(false);} } NoRedirectClientHttpRequestFactory httpRequestFactory = new NoRedirectClientHttpRequestFactory(); RestTemplate restTemplate = new RestTemplate(httpRequestFactory);接著,似乎更換ClientHttpRequestFactory并不合心意,還是要使用HttpComponentsClientHttpRequestFactory來實現(xiàn),HttpComponentsClientHttpRequestFactory是可以自定義HttpClient的,于是查到了HttpClient頭上,HttpClient是可以設(shè)置Redirect的,
第二種方式:
HttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build(); httpRequestFactory.setHttpClient(httpClient); RestTemplate restTemplate = new RestTemplate(httpRequestFactory);默認(rèn)提供了兩個類,DefaultRedirectStrategy和LaxRedirectStrategy,LaxRedirectStrategy繼承自DefaultRedirectStrategy
DefaultRedirectStrategy.java
/*** Redirectable methods.*/private static final String[] REDIRECT_METHODS = new String[] {HttpGet.METHOD_NAME,HttpHead.METHOD_NAME};LaxRedirectStrategy.java
/** ====================================================================* Licensed to the Apache Software Foundation (ASF) under one* or more contributor license agreements. See the NOTICE file* distributed with this work for additional information* regarding copyright ownership. The ASF licenses this file* to you 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** http://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.* ====================================================================** This software consists of voluntary contributions made by many* individuals on behalf of the Apache Software Foundation. For more* information on the Apache Software Foundation, please see* <http://www.apache.org/>.**/package org.apache.http.impl.client;import org.apache.http.annotation.Contract; import org.apache.http.annotation.ThreadingBehavior; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpHead; import org.apache.http.client.methods.HttpPost;/*** Lax {@link org.apache.http.client.RedirectStrategy} implementation* that automatically redirects all HEAD, GET, POST, and DELETE requests.* This strategy relaxes restrictions on automatic redirection of* POST methods imposed by the HTTP specification.** @since 4.2*/ @Contract(threading = ThreadingBehavior.IMMUTABLE) public class LaxRedirectStrategy extends DefaultRedirectStrategy {public static final LaxRedirectStrategy INSTANCE = new LaxRedirectStrategy();/*** Redirectable methods.*/private static final String[] REDIRECT_METHODS = new String[] {HttpGet.METHOD_NAME,HttpPost.METHOD_NAME,HttpHead.METHOD_NAME,HttpDelete.METHOD_NAME};@Overrideprotected boolean isRedirectable(final String method) {for (final String m: REDIRECT_METHODS) {if (m.equalsIgnoreCase(method)) {return true;}}return false;}}這就很清晰了,copy一份LaxRedirectStrategy的代碼,改寫掉REDIRECT_METHODS中的定義方法,如下:
import org.apache.http.annotation.Contract; import org.apache.http.annotation.ThreadingBehavior; import org.apache.http.impl.client.DefaultRedirectStrategy;/*** * @ClassName: MyRedirectStrategy * @Description: TODO * @author thinklight * @date 2018年4月20日 下午2:47:29 **/ @Contract(threading = ThreadingBehavior.IMMUTABLE) public class MyRedirectStrategy extends DefaultRedirectStrategy {public static final MyRedirectStrategy INSTANCE = new MyRedirectStrategy();/*** Redirectable methods.*/private static final String[] REDIRECT_METHODS = new String[] {};@Overrideprotected boolean isRedirectable(final String method) {for (final String m: REDIRECT_METHODS) {if (m.equalsIgnoreCase(method)) {return true;}}return false;} }ribbon+微信各種重定向問題,解決了。
第三種方式:
自己蠢了,今天因為cookie的問題發(fā)現(xiàn)了簡單的方式
HttpClient httpClient = HttpClientBuilder.create().disableCookieManagement().disableRedirectHandling().build();完整代碼如下:
@AutowiredRestTemplate restTemplate;@Bean@LoadBalancedRestTemplate restTemplate() {HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(); // NoRedirectClientHttpRequestFactory httpRequestFactory = new NoRedirectClientHttpRequestFactory();// 此類型不能使用httpClienthttpRequestFactory.setConnectionRequestTimeout(2000);httpRequestFactory.setConnectTimeout(10000);httpRequestFactory.setReadTimeout(7200000);// HttpClient httpClient = HttpClientBuilder.create()// .setRedirectStrategy(new MyRedirectStrategy())// .build();HttpClient httpClient = HttpClientBuilder.create().disableCookieManagement().disableRedirectHandling().build();httpRequestFactory.setHttpClient(httpClient);RestTemplate restTemplate = new RestTemplate(httpRequestFactory);logger.debug("指定字符編碼為UTF-8,原編碼為ISO-8859-1");restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));logger.debug("RestTemple默認(rèn)能轉(zhuǎn)換為application/json,轉(zhuǎn)換追加text/plain類型");restTemplate.getMessageConverters().add(new WxMappingJackson2HttpMessageConverter());return restTemplate;}
?
重定向參考:https://www.dozer.cc/2014/05/disable-resttemplate-redirect.html
cookie參考:https://stackoverflow.com/questions/10175649/resttemplate-and-cookie
https://stackoverflow.com/questions/22853321/resttemplate-client-with-cookies
轉(zhuǎn)載于:https://www.cnblogs.com/lossingdawn/p/8891234.html
總結(jié)
以上是生活随笔為你收集整理的restTemplate重定向问题 cookie问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 多线程之整体概括
- 下一篇: Py与Py3的区别之输入input()函