Restlet实战(十五)如何与表示层交互
首先还是设定一个应用场景,看看用restlet如何实现。
很多信息系统的某一个功能点的流程通常都是这样,首先进入一个列表页面,点击页面上的新增按钮,则进入新增页面,新增数据成功后,或者回到当前页面或者回到列表页面,这要看具体是怎么要求的。
下面就以Customer为例来模式实现这个流程。
需要说明的是,Restlet是使用Freemarker模板作为页面的展示而不是Jsp。在开始修改资源以及其它代码之前,我们需要费点功夫把FreeMarker集成进去,不是说Restlet已经集成FreeMarker了吗?我们还需要做什么工作?别急,且听我一一道来:
从官方给出的Restlet与Freemarker的结合的例子能看出,要是想在restlet中使用Freemarker,需要以下几步:
Properties properties = getProperties("clap://class/config/mailApplication.properties");
this.webRootPath = properties.getProperty("web.root.path");
final File templateDir = new File(webRootPath + "/tmpl");
Configuration fmc = new freemarker.template.Configuration();
fmc.setDirectoryForTemplateLoading(templateDir);
上述代码是指定FreeMarker模板文件的存放目录等信息,设置完成后,在Restlet里面可以引用:
org.restlet.ext.freemarker.TemplateRepresentation.TemplateRepresentation(String templateName,
Configuration config, Object dataModel, MediaType mediaType)
如果是一个测试程序,直接这样使用没有问题,但是如果真正的铲平开发,这样的代码会出现在产品的各个角落,非常的糟糕。
那么能不能把这段代码封装起来,作为一个公共的代码,至少维护起来方便,下面就借助于Spring来实现这样的封装。
因为Spring的 FreeMarkerConfigurer已经实现了Configuration的获取的操作,所以,我们就借助它来封装代码。这里,把模板文件的目录设定为/WEB-INF/view
则在Spring配置文件里加入:
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"> <property name="templateLoaderPath" value="/WEB-INF/view/"/> </bean>
接着,创建一个BaseResource类,将上述类注入进来,并且创建一些方法来简化使用Freemarker的操作:
public class BaseResource extends Resource {
FreeMarkerConfigurer freemarkerConfig;
public BaseResource(){}
public BaseResource(Context context, Request request, Response response) {
super(context, request, response);
}
/**
* Returns the reference of a resource according to its id and the reference
* of its "parent".
*
* @param parentRef
* parent reference.
* @param childId
* id of this resource
* @return the reference object of the child resource.
*/
protected Reference getChildReference(Reference parentRef, String childId) {
if (parentRef.getIdentifier().endsWith("/")) {
return new Reference(parentRef.getIdentifier() + childId);
} else {
return new Reference(parentRef.getIdentifier() + "/" + childId);
}
}
/**
* Returns a templated representation dedicated to HTML content.
*
* @param templateName
* the name of the template.
* @param dataModel
* the collection of data processed by the template engine.
* @return the representation.
*/
protected Representation getHTMLTemplateRepresentation(String templateName,
Map<String, Object> dataModel) {
// The template representation is based on Freemarker.
return new TemplateRepresentation(templateName, freemarkerConfig
.getConfiguration(), dataModel, MediaType.TEXT_HTML);
}
public FreeMarkerConfigurer getFreemarkerConfig() {
return freemarkerConfig;
}
public void setFreemarkerConfig(FreeMarkerConfigurer freemarkerConfig) {
this.freemarkerConfig = freemarkerConfig;
}
}
ok, 我们接下来考虑第一个功能点,列出所有Customer,对应的请求的URL应该是:http://serverIp:port/context/customers.
由于这个URl对应的资源是CustomersResource,访问的方法是get,所以,我们修改resource类的represent方法:
@Override
public Representation represent(Variant variant) {
List<Customer> customers = customerDAO.getAllCustomers();
setValueForCustomer(customers);
final Map<String, Object> dataModel = new TreeMap<String, Object>();
dataModel.put("customers", customers);
dataModel.put("resourceRef", getRequest().getResourceRef());
dataModel.put("rootRef", getRequest().getRootRef());
return getHTMLTemplateRepresentation("customers.html", dataModel);
}
由于只是模拟操作数据库,所以,硬编码设定一些值:
private void setValueForCustomer(List customers){
Customer customer = new Customer();
customer.setId("1");
customer.setName("Johnson");
customer.setAddress("Shanghai");
customers.add(customer);
customer = new Customer();
customer.setId("2");
customer.setName("Wood");
customer.setAddress("Beijing");
customers.add(customer);
customer = new Customer();
customer.setId("3");
customer.setName("Simon");
customer.setAddress("Guangzhou");
customers.add(customer);
}
从represent方法能看到,封装数据后,最后会转向到customer.html来显示所有查询到的customer。
customer.html
<div style="float: left">
<h4>List of users.</h4>
<table>
<tr>
<th>User</th>
</tr>
<#list customers as customer>
<tr>
<td><a href="">${customer.id} ${customer.name} ${customer.address}</a></td>
</tr>
</#list>
</table>
</div>
上一篇: vue修改滚动条样式
下一篇: css优化滚动条样式