package com.erdaoya.springcloud.comx.source.sourcebase; import com.erdaoya.springcloud.comx.context.Context; import com.erdaoya.springcloud.comx.source.Source; import com.erdaoya.springcloud.comx.source.SourceException; import com.erdaoya.springcloud.comx.utils.config.ConfigException; import com.erdaoya.springcloud.comx.utils.rest.ReservedParameterManager; import com.erdaoya.springcloud.comx.schema.TinyTemplate; import com.erdaoya.springcloud.comx.utils.config.Config; import com.erdaoya.springcloud.comx.utils.rest.RequestMessage; import com.erdaoya.springcloud.comx.utils.rest.Url; import java.io.IOException; import java.util.HashMap; import java.util.Map; /** * Created by xue on 12/23/16. */ abstract public class AbstractRequestBasedSourceBase extends AbstractSourceBase{ public AbstractRequestBasedSourceBase(Config conf) {super(conf);} /** * 针对 requestbase 处理 url 时 将url query 部分 encode * 这个涉及正则,需要再次验证 * @param context * @param sourceOptions * @param reservedVariables * @return Object data * @throws ConfigException * @throws IOException * @throws SourceException */ public Object executeLoading(Context context, Config sourceOptions, HashMap reservedVariables) throws ConfigException, IOException, SourceException{ String method = sourceOptions.str(Source.FIELD_METHOD, RequestMessage.METHOD_GET); Integer timeout = sourceOptions.intvalue(Source.FIELD_TIMEOUT, RequestMessage.DEFAULT_TIMEOUT); RequestMessage currentRequest = context.getRequest(); ReservedParameterManager reservedParameterManager = ReservedParameterManager.fromRequest(currentRequest); //TODO 验证这一步骤是不是已经被render String targetUrl = this.getResourceUrl(context, sourceOptions.rstr(Source.FIELD_URI), reservedVariables, reservedParameterManager.getReservedQueryParams()); context.getLogger().debug("source load remote data, method:"+ method + " targetUrl:" + targetUrl); Map requestData = null; if (method.equals(RequestMessage.METHOD_POST) || method.equals(RequestMessage.METHOD_PUT)) { if (!method.equals(currentRequest.getMethod())) { throw new UnmatchedRequestMethodException("Source loading, method unmatched: Current method is:"+ currentRequest.getMethod()); } requestData = currentRequest.getData(); } try { // Url 生成错误 处理 Url url = new Url(targetUrl); RequestMessage request = new RequestMessage(url, method, requestData, reservedParameterManager.getFilteredReservedHeaders(context), timeout); return this.doRequest(request, context); } catch (SourceException ex) { throw ex; } catch (Exception ex) { // TODO handle exceptions // should not be Exception ex.printStackTrace(); throw new SourceException(ex); } } private String getResourceUrl(Context context, String uri, HashMap reservedVariables, HashMap reservedQueryParams) throws ConfigException{ TinyTemplate tpl = new TinyTemplate(uri); String renderedUri = tpl.render(reservedVariables, context, true); if (isFullUri(renderedUri)) { return renderedUri; } // TODO url form url; renderedUri = this.getUrlPrefix(context) + renderedUri; return renderedUri; } private boolean isFullUri(String renderedUri) { return renderedUri.startsWith("http://") || renderedUri.startsWith("https://"); } abstract Object doRequest(RequestMessage request,Context context) throws SourceException; abstract String getUrlPrefix(Context context) throws ConfigException; }