扩展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文件,不用本地文件改了再传到服务器,只用在本地修改即可。用于开发阶段。


相关文章
|
4月前
|
缓存 安全 Java
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
从底层源码入手,通过代码示例,追踪AnnotationConfigApplicationContext加载配置类、启动Spring容器的整个流程,并对IOC、BeanDefinition、PostProcesser等相关概念进行解释
366 24
|
2月前
类的实例化过程在ES6中是如何优化的?
类的实例化过程在ES6中是如何优化的?
|
3月前
|
XML 存储 前端开发
手动开发-实现SpringMVC底层机制--小试牛刀
手动开发-实现SpringMVC底层机制--小试牛刀
26 0
|
5月前
|
设计模式 安全 数据库连接
|
6月前
|
开发框架 前端开发 JavaScript
在各种开发项目中使用公用类库的扩展方法,通过上下文方式快速调用处理函数
在各种开发项目中使用公用类库的扩展方法,通过上下文方式快速调用处理函数
|
8月前
|
存储 监控 安全
JVM工作原理与实战(五):类的生命周期-加载阶段
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了类的生命周期、类的加载阶段等内容。
90 5
|
8月前
|
监控 Java
动态代理为什么能称之为动态
动态代理为什么能称之为动态
31 0
|
前端开发 Java 程序员
struts2封装好的三种收参方式,零散、对象、集合。
struts2封装好的三种收参方式,零散、对象、集合。
111 0
struts2封装好的三种收参方式,零散、对象、集合。
|
存储 缓存 前端开发
Yii2.0的AssetBundle类一共有哪些方法?可以实现哪些功能?底层原理是什么?
Yii2.0的AssetBundle类一共有哪些方法?可以实现哪些功能?底层原理是什么?
134 0
|
缓存
读源码长知识 | 动态扩展类并绑定生命周期的新方式
在阅读viewModelScope源码时,发现了一种新的方式。 协程需隶属于某 CoroutineScope ,以实现structured-concurrency,而 CoroutineScope 应
180 0