有些时候,你想保存数据。XWiki平台可以根据你的需要提供不同的存储地方。下面是你所有的选择。
临时存储
执行上下文
如果要保存的数据只要保存一个请求的持续时间(即一个XWiki URL的调用),那么你应该在Execution Context声明一个属性。
例如,在一个组件(Java):
import org.xwiki.execution.*;
@Inject Execution execution;
...
// Declaring
ExecutionContext ec = execution.getContext();
ec.newProperty("mykey").initial(initialValue).declare();
...
// Updating
ec.setProperty("mykey", newValue);
...
// Retrieving
Object myvalue = e.getProperty("mykey");
执行上下文属性声明
该声明是目前可选的,属性在第一次设置时为隐式声明。该声明可以在ExecutionContextInitializer组件中进行。所有这些组件的初始化方法在classpath中可用和在一个components.txt文件指定,当执行上下文在请求中第一次初始化被调用。
import org.xwiki.context.ExecutionContext;
import org.xwiki.context.ExecutionContextInitializer;
import org.xwiki.context.ExecutionContextException;
import org.xwiki.component.annotation.Component;
@Component
public class DeclareMyPropertyExecutionContextInitializer implements ExecutionContextInitializer
{
@Override
public void initialize(ExecutionContext executionContext)
{
if (!executionContext.hasProperty("mykey")) {
executionContext.newProperty("mykey").type(String.class).nonNull().initial("").declare();
}
}
}
在上面的例子中可以看到,当被声明时,可以在属性来设置不同的attribute。下表显示了当前支持的attribute列表。
在一个请求周期,一些组件可以通过push到执行上下文堆栈来激活一个clean或cloned执行上下文。你可以通过设置attribute来控制如何在这些情况下管理你的属性。
Attribute | 参数 | 描述 |
---|---|---|
cloneValue() | - | 表明你希望value被cloned,当执行上下文cloned或你的属性是从父执行上下文继承 |
makeFinal() | - | 表明如果有人试图替换初始值对象应当抛出异常 |
inherited() | - | 表明属性应该由在当前请求中push出的任何新的执行上下文中继承 |
nonNull() | - | 表明如果属性值设置为null,应当抛出异常 |
type(Class<?> type) | type class的值对象应针对类型检查 | 当更新值对象,设置一个type来执行类型检查 |
Wiki页面访问执行上下文
目前,我们无法从wiki页面方便地访问执行上下文,但是这有待改进。目前在Velocity不支持,但在Groovy是可以。
从wiki页面:
{{groovy}}
import org.xwiki.context.*
def ec = services.component.getInstance(Execution.class).getContext()
ec.setProperty("mykey", myvalue)
{{/groovy}}
从wiki页面,可以很容易使用旧的XWiki Context(在未来,它应该完全会被执行上下文所取代)。
例如:
{{velocity}}
$xcontext.put("mykey", value)
{{/velocity}}
也可以将数据保存在HTTP Request,即使建议是使用执行上下文(因为执行上下文独立于执行环境,无论是工作在:Servlets, Portlets, JavaSE等)。
例如在wiki页面通过Velocity:
{{velocity}}
$request.setAttribute("mykey", value)
{{/velocity}}
Servlet Session
如果数据应持续更长一点(即例如跨度超过一个request) 你可以将其保存在Servlet会话(注意在这种情况下,你的代码将只在一个Servlet环境中工作)。
例如,在Java组件:
import org.xwiki.container.*;
@Inject Container container;
...
Request request = container.getRequest();
// Note that this is a bit of a hack and the notion of Session exists in the Container class (getSession()) but the Session interface is empty at the moment, making it useless)
if (request instanceof ServletRequest) {
HttpServletRequest servletRequest = (ServletRequest) request;
HttpSession session = servletRequest.getSession();
session.setAttribute("mykey", myvalue);
}
例如在wiki页面:
{{velocity}}
$request.getSession().setAttribute("mykey", myvalue)
{{/velocity}}
临时目录
如果数据应该持续的时间甚至比会话的时间更长,你可以将其保存在环境中临时目录中的一个文件。
例如,在Java组件:
import org.xwiki.environment.*;
import org.apache.commons.io.*;
@Inject Environment environment;
...
File tmpDir = environment.getTemporaryDirectory();
FileUtils.write(tmpDir, "something");
Servlet Context
如果数据持续时间与Web应用程序一致,你可以使用servlet上下文。这不容易访问,但也是可能的(注意在这种情况下,你的代码将只在一个Servlet环境中工作)。
例如,在Java组件:
import org.xwiki.container.*;
import com.xpn.xwiki.*;
import com.xpn.xwiki.web.*;
@Inject Execution execution;
...
// Get the older XWiki Context
XWikiContext xc = (XWikiContext) execution.getContext().getProperty("xwikicontext");
XWikiEngineContext ec = xc.getEngineContext();
ec.setAttribute("mykey", myvalue);
永久保存
Wiki Model
最佳数据保存地点一般在wiki本身(查看数据模型和API指南了解更多例子)。有几个地方,你可以存储数据:
- 在文档内容中
- 在一个文档的XObject对象
- 在附件中
永久目录
另一种可能性是使用环境的永久目录。
例如,在Java组件:
import org.xwiki.environment.*;
import org.apache.commons.io.*;
@Inject Environment environment;
...
File permDir = environment.getPermanentDirectory();
FileUtils.write(permDir, "something");