REST (3) Restlet implements REST

The Restlet project provides a lightweight and comprehensive framework for "mapping between REST concepts and Java classes". It can be used to implement any kind of RESTful system, not just RESTful web services.
Restlet refers to the terms of the REST standard, such as: resource (resource), representation (representation), connector (connector), component (component), media type (media type), language (language), and so on. Restlet adds some specialized classes (such as Application, Filter, Finder, Router, and Route) to simplify the integration of restlets with each other and the mapping of incoming requests to the resources that handle them.

For other Restlet introductions, see: Getting Started with Restlet . This section briefly introduces the integration and client access of restlet2+spring4.

1. For the basic environment
of spring web, see the web project testRest created by Jersey in the previous section.

2. The REST address
is similar to the previous section. Design the rest interface address of the restlet module:
/restlet/teachers GET Get all resources
/restlet/teachers POST Create a new resource, content contains the resource content
/restlet/teacher/{id} GET Get the number The resource with the id
/restlet/teacher/{id} PUT Update the resource with the id, the content contains the resource content
/restlet/teacher/{id} DELETE Delete the resource with the id

3. The restlet library
adds Restlet dependencies to the project pom.xml:
<repositories>
	<repository>
		<id>maven-restlet</id>
		<name>Restlet repository</name>
		<url>https://maven.restlet.com</url>
	</repository>
</repositories>
<properties>
	<restlet.version>2.3.5</restlet.version>
	<fastjson.version>1.2.7</fastjson.version>
</properties>
<dependencies>	
	...
	<!-- restlet begin -->
	<dependency>
		<groupId>org.restlet.jee</groupId>
		<artifactId>org.restlet</artifactId>
		<version>${restlet.version}</version>
	</dependency>
	<dependency>
		<groupId>org.restlet.jee</groupId>
		<artifactId>org.restlet.ext.json</artifactId>
		<version>${restlet.version}</version>
	</dependency>
	<dependency>
		<groupId>org.restlet.jee</groupId>
		<artifactId>org.restlet.ext.spring</artifactId>
		<version>${restlet.version}</version>
	</dependency>
	<dependency>
		<groupId>org.restlet.jee</groupId>
		<artifactId>org.restlet.ext.servlet</artifactId>
		<version>${restlet.version}</version>
	</dependency>
	<dependency>
		<groupId>org.restlet.jee</groupId>
		<artifactId>org.restlet.ext.xml</artifactId>
		<version>${restlet.version}</version>
	</dependency>
	<dependency>
		<groupId>org.restlet.jee</groupId>
		<artifactId>org.restlet.ext.oauth</artifactId>
		<version>${restlet.version}</version>
	</dependency>
	<!-- json related jar package -->
	<dependency>
		<groupId>com.alibaba</groupId>
		<artifactId>fastjson</artifactId>
		<version>${fastjson.version}</version>
	</dependency>
	<dependency>
		<groupId>com.google.guava</groupId>
		<artifactId>guava</artifactId>
		<version>${guava.version}</version>
	</dependency>
	<!-- restlet end -->
	...

Restlet uses version 2.3.5 and adds servlet, spring, json, xml and other packages. Since the Restlet library is not in the central repository, it needs to be added to the https://maven.restlet.com repository.

4. Servlet
configuration Restlet access entry.
<!-- restlet -->
<servlet>
	<servlet-name>restlet</servlet-name>
	<servlet-class>org.restlet.ext.spring.SpringServerServlet</servlet-class>
	<init-param>
		<param-name>org.restlet.component</param-name>
		<param-value>component</param-value>
	</init-param>
</servlet>
<servlet-mapping>
	<servlet-name>restlet</servlet-name>
	<url-pattern>/restlet/*</url-pattern>
</servlet-mapping>

Restlet Servlet will intercept all accesses under /restlet/*.
After Restlet is integrated with web and spring, there is no need to implement Router, Application, and Component by yourself. But it needs to be configured in spring.
Create a restlet configuration directory config\restlet under the configuration file directory src\main\resources\, and create a configuration file restlet.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
						http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
	default-autowire="byName" default-lazy-init="true">

	<bean id="component" class="org.restlet.ext.spring.SpringComponent">
		<property name="defaultTarget" ref="router" />
	</bean>
	<bean id="router" class="org.restlet.ext.spring.SpringBeanRouter"></bean>

</beans>

The component bean defined here will be referenced by the Restlet servlet configured in web.xml.

5. Implement the api
Add the TeachersResource class in com.sunbin.test.restlet to implement the interface of the /teachers path:
package com.sunbin.test.restlet;

import java.util.HashMap;
import java.util.Map;

import org.restlet.data.Form;
import org.restlet.ext.json.JsonRepresentation;
import org.restlet.representation.Representation;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
import org.restlet.resource.ServerResource;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson.JSON;
import com.sunbin.test.teacher.pojo.Teacher;
import com.sunbin.test.teacher.service.TeacherService;

public class TeachersResource extends ServerResource {

	@Autowired
	private TeacherService teacherService;

	@Get
	public Representation get() {
		System.out.println("Restlet TeachersResource.get");
		Map map = new HashMap();
		map.put("teachers", teacherService.list());
		return new JsonRepresentation(JSON.toJSONString(map));
	}
	
	@Post("*:json")
	public Representation post(Representation entity){
		Map map = new HashMap();
		try {
			Form form = new Form(entity);
			System.out.println("Restlet TeachersResource.post:"+form);
			Teacher teacher = new Teacher();
			teacher.setName(form.getFirstValue("name"));
			teacher.setAge(Integer.parseInt(form.getFirstValue("age")));
			teacherService.save(teacher);
			map.put("status", "y");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace ();
		}
		return new JsonRepresentation(JSON.toJSONString(map));
	}
}

The following Restlet's own annotations are used:
@Get: The response method of the GET request.
@Post("*:json"): The response method of the POST request, specifying that * can accept various Content-Type request data, and json can return Content-Type: application/json data.

It should be noted that the json returned by Restlet returns new JsonRepresentation(map), which will simply call toString on the key value in the Map, and then return the json string. For example: {"teachers":["Teacher [id=1, age=1, name=a]","Teacher [id=2, age=2, name=b]"]}, this is not standard json. So simply use Ali's fastjson library to convert the result into JSONString first, and then return: {"teachers":[{"age":1,"id":1,"name":"a"},{"age": 2,"id":2,"name":"b"}]}.

Add the TeacherResource class to implement the interface of the /teacher/{id} path:
package com.sunbin.test.restlet;


import java.util.HashMap;
import java.util.Map;


import org.restlet.data.Form;
import org.restlet.ext.json.JsonRepresentation;
import org.restlet.representation.Representation;
import org.restlet.resource.Delete;
import org.restlet.resource.Get;
import org.restlet.resource.Put;
import org.restlet.resource.ServerResource;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson.JSON;
import com.sunbin.test.teacher.pojo.Teacher;
import com.sunbin.test.teacher.service.TeacherService;

public class TeacherResource extends ServerResource{

	@Autowired
	private TeacherService teacherService;

	@Get
	public Representation get(){
		String id = (String)getRequest().getAttributes().get("id");
		System.out.println("Restlet TeacherResource.get:"+id);
		Teacher teacher = new Teacher();
		teacher.setId(Integer.parseInt(id));
		Map map = new HashMap();
		map.put("teacher", teacherService.get(teacher));
		return new JsonRepresentation(JSON.toJSONString(map));
	}

	@Put	
	public Representation put(Representation entity){
		Map map = new HashMap();
		try {
			String id = (String)getRequest().getAttributes().get("id");
			Form form = new Form(entity);
			System.out.println("Restlet TeacherResource.put:"+id+":"+form);
			Teacher teacher = new Teacher();
			teacher.setId(Integer.parseInt(id));
			teacher.setName(form.getFirstValue("name"));
			teacher.setAge(Integer.parseInt(form.getFirstValue("age")));
			teacherService.update(teacher);
			map.put("status", "y");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace ();
		}
		return new JsonRepresentation(JSON.toJSONString(map));
	}

	@Delete
	public Representation delete(){
		Map map = new HashMap();
		try {
			String id = (String)getRequest().getAttributes().get("id");
			System.out.println("Restlet TeacherResource.delete:"+id);
			Teacher teacher = new Teacher();
			teacher.setId(Integer.parseInt(id));
			teacherService.remove(teacher);
			map.put("status", "y");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace ();
		}
		return new JsonRepresentation(JSON.toJSONString(map));
	}
}

The same is not used for JAX-RS annotations, but Restlet's own annotations (different case).

The path binding of restlet needs to be configured in the spring file. Add configuration in restlet.xml:
	<bean name="/teacher/{id}" id="teacherResource"
		class="com.sunbin.test.restlet.TeacherResource" scope="prototype">
	</bean>
	<bean name="/teachers" id="teachersResource"
		class="com.sunbin.test.restlet.TeachersResource" scope="prototype">
	</bean>


6.js test
Use the test page src\main\webapp\rest\index.jsp in the previous section to test:
...
	<script type="text/javascript">
		// test framework
		//var restType = "jersey";
		var restType = "restlet";
		//var restType = "resteasy";
		//var restType = "restCxf";
		//var restType = "restMvc";
...

After redeploying, use a browser to visit http://localhost:8080/testRest/rest , the test content is the same as the jersey test.

7.RestletClient test
Restlet provides Client library for testing REST interface.
Create a new TestRestlet class with the following code:
package com.sunbin.test.restlet;

import java.io.IOException;

import org.restlet.resource.ClientResource;
import org.restlet.resource.ResourceException;

public class TestRestlet {

	public static final String URL_BASE = "http://localhost:8080/testRest/restlet/";

	/**
	 * @param args
	 * @throws IOException
	 * @throws ResourceException
	 */
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		String module = "teacher";
		String url = "";
		ClientResource client = null;
		String entity = "";
		String result = "";

		url = URL_BASE + module + "s";
		System.out.println("get\t " + url);
		client = new ClientResource(url);
		result = client.get().getText();
		System.out.println(result);

		url = URL_BASE + module + "s";
		System.out.println("post\t " + url);
		client = new ClientResource(url);
		entity = "name=a&age=1";
		result = client.post(entity).getText();
		System.out.println(result);

		url = URL_BASE + module + "s";
		System.out.println("get\t " + url);
		client = new ClientResource(url);
		result = client.get().getText();
		System.out.println(result);

		url = URL_BASE + module + "/1";
		System.out.println("get\t " + url);
		client = new ClientResource(url);
		result = client.get().getText();
		System.out.println(result);

		url = URL_BASE + module + "/1";
		System.out.println("put\t " + url);
		client = new ClientResource(url);
		entity = "name=aa&age=11";
		result = client.put(entity).getText();
		System.out.println(result);

		url = URL_BASE + module + "s";
		System.out.println("get\t " + url);
		client = new ClientResource(url);
		result = client.get().getText();
		System.out.println(result);

		url = URL_BASE + module + "/1";
		System.out.println("delete\t " + url);
		client = new ClientResource(url);
		result = client.delete().getText();
		System.out.println(result);

		url = URL_BASE + module + "s";
		System.out.println("get\t " + url);
		client = new ClientResource(url);
		result = client.get().getText();
		System.out.println(result);
	}

}

The test results were similar to Jersey.

8. Deploy to jboss If
the Restlet Web project is deployed to jboss, it will fail to start due to the jboss class loading configuration.
You need to modify the module.xml file under the jboss directory /modules/system/layers/base/sun/jdk/main:
<dependencies>
	<system export="true">
		<paths>
			...
			<path name="com/sun/net/httpserver"/>
			...

Add the httpserver configuration line.

9. Restlet accesses session
Restlet does not recommend accessing session information in Resource, because this goes against the stateless design of REST.
But if you need to access Session in Resource, you can get it by the following code:
import org.restlet.Request;
import org.restlet.engine.adapter.HttpRequest;
import org.restlet.engine.adapter.ServerCall;
import org.restlet.ext.servlet.internal.ServletCall;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

...
Request request = getRequest();
if (request instanceof HttpRequest) {
	final ServerCall httpCall = ((HttpRequest) request)
			.getHttpCall();
	if (httpCall instanceof ServletCall) {
		HttpServletRequest httpServletRequest = ((ServletCall) httpCall)
				.getRequest();
		HttpSession session = httpServletRequest.getSession();
...

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326638501&siteId=291194637