import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Set; import javax.servlet.ServletContext; import org.apache.commons.lang.StringUtils; import org.apache.velocity.runtime.RuntimeConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.web.context.ServletContextAware; import org.springframework.web.context.WebApplicationContext; import com.alibaba.citrus.service.resource.Resource; import com.alibaba.citrus.service.resource.ResourceLoader; import com.alibaba.citrus.service.resource.ResourceLoaderContext; import com.alibaba.citrus.service.resource.ResourceLoadingOption; import com.alibaba.citrus.service.resource.ResourceLoadingService; import com.alibaba.citrus.service.resource.support.InputStreamResource; import com.alibaba.citrus.service.template.TemplateService; import com.alibaba.citrus.service.velocity.impl.VelocityEngineImpl; import com.alibaba.citrus.service.velocity.impl.VelocityRuntimeInstance; import static org.springframework.web.context.WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE; /** * * @author yankai913@gmail.com * @date 2016年4月11日 */ public class HttpResourceLoader implements ResourceLoader, ServletContextAware, ApplicationListener<ContextRefreshedEvent> { private static final Logger logger = LoggerFactory.getLogger(HttpResourceLoader. class ); String resourceRemoteHost = "http://localhost:6666" ; String vmEncoding = "UTF-8" ; String[] additionalPathArr = new String[] { "" , "/common" }; ApplicationContext applicationContext; ServletContext servletContext; @Override public void init(ResourceLoadingService resourceLoadingService) { } @Override public Resource getResource(ResourceLoaderContext context, Set<ResourceLoadingOption> options) { String resourceName = context.getResourceName(); try { for (String additionalPath : additionalPathArr) { String remoteFileURL = this .resourceRemoteHost + additionalPath + resourceName; HttpUtils.HttpResult httpRequest = HttpUtils.httpGet(remoteFileURL, null , null , vmEncoding, 3000 ); if (httpRequest.code == HttpURLConnection.HTTP_OK) { String htmlText = httpRequest.content; wrapHtmlContent(resourceName, htmlText); ByteArrayInputStream bais = new ByteArrayInputStream(htmlText.getBytes(vmEncoding)); InputStreamResource resource = new PrototypeInputStreamResource(bais); return resource; } else { continue ; } } throw new IOException( "http get template failed! resourceName=" + resourceName); } catch (Exception e) { logger.error( "http get template failed! resourceName=" + resourceName + e.getMessage(), e); } return null ; } void wrapHtmlContent(String resourceName, String htmlText) { SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ); String timestamp = sdf.format( new Date()); String content = "<!-- http get " + resourceName + "\t" + timestamp + " start -->\n" ; content = content + htmlText; content = "\n<!-- http get " + resourceName + "\t" + timestamp + " end -->\n" ; } @Override public void setServletContext(ServletContext servletContext) { this .servletContext = servletContext; } @Override public void onApplicationEvent(ContextRefreshedEvent event) { if (event.getApplicationContext().getParent() == null ) { WebApplicationContext wac = (WebApplicationContext) servletContext .getAttribute(ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); TemplateService ts = (TemplateService) wac.getBean( "templateService" ); VelocityEngineImpl ve = (VelocityEngineImpl) ts.getTemplateEngine( "vm" ); VelocityRuntimeInstance vri = (VelocityRuntimeInstance) ve.getRuntimeServices(); vmEncoding = StringUtils.trimToNull((String) vri.getProperty(RuntimeConstants.INPUT_ENCODING)); } } static class PrototypeInputStreamResource extends InputStreamResource { public PrototypeInputStreamResource(InputStream stream) { super (stream); } public long lastModified() { return System.currentTimeMillis(); } } } |