1. Log配置
无论是Jetty服务器自身,还是Web服务程序的需求,都需要提供log服务。我们使用log4j,这里提供一个简单的log4j的配置,如下:
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd
HH:mm:ss.SSS}:: %-4r [%t] %-5p %c %x %n%-5p %m%n
log4j.rootLogger=info, stdout, R
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.file=gridServer.log
log4j.appender.R.MaxFileSize=100KB
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d{yyyy-mm-dd
HH:mm:ss.SSS} ::%-4r [%t] %-5p %c %x %n%-5p %m%n
2. 开启jetty服务
直接执行StartServer类的main方法,您应当能够获取如下的输出信息。
2011-07-12 10:30:18.875::
0 [main]
INFO org.eclipse.jetty.util.log
INFO jetty-7.3.0.v20110203
2011-07-12 10:30:19.296:: 421 [main] INFO /MutiInvoke
INFO Initializing Spring root
WebApplicationContext
2011-07-12 10:30:19.296:: 421 [main] INFO org.springframework.web.context.ContextLoader
INFO Root WebApplicationContext:
initialization started
2011-07-12 10:30:19.343:: 468 [main] INFO org.springframework.web.context.support.XmlWebApplicationContext
INFO Refreshing Root
WebApplicationContext: startup date [Tue Jul 12 10:30:19 CST 2011];
root of context hierarchy
2011-07-12 10:30:19.421:: 546 [main] INFO org.springframework.beans.factory.xml.XmlBeanDefinitionReader
INFO Loading XML bean definitions
from ServletContext resource
[/resources/spring/spring-servlet.xml]
2011-07-12 10:30:19.828:: 953 [main] INFO org.springframework.beans.factory.support.DefaultListableBeanFactory
INFO Pre-instantiating singletons
in
org.springframework.beans.factory.support.DefaultListableBeanFactory@f18e8e:
defining beans
[org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,studentDao,studentResource];
root of factory hierarchy
2011-07-12 10:30:19.843:: 968 [main] INFO org.springframework.web.context.ContextLoader
INFO Root WebApplicationContext:
initialization completed in 547 ms
2011-07-12 10:30:19.843:: 968 [main] INFO org.eclipse.jetty.util.log
INFO started
o.e.j.w.WebAppContext{/MutiInvoke,file:/I:/programs/eclipse/MutiInvokeTest/}
2011-07-12 10:30:19.953:: 1078 [main]
INFO /MutiInvoke
INFO Initializing Spring
FrameworkServlet 'Flex blazeds'
2011-07-12 10:30:19.953:: 1078 [main]
INFO org.springframework.web.servlet.DispatcherServlet
INFO FrameworkServlet 'Flex
blazeds': initialization started
2011-07-12 10:30:19.953:: 1078 [main]
INFO org.springframework.web.context.support.XmlWebApplicationContext
INFO Refreshing
WebApplicationContext for namespace 'Flex blazeds-servlet': startup
date [Tue Jul 12 10:30:19 CST 2011]; parent: Root
WebApplicationContext
2011-07-12 10:30:19.953:: 1078 [main]
INFO org.springframework.beans.factory.xml.XmlBeanDefinitionReader
INFO Loading XML bean definitions
from ServletContext resource
[/resources/spring/spring-flex-servlet.xml]
2011-07-12 10:30:20.125:: 1250 [main]
INFO org.springframework.beans.factory.support.DefaultListableBeanFactory
INFO Pre-instantiating singletons
in
org.springframework.beans.factory.support.DefaultListableBeanFactory@18d7ace:
defining beans
[_messageBrokerHandlerAdapter,_messageBrokerDefaultHandlerMapping,_jsonConfigMapEditorConfigurer,_messageBrokerMessagingProcessor,_flexRemotingAnnotationPostProcessor,_messageBrokerRemotingProcessor,org.springframework.flex.core.ExceptionTranslationAdvice#0,org.springframework.flex.core.EndpointServiceMessagePointcutAdvisor#0,org.springframework.flex.core.MessageInterceptionAdvice#0,org.springframework.flex.core.EndpointServiceMessagePointcutAdvisor#1,_messageBrokerEndpointProcessor,_messageBroker,org.springframework.flex.remoting.RemotingDestinationExporter#0];
parent:
org.springframework.beans.factory.support.DefaultListableBeanFactory@f18e8e
2011-07-12 10:30:20.218:: 1343 [main]
INFO org.springframework.flex.config.FlexConfigurationManager
INFO Loading Flex services
configuration from: ServletContext resource
[/resources/flex/services-config.xml]
2011-07-12 10:30:20.343:: 1468 [main]
INFO org.springframework.flex.config.FlexConfigurationManager
INFO Including Flex services
configuration from: ServletContext resource
[/resources/flex/remoting-config.xml]
2011-07-12 10:30:20.484:: 1609 [main]
INFO org.springframework.flex.core.MessageBrokerFactoryBean
INFO BlazeDS - Community Edition:
4.0.0.14931
2011-07-12 10:30:20.531:: 1656 [main]
INFO org.springframework.flex.core.MessageBrokerFactoryBean
INFO MessageBroker with id
'_messageBroker' is starting.
2011-07-12 10:30:20.796:: 1921 [main]
INFO org.springframework.flex.core.MessageBrokerFactoryBean
INFO MessageBroker with id
'_messageBroker' is ready (startup time: '265' ms)
2011-07-12 10:30:20.796:: 1921 [main]
INFO org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
INFO Default mapping to handler
[flex.messaging.MessageBroker@2bccb2]
2011-07-12 10:30:20.812:: 1937 [main]
INFO org.springframework.flex.remoting.RemotingDestinationExporter
INFO Created remoting destination
with id 'studentResource'
2011-07-12 10:30:20.828:: 1953 [main]
INFO org.springframework.flex.remoting.RemotingDestinationExporter
INFO Remoting destination
'studentResource' has been started started successfully.
2011-07-12 10:30:20.921:: 2046 [main]
INFO org.springframework.web.servlet.DispatcherServlet
INFO FrameworkServlet 'Flex
blazeds': initialization completed in 968 ms
2011-07-12 10:30:20.921:: 2046 [main]
INFO /MutiInvoke
INFO Initializing Spring
FrameworkServlet 'RMI Hessian'
2011-07-12 10:30:20.921:: 2046 [main]
INFO org.springframework.web.servlet.DispatcherServlet
INFO FrameworkServlet 'RMI
Hessian': initialization started
2011-07-12 10:30:20.921:: 2046 [main]
INFO org.springframework.web.context.support.XmlWebApplicationContext
INFO Refreshing
WebApplicationContext for namespace 'RMI Hessian-servlet': startup
date [Tue Jul 12 10:30:20 CST 2011]; parent: Root
WebApplicationContext
2011-07-12 10:30:20.921:: 2046 [main]
INFO org.springframework.beans.factory.xml.XmlBeanDefinitionReader
INFO Loading XML bean definitions
from ServletContext resource
[/resources/spring/spring-hessianRmi-servlet.xml]
2011-07-12 10:30:20.953:: 2078 [main]
INFO org.springframework.beans.factory.support.DefaultListableBeanFactory
INFO Pre-instantiating singletons
in
org.springframework.beans.factory.support.DefaultListableBeanFactory@110278e:
defining beans [/student]; parent:
org.springframework.beans.factory.support.DefaultListableBeanFactory@f18e8e
2011-07-12 10:30:21.031:: 2156 [main]
INFO org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
INFO Mapped URL path [/student]
onto handler
[org.springframework.remoting.caucho.HessianServiceExporter@6b62d1]
2011-07-12 10:30:21.093:: 2218 [main]
INFO org.springframework.web.servlet.DispatcherServlet
INFO FrameworkServlet 'RMI
Hessian': initialization completed in 172 ms
2011-07-12 10:30:21.140:: 2265 [main]
INFO org.eclipse.jetty.util.log
INFO Started
SelectChannelConnector@202.194.158.128:8089
2011-07-12 10:30:21.140:: 2265 [main]
INFO org.eclipse.jetty.util.log
INFO Started
SelectChannelConnector@localhost:8088
2011-7-12 10:30:49
com.sun.jersey.spi.spring.container.servlet.SpringServlet
getContext
信息: Using default applicationContext
2011-7-12 10:30:49
com.sun.jersey.spi.spring.container.SpringComponentProviderFactory
registerSpringBeans
信息: Registering Spring bean, studentResource, of
type org.example.resource.StudentResource as a root resource
class
2011-7-12 10:30:49
com.sun.jersey.server.impl.application.WebApplicationImpl
_initiate
信息: Initiating Jersey application, version 'Jersey: 1.8
06/24/2011 12:17 PM'
通过阅读输出的信息,您应当能看出我们提供的三种风格的服务都已经正常开启。
3. 编写客户端
RMI类型的客户端,相对比较简单,下面代码简单描述了如何连接并使用远程服务.
package org.example.client;
import java.net.MalformedURLException;
import java.util.List;
import org.example.model.Student;
import
org.example.remoteInvoke.StudentInterface;
import
com.caucho.hessian.client.HessianProxyFactory;
public class RmiClient {
public static void main(String[] args)
throws MalformedURLException {
String url =
"http://202.194.158.128:8089/MutiInvoke/RMI/student";
HessianProxyFactory factory = new HessianProxyFactory();
StudentInterface studentResource = (StudentInterface)
factory.create(StudentInterface.class, url);
studentResource.createStudent(new
Student("张三","S09080504",19));
studentResource.createStudent(new
Student("李氏","S09080503",18));
List students =
studentResource.getAllStudent();
for(Student s:students)
{
System.out.println(s.getName());
System.out.println(s.getId());
System.out.println(s.getAge());
}
}
}
在这里,我们先创建了两个同学,然后将新同学添加到服务端,之后获取同学并输出。
执行输出结果:
张三
S09080504
19
李氏
S09080503
18
Rest客户端与RMI比较相似,我们借助Spring的RestTemplate完成对Http服务的创建和使用。
package org.example.client;
import java.net.URI;
import java.net.URISyntaxException;
import org.example.model.Student;
import org.example.model.StudentList;
import
org.springframework.web.client.RestClientException;
import
org.springframework.web.client.RestTemplate;
public class RestClient {
private static String url =
"http://202.194.158.128:8089/MutiInvoke/REST/student/";
public static void main(String[] args)
throws RestClientException, URISyntaxException {
RestTemplate restTemplate = new RestTemplate();
Student student = new Student("大关", "S09080458", 22);
restTemplate.postForLocation(new URI(url),
student);
student = new Student("李雷","S09080707",33);
restTemplate.postForLocation(new URI(url),
student);
student = new Student("Lucy","S09080808",23);
restTemplate.postForLocation(new URI(url),
student);
StudentList students = restTemplate.getForObject(new
URI(url), StudentList.class);
for(Student s:students.getStudent())
{
System.out.println(s.getId());
System.out.println(s.getName());
System.out.println(s.getAge());
System.out.println();
}
}
}
这次创建了三个同学,并将三个新同学添加到远程,之后获取所有同学。
执行结果:
S09080707
李雷
33
S09080504
张三
19
S09080808
Lucy
23
S09080503
李氏
18
S09080458
大关
22
(注意,由于RMI已经向远程提交了两个新同学,因此,这里就是五个同学的信息)。
最后给出Flex客户端代码(注意Flex要使用Flash
Builder进行编写和运行,并需要连接服务额外的操作,如果您对Flex感兴趣,可以参考我的其他文章,或者直接到官方网站下载相应的教程(有一个七天学会Flex的视频教程推荐观看)。
encoding="utf-8"?>
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955"
minHeight="600" xmlns:services="services.*">
import mx.collections.ArrayList;
import mx.controls.Alert;
import mx.rpc.CallResponder;
import valueObjects.Student;
[Bindable]
public var responder:CallResponder = new
CallResponder();
protected function
addStudent_clickHandler(event:MouseEvent):void
{
var student:Student = new Student();
student.id = studentId.text;
student.name = studentName.text;
student.age = Number(age.text);
studentResource.createStudent(student);
}
protected function
getAllStudent_clickHandler(event:MouseEvent):void{
responder.token = studentResource.getAllStudent();
}
]]>
id="studentResource"
fault="Alert.show(event.fault.faultString + '\n' +
event.fault.faultDetail)"
showBusyCursor="true">
url="http://202.194.158.128:8089/MutiInvoke/messagebroker/amf"/>
paddingLeft="20"
paddingRight="20">
width="100%">
width="100%"/>
width="100%">
width="100%"/>
width="100%">
width="100%"/>
click="addStudent_clickHandler(event)"/>
height="100%">
click="getAllStudent_clickHandler(event)"/>
dataProvider="{responder.lastResult}">
dataField="name"/>
dataField="id"/>
dataField="age"/>
执行结果:
4. 总结
本文通过以一步一步的方式,讲解了如何实现一个提供多种通信风格的Web服务的搭建,通过对本文的学习,您应当能够了解不同的通信风格的优缺点,并能够为自己的web服务选择合适的通信风格。
5. 文档结构
I:\programs\eclipse\MutiInvokeTest>tree /f
├─lib
│ aopalliance.jar
│ asm-3.1.jar
│ asm-3.3.jar
│ backport-util-concurrent-2.2.jar
│ castor-1.3-core.jar
│ castor-1.3.jar
│ cglib-nodep-2.2.jar
│ commons-fileupload-1.2.1.jar
│ commons-io-1.3.2.jar
│ commons-logging-api-1.1.1.jar
│ dom4j-1.6.1.jar
│ flex-messaging-common.jar
│ flex-messaging-core.jar
│ flex-messaging-opt.jar
│ flex-messaging-proxy.jar
│ flex-messaging-remoting.jar
│ flex-rds-server.jar
│ hessian-4.0.7.jar
│ javax.el_2.1.0.v201004190952.jar
│ javax.servlet.jsp.jstl_1.2.0.v201004190952.jar
│ javax.servlet.jsp_2.1.0.v201004190952.jar
│ jaxen-1.1-beta-6.jar
│ jcl-over-slf4j-1.5.8.jar
│ jersey-core-1.8.jar
│ jersey-server-1.8.jar
│ jersey-spring-1.8.jar
│ jetty-ajp-7.3.0.v20110203.jar
│ jetty-annotations-7.3.0.v20110203.jar
│ jetty-client-7.3.0.v20110203.jar
│ jetty-continuation-7.3.0.v20110203.jar
│ jetty-deploy-7.3.0.v20110203.jar
│ jetty-http-7.3.0.v20110203.jar
│ jetty-io-7.3.0.v20110203.jar
│ jetty-jmx-7.3.0.v20110203.jar
│ jetty-jndi-7.3.0.v20110203.jar
│ jetty-jsp-2.1-7.3.0.v20110203.jar
│ jetty-plus-7.3.0.v20110203.jar
│ jetty-policy-7.3.0.v20110203.jar
│ jetty-rewrite-7.3.0.v20110203.jar
│ jetty-security-7.3.0.v20110203.jar
│ jetty-server-7.3.0.v20110203.jar
│ jetty-servlet-7.3.0.v20110203.jar
│ jetty-servlets-7.3.0.v20110203.jar
│ jetty-util-7.3.0.v20110203.jar
│ jetty-webapp-7.3.0.v20110203.jar
│ jetty-websocket-7.3.0.v20110203.jar
│ jetty-xml-7.3.0.v20110203.jar
│ jsr311-api-1.1.1.jar
│ junit-4.7.jar
│ log4j-1.2.16.jar
│ org.apache.jasper.glassfish_2.1.0.v201007080150.jar
│ org.springframework.aop-3.0.3.RELEASE.jar
│ org.springframework.asm-3.0.3.RELEASE.jar
│ org.springframework.aspects-3.0.3.RELEASE.jar
│ org.springframework.beans-3.0.3.RELEASE.jar
│ org.springframework.context-3.0.3.RELEASE.jar
│ org.springframework.context.support-3.0.3.RELEASE.jar
│ org.springframework.core-3.0.3.RELEASE.jar
│ org.springframework.expression-3.0.3.RELEASE.jar
│ org.springframework.flex-1.0.3.RELEASE.jar
│ org.springframework.instrument-3.0.3.RELEASE.jar
│ org.springframework.instrument.tomcat-3.0.3.RELEASE.jar
│ org.springframework.oxm-3.0.3.RELEASE.jar
│ org.springframework.web-3.0.3.RELEASE.jar
│ org.springframework.web.servlet-3.0.3.RELEASE.jar
│ servlet-api-2.5.jar
│ slf4j-api-1.5.8.jar
│ slf4j-log4j12-1.5.8.jar
├─resources
│ │ log4j.properties
│ │ version.properties
│ │ web.xml
│ │
│ ├─flex
│ │ crossdomain.xml
│ │ messaging-config.xml
│ │ proxy-config.xml
│ │ remoting-config.xml
│ │ services-config.xml
│ │
│ └─spring
│ spring-flex-servlet.xml
│ spring-hessianRmi-servlet.xml
│ spring-servlet.xml
│
├─src
│ │ log4j.properties
│ │ StudentLists.xsd
│ │
│ └─org
│ └─example
│ ├─client
│ │ RestClient.java
│ │ RmiClient.java
│ │
│ ├─model
│ │ Student.java
│ │ StudentDao.java
│ │ StudentList.java
│ │
│ ├─remoteInvoke
│ │ StudentInterface.java
│ │
│ ├─resource
│ │ StudentResource.java
│ │
│ └─server
│ StartServer.java
│
└─WEB-INF
└─flex
crossdomain.xml
messaging-config.xml
proxy-config.xml
remoting-config.xml
services-config.xml
6. 参考文献
Spring 官方文档
Jersey 官方文档
Flex 使用文档 Adobe官方文档
Jetty 官方文档