扩展webx资源装载器之HttpResourceLoader(一):简单实现

简介:

webx是一个开源的web框架,主页地址:http://www.openwebx.org/。这里我们主要说下使用http协议对网络中任意资源进行装载,来增强webx资源装载的功能。

用webx官网的mvn命令,生成tutorial1项目,里面webx的pom如下:

1

2

3

4

5

6

7

8

...

<webx-version>3.2.4</webx-version>

...

<dependency>

<groupId>com.alibaba.citrus</groupId>

<artifactId>citrus-webx-all</artifactId>

</dependency>

...

这个版本里,webx的resourceLoader有2种扩展:

[res-loaders:webapp-loader /]:通过servletContext.getResource(resourceName)来获取资源。
[res-loaders:classpath-loader /]:通过classLoader.getResource(resourceName)来获取资源。
[res-loaders:super-loader/]:通过resource.xml里配置的资源别名,结合配置的资源加载器,来进行资源加载。这种是在前面2种的基础之上。

基于springExt,这里扩展点是res-loaders,捐献是webapp-loader,classpath-loader和super-loader。

新增一个http-loader,即[res-loaders:http-loader/],具体的捐献实现和配置在后面会再进行介绍,。

HttpResourceLoader简单类实现:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

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();

}

}

}

remoteResourceHost:资源所在的地方,例如,vm目录放在本地,nginx指向vm目录,nginx作为文件服务器提供文件资源服务。
httpUtils是一个http工具类。

这样一个扩展好处就是,服务器部署某个应用后,配置vm目录指向本地,如果需要修改vm看效果,不用重启应用,不用登录服务器修改vm文件,不用本地文件改了再传到服务器,只用在本地修改即可。用于开发阶段。


相关文章
|
20天前
|
数据库
优化数据加载策略:深入探讨Entity Framework Core中的懒加载与显式加载技术及其适用场景
【8月更文挑战第31天】在 Entity Framework Core(EF Core)中,数据加载策略直接影响应用性能。本文将介绍懒加载(Lazy Loading)和显式加载(Eager Loading)的概念及适用场景。懒加载在访问导航属性时才加载关联实体,可优化性能,但可能引发多次数据库查询;显式加载则一次性加载所有关联实体,减少查询次数但增加单次查询的数据量。了解这些策略有助于开发高性能应用。
27 0
|
20天前
|
设计模式 安全 数据库连接
|
10月前
|
存储 Java Spring
Spring框架中的Resource接口是什么,以及它在加载和访问资源时的关键作用
使用 Resource 加载资源 要使用 Resource 接口加载资源,首先需要获取一个 ResourceLoader 实例,通常可以通过依赖注入来获得。接下来,您可以使用 ResourceLoader 来获取 Resource 对象,然后使用它来访问资源的内容。
100 0
.NET Core反射获取带有自定义特性的类,通过依赖注入根据Attribute元数据信息调用对应的方法
.NET Core反射获取带有自定义特性的类,通过依赖注入根据Attribute元数据信息调用对应的方法
156 0
|
Java 中间件 Maven
如何实现Java类隔离加载?
Java 开发中,如果不同的 jar 包依赖了某些通用 jar 包的版本不一样,运行时就会因为加载的类跟预期不符合导致报错。如何避免这种情况呢?本文通过分析 jar 包产生冲突的原因及类隔离的实现原理,分享两种实现自定义类加载器的方法。
如何实现Java类隔离加载?
|
存储 缓存 前端开发
Yii2.0的AssetBundle类一共有哪些方法?可以实现哪些功能?底层原理是什么?
Yii2.0的AssetBundle类一共有哪些方法?可以实现哪些功能?底层原理是什么?
111 0
|
PHP 数据库
Yii2.0框架一共有哪些异常类?底层原理是什么?
Yii2.0框架一共有哪些异常类?底层原理是什么?
128 0
|
SQL PHP 数据库
Yii2.0框架中的Active Record和数据访问对象(DAO)有什么区别?在实际开发中该如何选择?
Yii2.0框架中的Active Record和数据访问对象(DAO)有什么区别?在实际开发中该如何选择?
|
缓存
读源码长知识 | 动态扩展类并绑定生命周期的新方式
在阅读viewModelScope源码时,发现了一种新的方式。 协程需隶属于某 CoroutineScope ,以实现structured-concurrency,而 CoroutineScope 应
164 0
|
存储 缓存 NoSQL
AOP实现上下文存储 --- 系统框架搭建(三)
AOP实现上下文存储 --- 系统框架搭建(三)