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


相关文章
|
8月前
|
开发框架 前端开发 JavaScript
在各种开发项目中使用公用类库的扩展方法,通过上下文方式快速调用处理函数
在各种开发项目中使用公用类库的扩展方法,通过上下文方式快速调用处理函数
|
10月前
基于若依的ruoyi-nbcio流程管理系统增加读取节点扩展属性的方法
基于若依的ruoyi-nbcio流程管理系统增加读取节点扩展属性的方法
95 0
|
前端开发 Java Spring
浅谈SpringMVC的概念及执行原理
浅谈SpringMVC的概念及执行原理
59 0
|
10月前
|
负载均衡 Java API
|
数据挖掘 Python
4.【.netcore Configuration】理解Configuration中Section弱方式读取和Binder模式的强类型读取代码
4.【.netcore Configuration】理解Configuration中Section弱方式读取和Binder模式的强类型读取代码
141 0
|
前端开发 Java 程序员
struts2封装好的三种收参方式,零散、对象、集合。
struts2封装好的三种收参方式,零散、对象、集合。
116 0
struts2封装好的三种收参方式,零散、对象、集合。
|
XML 缓存 NoSQL
分布式服务器框架之Server.Common中通过Xml配置渠道、服务器集群、热更新信息代码解析Xml缓存进内存
ChannelConfig.cs代码解析加载ChannelConfig.xml。使用了System.Xml.Linq的XDocument工具类来加载xml文件。其基本原理就是获取到Root节点下名为“Channel”的所有Element节点,然后使用迭代器循环,拿到每一个Element中的属性,先缓存ChannelEntity结构中,最后存到字典里。
|
XML 开发框架 前端开发
创建 JavaWeb 应用(静态和动态)| 学习笔记
快速学习创建 JavaWeb 应用(静态和动态),介绍了创建 JavaWeb 应用(静态和动态)系统机制, 以及在实际应用过程中如何使用。
|
存储 缓存 NoSQL
AOP实现上下文存储 --- 系统框架搭建(三)
AOP实现上下文存储 --- 系统框架搭建(三)