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 小小凉粉 阅读(358) | 评论 (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 小小凉粉 阅读(446) | 评论 (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 小小凉粉 阅读(1133) | 评论 (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 小小凉粉 阅读(262) | 评论 (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 小小凉粉 阅读(288) | 评论 (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 小小凉粉 阅读(849) | 评论 (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 小小凉粉 阅读(169) | 评论 (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 小小凉粉 阅读(313) | 评论 (0)编辑 收藏

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