Restlet - 基於Spring的Restlet開發例項

襲冷發表於2014-04-01
一、相關說明
    version:文中示例使用的Spring版本為3.0.3,Restlet版本為2.1.0。
    entity:Student

二、建立Java Web工程,新增相關Jar。文中示例工程名為SpringRestlet。
    
    說明:動態代理的cglib-nodep.jar不可缺少。

三、web.xml配置

<servlet>
	<servlet-name>dispatcherServlet</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath*:/applicationContext.xml</param-value>
	</init-param>
</servlet>
<!--Spring ApplicationContext load -->
<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Spring,avoid leaking memory -->
<listener>
	<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<filter>
	<filter-name>encodingFilter</filter-name>
	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
	<init-param>
		<param-name>encoding</param-name>
		<param-value>UTF-8</param-value>
	</init-param>
	<init-param>
		<param-name>forceEncoding</param-name>
		<param-value>true</param-value>
	</init-param>
</filter>
<!-- restlet servlet -->
<servlet>
	<servlet-name>restlet</servlet-name>
	<servlet-class>org.restlet.ext.spring.SpringServerServlet</servlet-class>
	<init-param>
		<param-name>org.restlet.application</param-name>
		<param-value>application</param-value>
	</init-param>
</servlet>
<servlet-mapping>
	<servlet-name>restlet</servlet-name>
	<url-pattern>/*</url-pattern>
</servlet-mapping>
四、Model實體類程式碼

@JsonSerialize(include = Inclusion.NON_NULL)
public class Student {
	private Integer id;
	private String name;
	private Integer sex;
	private Integer age;

	public Student() {
	}
	/** setter/getter **/
}
    說明:@JsonSerialize(include = Inclusion.NON_NULL)為JackSon的註解,作用是返回JSON格式的實體時不返回該實體類值為Null的Field,如: {"id" : 1,"name" : null,"sex" : 1,"age" : 20} 。


五、Resource程式碼
    1、StudentResource:示例中主要針對單個例項的Retrieve、Update和Delete。

@Controller
@Scope("prototype")
public class StudentResource extends ServerResource {
	private Integer id;
	@Autowired
	private StudentBO studentBO;

	public void setStudentBO(StudentBO studentBO) {
		this.studentBO = studentBO;
	}

	@Override
	protected void doInit() throws ResourceException {
		id = Integer.valueOf((String) getRequestAttributes().get("studentId"));
	}

	@Get("json")
	public Student findStudentById() {
		Student s = this.studentBO.getStudent(id);
		return s;
	}

	@Delete("json")
	public Integer deleteStudentById() {
		return this.studentBO.removeStudent(id);
	}

	@Put("json")
	public Integer updateStudent(Student student) {
		student.setId(id);
		return this.studentBO.saveOrUpdateStudent(student);
	}
}
    2、StudentListResource:示例中主要針對單個例項的Create和多個例項的Retrieve。

@Controller
@Scope("prototype")
public class StudentListResource extends ServerResource {
	@Autowired
	private StudentBO studentBO;

	@Post
	public Integer saveStudent(Student student) {
		return studentBO.saveOrUpdateStudent(student);
	}

	@Get("json")
	public List<Student> findStudentAll() {
		return studentBO.getStudentAll();
	}

	public void setStudentBO(StudentBO studentBO) {
		this.studentBO = studentBO;
	}
}
    說明:接受Spring管理的Bean,@Scope("prototype")的annotation必須要有,否則會出現正確呼叫指定方法的問題,用xml配置Bean時也必須要Attribute:scope。


六、BusinessObject程式碼

@Service
@Scope("prototype")
public class StudentBO {
	private static Map<Integer, Student> students = new HashMap<Integer, Student>();
	// next Id
	private static int nextId = 5;
	static {
		students.put(1, new Student(1, "Michael", 1, 18));
		students.put(2, new Student(2, "Anthony", 1, 22));
		students.put(3, new Student(3, "Isabella", 0, 19));
		students.put(4, new Student(4, "Aiden", 1, 20));
	}

	public Student getStudent(Integer id) {
		return students.get(id);
	}

	public List<Student> getStudentAll() {
		return new ArrayList<Student>(students.values());
	}

	public Integer saveOrUpdateStudent(Student student) {
		if (student.getId() == null) {
			student.setId(nextId++);
		}
		students.put(student.getId(), student);
		return student.getId();
	}

	public Integer removeStudent(Integer id) {
		students.remove(id);
		return id;
	}
}
七、Spring applictionContext.xml配置

<!-- 該application在web.xml中引用  -->
<bean name="application" class="org.restlet.Application">
	<property name="inboundRoot">
		<bean class="org.restlet.ext.spring.SpringRouter">
			<constructor-arg ref="application"/>
			<property name="attachments">
				<map>
					<entry key="/student/{studentId}">
						<bean class="org.restlet.ext.spring.SpringFinder">
							<lookup-method name="create" bean="studentResource"/>
						</bean>
					</entry>
					<entry key="/student">
						<bean class="org.restlet.ext.spring.SpringFinder">
							<lookup-method name="create" bean="studentsResource"/>
						</bean>
					</entry>
				</map>
			</property>
		</bean>
	</property>
</bean>
<!-- spring annotation -->
<context:component-scan base-package="com.xl.sr"/>
八、Client程式碼

public class StudentClient {
	public void student_get() {
		try {
			ClientResource client = new ClientResource("http://127.0.0.1:8080/SpringRestlet/student/1");
			Representation representation = client.get();
			System.out.println(representation.getText());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void student_delete() {
		try {
			ClientResource client = new ClientResource("http://127.0.0.1:8080/SpringRestlet/student/1");
			Representation representation = client.delete();
			System.out.println(representation.getText());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void student_put() {
		try {
			ClientResource client = new ClientResource("http://127.0.0.1:8080/SpringRestlet/student/1");
			Student student = new Student("Test_Put", 1, 18);
			Representation representation = client.put(student, MediaType.APPLICATION_JAVA_OBJECT);
			System.out.println(representation.getText());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void student_post() {
		try {
			ClientResource client = new ClientResource("http://127.0.0.1:8080/SpringRestlet/student");
			Student student = new Student("Test_Post", 1, 18);
			Representation representation = client.post(student, MediaType.APPLICATION_JAVA_OBJECT);
			System.out.println(representation.getText());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void student_findAll() {
		try {
			ClientResource client = new ClientResource("http://127.0.0.1:8080/SpringRestlet/student");
			Representation representation = client.get();
			System.out.println(representation.getText());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		StudentClient client = new StudentClient();
		client.student_get();
	}
}
九、補充
    (1)、請求引數問題:客戶端傳送形如/student/{studentId}的URI請求時,可能是還需要攜帶其他parameter的,引數攜帶形式可如/student/{studentId}?name=John&sex=23;Server端獲取引數時,針對在URI{}內的引數使用getRequest().getAttributes().get("studentId");方式獲取,針對附加引數可以通過Form form = getRequest().getResourceRef().getQueryAsForm(); String name = form.getValues("name");方式獲取。
    (2)、客戶端工具:測試Server端時,如果不想寫Client端code,可以是WizTools.org的RestClient-ui.jar的小工具,Post和Put請求時的物件可以以JSON格式新增到Http body中即可。
    (3)、相關資源:文中工程以上傳至51cto下載中心,含程式碼和Jar包。連結地址:http://download.csdn.net/detail/u013379717/7127389
 
 
 

相關文章