posts - 28, comments - 27, trackbacks - 0, articles - 0
  语源科技BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

首先下载soap,把soap.war放到tomcat/webapp/目录下,在classpath下面加入soap.jar、mail.jar和 activation.jar,然后创建一个Service和Client,把Service.class放到 tomcat/webapp/soap/WEB-INF/classes目录下,然后把mail.jar和activation.jar放到 tomcat/webapp/soap/WEB-INF/lib下面,并写一个配置文件用于部署服务。

<isd:service
   xmlns:isd="http://xml.apache.org/xml-soap/deployment"
   id="urn:service" checkMustUnderstands="true">
      <isd:provider type="java" scope="Request" methods="setAlarm">
      <isd:java class="work.Service" static="false"/>
   </isd:provider>
</isd:service>


上面的work.Service是类的全名,setAlarm是提供的服务名,urn:service是URI。再写一个脚本来调用配置文件部署服务

java org.apache.soap.server.ServiceManagerClient
http://localhost:8080/soap/servlet/rpcrouter deploy deploy.xml

启动Tomcat之后,启动脚本,然后执行Client代码就可以了,Client的主体代码很简单,代码里面就不加入注释了。
  
    Call call = new Call ();
    call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
    call.setTargetObjectURI ("urn:service");
    call.setMethodName ("setAlarm");
    Parameter param = new Parameter("alarm", String.class, alarm, Constants.NS_URI_SOAP_ENC);
    Vector paramList = new Vector();
    paramList.addElement(param);
    call.setParams (paramList);
    URL url = new URL ("http://localhost:8080/soap/servlet/rpcrouter");
    Response resp = call.invoke (url, "");
    if (!resp.generatedFault()) {
      // Extract Return value
      Parameter result = resp.getReturnValue ();
      String greeting = (String) result.getValue();
      return greeting;
    }
    else {
      //  Extract Fault Code and String
      Fault f = resp.getFault();
      String faultCode = f.getFaultCode();
      String faultString = f.getFaultString();
      System.err.println("Fault Occurred (details follow):");
      System.err.println("Fault Code:  "+faultCode);
      System.err.println("Fault String:  "+faultString);
      return new String ("Fault Occurred.  No greeting for you!");
    }

posted @ 2006-09-18 15:06 小小凉粉 阅读(403) | 评论 (0) | 编辑 收藏

昨天写完程序并部署Service之后,一直都在抛出接口不匹配的异常,于是我就写了个简单的接口,只传入一个String类型的参数,结果运行正常。然后我又写了个只传入Integer类型参数的接口,果不出所料,又发生了接口不匹配的异常。接下来我就开始改Client端代码:

params.addElement(new Parameter("eventStatus",Integer.class, new Integer(1), null));
params.addElement(new Parameter("eventStatus",int.class, new Integer(1), null));
params.addElement(new Parameter("eventStatus",int.class, 1, null));
params.addElement(new Parameter("eventStatus",Intege.class, 1, null));
结果统统失败,弄的我都要抓狂了。

今天到了公司以后,跟组长说了这件事情,组长说让我换用AXIS试试看,我到ws.apache.org/axis上面看了看文档,在user guide里面给出的例子和我的代码差别很大,我就只好按着它的例子重新改代码

写完以后,配环境变量配的快要抓狂……部署的时候又是一头雾水……最后始终没有成功……最后回到宿舍才想到,AXIS和Apache SOAP Server不过都是服务器而已,不应该存在规范上的区别,也就是不应该会影响到客户端的程序,于是我就按照最开始的代码,把Service部署好,启动 Tomcat,从WSDL中找到对应的信息

<wsdl:service name="ServiceService">
 <wsdl:port binding="impl:serviceSoapBinding" name="service">
  <wsdlsoap:address location="http://localhost:8080/axis/services/service" />
 </wsdl:port>
</wsdl:service>

在xml配置文件中,把location赋值给URL,把name赋值给TargetObjectURI,运行Client,一切OK
不知道是不是因为机器的问题,在公司的思路远远不如在宿舍啊

不过今天至少让我很熟练的掌握了如何手工部署AXIS服务,创建一个wsdd文件,我把它命名为deploy.wsdd

<deployment name="lijian" xmlns="http://xml.apache.org/axis/wsdd/"
    xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
  <service name="service" provider="java:RPC">
    <parameter name="className" value="Service" />
    <parameter name="allowedMethods" value="setAlarmInfo" />
  </service>
</deployment>


把这个文件放到Tomcat/webapps/axis/WEB-INF/目录下,把service的类放到WEB-INF/classes/目录下,把 axis.jar;jaxrpc.jar;commons-logging-1.0.4.jar;commons-discovery-0.2.jar;saaj.jar 放到classpath里面,启动Tomcat之后,到webapps/axis/WEB-INF目录下运行:
java org.apache.axis.client.AdminClient deploy.wsdd
之后可以访问
http://localhost:8080/axis/
来查看刚才部署的service对应的wsdl了

posted @ 2006-09-18 15:05 小小凉粉 阅读(487) | 评论 (0) | 编辑 收藏

在web环境下,Quartz可以通过配置文件来完成后台的作业调度,不必手工创建Trigger和Scheduler,其步骤如下:

首先将quartz.jar,以及lib目录下面core和optional两个目录中的所有jar全都放入项目WEB-INF\lib目录下

job就是一个简单的java类,这里的功能就是输出当前的时间了。

import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class Helloworld implements Job{
 public Helloworld() {
 }

 private static Log _log = LogFactory
   .getLog(Helloworld.class);

 public void execute(JobExecutionContext context)
   throws JobExecutionException {
  _log.info("Hello World! - " + new Date());
 }
}

然后编写quartz.properties文件,这个文件的默认名称就是quartz.properties,如果启动项目的时候,Quartz没有在工程中找到该文件,就会从自己的jar包下面读取其默认的properties文件,其内容如下:

org.quartz.scheduler.instanceName = TestScheduler
org.quartz.scheduler.instanceId = one

org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount =  2
org.quartz.threadPool.threadPriority = 4

org.quartz.plugin.triggHistory.class = org.quartz.plugins.history.LoggingTriggerHistoryPlugin
org.quartz.plugin.triggHistory.triggerFiredMessage = Trigger {1}.{0} fired job {6}.{5} at: {4, date, HH:mm:ss MM/dd/yyyy}
org.quartz.plugin.triggHistory.triggerCompleteMessage = Trigger {1}.{0} completed firing job {6}.{5} at {4, date, HH:mm:ss MM/dd/yyyy} with resulting trigger instruction code: {9}

org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.JobInitializationPlugin
org.quartz.plugin.jobInitializer.fileName = quartz_job.xml
org.quartz.plugin.jobInitializer.overWriteExistingJobs = false
org.quartz.plugin.jobInitializer.failOnFileNotFound = true
org.quartz.plugin.shutdownhook.class = org.quartz.plugins.management.ShutdownHookPlugin
org.quartz.plugin.shutdownhook.cleanShutdown = true

上面的

org.quartz.plugin.jobInitializer.fileName = quartz_job.xml

是用来配置定义job文件的名称。

然后编写quartz_job.xml,

<?xml version="1.0" encoding="UTF-8"?>
<quartz>
  <job>
    <job-detail>
      <name>helloworld</name>
      <group>group1</group>
      <job-class>Helloworld</job-class>
    </job-detail>
    <trigger>
      <cron>
        <name>test</name>
        <group>group1</group>
        <job-name>helloworld</job-name>
        <job-group>group1</job-group>
        <cron-expression>0 0/1 * * * ?</cron-expression>
     </cron>
    </trigger>
  </job>
</quartz>

可以看到,在配置文件中把jobdetail和trigger都作了完整的定义,并组合成一个job。下面,我们把上面两个文件都放入/WEB-INF/classes目录下,然后按照api中的说明修改一下web.xml。

     <servlet>
         <servlet-name>
             QuartzInitializer
         </servlet-name>
         <display-name>
             Quartz Initializer Servlet
         </display-name>
         <servlet-class>
             org.quartz.ee.servlet.QuartzInitializerServlet
         </servlet-class>
         <load-on-startup>1</load-on-startup>
         <init-param>
             <param-name>config-file</param-name>
             <param-value>/quartz.properties</param-value>
         </init-param>
         <init-param>
             <param-name>shutdown-on-unload</param-name>
             <param-value>true</param-value>
         </init-param>
     </servlet>

这样,在启动Tomcat的时候,QuartzInitializerServlet这个Servlet就会自动读取quartz.properties这个配置文件,并初始化调度信息,启动Scheduler。
我在这里用的是Quartz1.5.0,在1.5.1中新增加了QuartzInitializerListener,但是似乎有些问题,始终启动不起来,而且更过分的是,它的api居然写错了,在<listener-class>这个标记中,用了 QuartzInitializerServletListener,就算把机器砸了,它也找不到这个类啊!

现在就大功告成了
一个Job类,一个quartz.properties文件,一个quertz_job.xml文件,还有修改一下web.xml文件,很简单呀!

不过看起来简单,解决的过程却很郁闷,单单是考虑如何在后台进程中运行Servlet就花了好长时间,后来查资料以后才知道可以用Listener或者是启动时运行的Servlet来完成,看来自己的底子还是不扎实的.

另外就是在Tomcat出现问题的时候,居然忘了到logs下面去看日志,这个疏忽是不可原谅的!以后要牢牢记住!

posted @ 2006-09-18 15:05 小小凉粉 阅读(1178) | 评论 (0) | 编辑 收藏

在验证用户登录的时候,各个类调用的顺序如下所示:

authenticationProcessionFilter(AuthenticationProcessingFilter)---->

authenticationManager(ProviderManger)---->

daoAuthenticationProvider(DaoAuthenticationProvider)---->

userDetailsService(UserDetailsService)

在最底层的UserDetailsService接口中,提供了loadUserByUsername这个方法,我们只需要实现这个接口,并实现接口中的方法,就可以使用自己的验证功能了。该方法传入的参数是String username,返回类型是UserDetails,很显然,我们需要通过自己的dao,根据username来得到自定义的user类型,然后把它封装到UserDetails里面去,然后返回。

另外,在UserDetail这个类里面,有一个GrantedAuthority[] 类型的属性,用来存放该用户所对应的权限,我们在loadUserByUsername这个方法里面,同样也需要得到该用户的权限,并把它赋给返回的UserDetails。

假如用户对应的类名为UserInfo,权限对应的类名为Roles,在UserInfo中有一个变量

private Set roles;

在得到权限信息的时候,因为它是集合,所以可以使用延迟加载功能,读取的时候先从缓存中取数据,如果取不到的话,就调用UserInfo.getRoles()方法,这个时候就会到数据库中取数据了,取到以后,再把数据放到缓存中。

posted @ 2006-09-18 15:04 小小凉粉 阅读(315) | 评论 (0) | 编辑 收藏

1. SOAP--Simple Object Access Protocal

SOAP is a lightweight protocol intented to exchanging structured information in a decentralized, distributed environment.The two major goals for SOAP is simplicity and extensibility.

SOAP is widely used for XML messaging as it :

    defines thin layer on top of widely understood HTTP 
    is flexible and extensible 
    enjoys broad industry and developer community support

Main uses of SOAP are for

    messaging: sending XML data orders, invoices, forms 
    RPC: invoking services querying data sources, transacting

2. WSDL--Web Service Definition Language

As the communication protocols and message formats are standardized in the web community, it becomes increasingly possible and important to be able to describe the communication s in some structured way.WSDL addresses this need by defining an XML grammar for describing network services as collections of communication endpoints capable of exchanging messages.

3.  UDDI-- Universal Description, Discovery, and Integration

UDDI protocol is a central element of the group of related standards that comprise the Web services stack. The specification defines a standard method for publishing and discovering the network-based software components of a service-oriented architecture.

4.  the relationship between SOAP,WSDL and UDDI

web service client 需要定位另一个应用程序或者是网络上的某一段业务逻辑, client 通过 name 、 catagory 、 identifier 或者 specification 来从 UDDI registry 中查询服务,定位以后, client 从 UDDI registry 中得到 WSDL 文档的位置信息。在 WSDL 文档的 XML schema 中包含了如何访问 web service 和请求信息的格式, client 按照 xml schema 的格式来创建一个 soap 消息,并向 host 发送请求。

posted @ 2006-09-18 15:03 小小凉粉 阅读(340) | 评论 (0) | 编辑 收藏

用一个类来存放applicationContext:
public class ContextHolder {
  private final static ContextHolder instance = new ContextHolder();
  private ApplicationContext ac;
  private ContextHolder() {
  }
  public static ContextHolder getInstance() {
    return instance;
  }
  public synchronized void setApplicationContext(ApplicationContext ac) {
    this.ac = ac;
  }
  public ApplicationContext getApplicationContext() {
    return ac;
  }  
}

然后写一个servlet,继承自org.springframework.web.context.ContextLoaderServlet,并配置web.xml,让它在tomcat启动时自动运行。然后在它的init方法中,加入如下的代码:
WebApplicationContext context = WebApplicationContextUtils.
    getWebApplicationContext(this.getServletContext());
ContextHolder.getInstance().setApplicationContext(context);

posted @ 2006-09-18 14:57 小小凉粉 阅读(900) | 评论 (0) | 编辑 收藏

Can you foresee everything? No. Are the decisions you make today final? No. It's practically impossible to think everything or know everything in the beginning of a project. You will learn more as a project goes on. However, you can use your experience or experiences of others to guide you in a certain direction. You can make decisions that might minimize changes tomorrow.

posted @ 2006-09-18 14:54 小小凉粉 阅读(210) | 评论 (0) | 编辑 收藏

EventHandler要抽象出一个接口来,然后根据不同的需要实现不同的handler,不然就无法在服务器reply以后通知UI更新,但至于是否要在UI中再生成异步线程来做这件事情,还要通过编码测试一下。

不过目前我的感觉是不需要再生成异步线程了,因为底层Peercore的操作本身就是异步的,不需要等待它的方法操作完毕以后再返回,应该只需要把UI中要更新的控件作为参数传到EventHandler里面去,这样handler就可以通知UI更新了——打住!RCP非UI的线程是无法操作UI线程的!!只能通过UIJob或者是Display.asnyexec()方法来更新UI,所以....还是要定义很多的UIJob的子类的......

posted @ 2006-09-18 14:54 小小凉粉 阅读(340) | 评论 (0) | 编辑 收藏

仅列出标题
共3页: 上一页 1 2 3