`
ajax
  • 浏览: 251827 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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

    博客分类:
  • REST
阅读更多

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

 

 

 

 

分享到:
评论
5 楼 liu.da101 2012-04-27  
出现中文乱码怎么办呀?
4 楼 junjieshow 2010-05-07  
mailApplication.properties这个文件里存是什么?
3 楼 xiantiaolang 2010-04-12  
我用的spring2.5,customersResource bean是要注入freemarkerConfig才行
2 楼 ajax 2009-08-10  
nocohol 写道
在学习这章的时候,有个地方要注意一下下,作者没有写上去,就是在Spring context configuration, 定义了一个freemarker configure的bean
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">  
    <property name="templateLoaderPath" value="/WEB-INF/view/"/>  
</bean>

我们还应该将其mapping到customersResource bean的freemarkerConfig属性,要不然在调 getHTMLTemplateRepresentation(String templateName,
Map<String, Object> dataModel) 时会发现freemarkerConfig注入不成功!


Spring貌似从2.0以后,就支持自动注入了,默认是byName,当让还有byType等。不需要显式的配置一个bean为另外一个Bean的属性。
1 楼 nocohol 2009-08-10  
在学习这章的时候,有个地方要注意一下下,作者没有写上去,就是在Spring context configuration, 定义了一个freemarker configure的bean
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">  
    <property name="templateLoaderPath" value="/WEB-INF/view/"/>  
</bean>

我们还应该将其mapping到customersResource bean的freemarkerConfig属性,要不然在调 getHTMLTemplateRepresentation(String templateName,
Map<String, Object> dataModel) 时会发现freemarkerConfig注入不成功!

相关推荐

Global site tag (gtag.js) - Google Analytics