欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Restlet实战(十五)如何与表示层交互

程序员文章站 2022-07-03 20:53:24
...

首先还是设定一个应用场景,看看用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>