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


上一篇:cassandra入门(一):jdbc连接cassandra作增删改查


下一篇:RocketMQ学习(六):消息的生命周期上之消息的产生