0

我想用 Spring3 创建 Web 服务(使用自下而上的原则)。

在这里,我对需要在 web.xml 文件中声明的 servlet 感到困惑。

我在 Google 中获得了两个使用不同 servlet 的参考。

1> org.springframework.ws.transport.http.MessageDispatcherServlet 2> com.sun.xml.ws.transport.http.servlet.WSSpringServlet

谁能建议我将哪个 servlet 用于 Spring Web Service ?

我也面临网络服务中的 DI 问题。

这是我的网络服务配置 sel-ws-config.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:wss="http://jax-ws.dev.java.net/spring/servlet"
        xmlns:ws="http://jax-ws.dev.java.net/spring/core"   
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                            http://www.springframework.org/schema/context
                            http://www.springframework.org/schema/context/spring-context-3.0.xsd
                            http://jax-ws.dev.java.net/spring/core
                            http://jax-ws.dev.java.net/spring/core.xsd
                            http://jax-ws.dev.java.net/spring/servlet
                            http://jax-ws.dev.java.net/spring/servlet.xsd
                            ">

    <!-- FOR DEPENDENCY INJECTION -->                           
    <context:component-scan base-package="com.eks.sel.web.service" />

    <!--SET THE SERVICE ANNOTATION DRIVEN -->
    <!-- <wss:annotation-driven/> -->                           

    <!--DECLARE WEB SERVICE BEAN DETAILs -->
    <wss:binding url="/authenticateUserService">
        <wss:service>
            <ws:service  bean="#authenticateUserServiceBean" />                     
        </wss:service>      
    </wss:binding>


    <bean id="authenticateUserServiceBean" class="com.eks.sel.web.service.AuthenticateUserWS">
         <property name="userService">
            <ref bean="userService" />  
        </property> 
    </bean>

</beans>

这是Web服务bean的代码......

package com.eks.sel.web.service;

import java.util.Map;

import javax.inject.Inject;
import javax.jws.WebMethod;
import javax.jws.WebService;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.eks.sel.controller.PageRenderConstant;
import com.eks.sel.service.IUserService;
import com.eks.sel.service.bean.SELUserVO;
import com.eks.sel.web.service.bean.AuthenticateUserReq;
import com.eks.sel.web.service.bean.AuthenticateUserRes;


@Service("authenticateUserWS")
@WebService
public class AuthenticateUserWS {


    public static final Logger LOGGER = Logger.getLogger(AuthenticateUserWS.class);

    /**
     * USER SERVICE DI : TO CALL AUTHENTICATE SERVICE
     */     

    /*@Autowired
    private IUserService userService;

    public IUserService getUserService() {
        return userService;
    }

    public void setUserService(IUserService userService) {
        this.userService = userService;
    }*/


    public IUserService userService;

    @Inject
    public AuthenticateUserWS(IUserService userService){
        this.userService = userService;
    }


    /**
     * WEB SERVICE USED TO AUTHENTICATE USER
     * @param req
     * @return
     */
    @WebMethod
    public AuthenticateUserRes authenticateUser(AuthenticateUserReq req){
        AuthenticateUserRes resp = null;
        try{
            if(this.userService==null){
                resp = new AuthenticateUserRes();
                resp.setRespCode(false);
                resp.setRespMessage("Injection Failed");
            }else if(req.getUserName()!=null && req.getPassword()!=null && req.getUserName().trim().length()>0
                    && req.getPassword().trim().length()>0){


                //CALL AUTHENTICATE SERVICE
                Map respMap = userService.checkUserCredential(req.getUserName(),req.getPassword());

                if(respMap!=null && respMap.get(PageRenderConstant.USER_VO)!=null){
                    SELUserVO userVo =(SELUserVO) respMap.get(PageRenderConstant.USER_VO);

                    //PREPARE RESPONSE WITH SUCCESS MESSAGE
                    resp = new AuthenticateUserRes();
                    resp.setRespCode(true);
                    resp.setRespMessage("VALID USER");
                    resp.setStoreCode(userVo.getSiteId());
                    resp.setStoreDesc(userVo.getSiteName());

                }else{
                    //PREPARE RESPONSE WITH ERROR
                    resp = new AuthenticateUserRes();
                    resp.setRespCode(false);
                    resp.setRespMessage("Invalid username OR Password");
                }
            }else{
                //PREPARE RESPONSE WITH ERROR
                resp = new AuthenticateUserRes();
                resp.setRespCode(false);
                resp.setRespMessage("Please provide valid username OR password");
            }           

        }catch(Exception ex){
            LOGGER.fatal("Exception generated in authenticate user web service : ",ex);

            //PREPARE RESPONSE WITH ERROR
            resp = new AuthenticateUserRes();
            resp.setRespCode(false);
            resp.setRespMessage("Error while validation : "+ex.getMessage());
        }
        return resp;
    }

}

这是我的 web.xml 文件...

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">

    <!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:/META-INF/spring/root-context.xml</param-value>
    </context-param>

    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>com.eks.sel.listener.SELApplicationListener</listener-class>
    </listener>

    <!-- SPRING HANDLER FOR DISPATCHING REQUEST -->
    <servlet>
        <servlet-name>selsad</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:/META-INF/spring/selsad/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>selsad</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>




    <!-- SERVLET FOR WEB SERVICE REQUEST PROCESSING -->
    <servlet>
        <servlet-name>spring-ws</servlet-name>
        <!-- <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class> -->
        <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
        <!-- <servlet-class>com.sun.xml.ws.transport.http.servlet.WSSpringServlet</servlet-class> -->        
        <init-param>
            <param-name>transformWsdlLocations</param-name>
            <param-value>true</param-value>
        </init-param>        
    </servlet>  

    <servlet-mapping>
        <servlet-name>spring-ws</servlet-name>
        <url-pattern>*.wsdl</url-pattern>
    </servlet-mapping>


    <!-- PROJECT DISPLAY NAME -->
    <display-name>SELSAD</display-name>

    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>


    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

</web-app>

这是我的 root-context.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"   
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!-- Root Context: defines shared resources accessible to all other web components -->

    <!-- Property Config -->
    <import resource="property-config.xml"/>

    <!-- Database and Transaction Config -->
    <import resource="database-config.xml"/>

    <!-- SERVICE MODULE -->
    <context:component-scan base-package="com.eks.sel.service" />

    <!-- DAO MODULE -->
    <context:component-scan base-package="com.eks.sel.dao" />

    <!-- Mail Config -->
    <import resource="mail-config.xml"/>    

    <!-- Scheduler Config -->
    <import resource="scheduler-config.xml"/>

    <!-- Scheduler Config -->
    <import resource="scheduler-config-domain.xml"/>


    <!-- Web Service Config -->
    <import resource="sel-ws-config.xml"/>

</beans>

包括“ UserService ”在内的所有服务都写在com.eks.sel.service包下。 sel-ws-config.xml是我上面提到的网络服务配置文件。

这是我的 userService bean,我在 Web 服务中使用它来验证用户..

package com.eks.sel.service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.RandomUtils;
import org.springframework.stereotype.Service;

import com.eks.sel.controller.PageRenderConstant;
import com.eks.sel.dao.IConceptDAO;
import com.eks.sel.dao.ISiteDAO;
import com.eks.sel.dao.IUserDAO;
import com.eks.sel.model.Concept;
import com.eks.sel.model.Site;
import com.eks.sel.model.User;
import com.eks.sel.service.bean.SELUserVO;
import com.eks.sel.util.SELUtil;


@Service("userService")
public class UserService implements IUserService {

    private IUserDAO userDAO;

    private ISiteDAO siteDAO;

    private IConceptDAO conceptDAO;

    /**
     * @param userDAO
     */
    @Inject
    public UserService(IUserDAO userDAO, IConceptDAO conceptDAO , ISiteDAO siteDAO) {       
        this.userDAO = userDAO;
        this.siteDAO = siteDAO;
        this.conceptDAO = conceptDAO;
    }

    @Override
    public Map checkUserCredential(String UserId, String password) {
        User user = this.userDAO.findById(UserId);
        Map userMap = new HashMap();        
        String result="INVALID";

        if(null!=user){
            if(null!=password && !"".equals(password) && password.equals(user.getPassword())){
                result="VALID";
                userMap.put(PageRenderConstant.USER_VO, getSelUserVo(user));
            }
        }
        userMap.put(PageRenderConstant.USER_LOGIN_MSG_KEY, result);
        return userMap;
    }



}

使用依赖注入时出现以下异常...

org.apache.catalina.LifecycleException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.sun.xml.ws.transport.http.servlet.SpringBinding#0' defined in class path resource [META-INF/spring/sel-ws-config.xml]: Cannot create inner bean '(inner bean)' of type [org.jvnet.jax_ws_commons.spring.SpringService] while setting bean property 'service'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': FactoryBean threw exception on object creation; nested exception is javax.xml.ws.WebServiceException: Unable to create JAXBContext
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:5389)
    at com.sun.enterprise.web.WebModule.start(WebModule.java:498)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:917)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:901)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:733)
    at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:2000)
    at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1651)
    at com.sun.enterprise.web.WebApplication.start(WebApplication.java:109)
    at org.glassfish.internal.data.EngineRef.start(EngineRef.java:130)
    at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:269)
    at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:294)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:462)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)
    at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:382)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:355)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:370)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1045)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:96)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1244)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1232)
    at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:459)
    at com.sun.enterprise.v3.admin.AdminAdapter.service(AdminAdapter.java:209)
    at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:168)
    at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:117)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:238)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
    at java.lang.Thread.run(Thread.java:619)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.sun.xml.ws.transport.http.servlet.SpringBinding#0' defined in class path resource [META-INF/spring/sel-ws-config.xml]: Cannot create inner bean '(inner bean)' of type [org.jvnet.jax_ws_commons.spring.SpringService] while setting bean property 'service'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': FactoryBean threw exception on object creation; nested exception is javax.xml.ws.WebServiceException: Unable to create JAXBContext
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:281)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:125)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1325)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1086)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
    at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:4750)
    at com.sun.enterprise.web.WebModule.contextListenerStart(WebModule.java:550)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:5366)
    ... 38 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': FactoryBean threw exception on object creation; nested exception is javax.xml.ws.WebServiceException: Unable to create JAXBContext
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:149)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:109)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:274)
    ... 56 more
Caused by: javax.xml.ws.WebServiceException: Unable to create JAXBContext
    at com.sun.xml.ws.model.AbstractSEIModelImpl.createJAXBContext(AbstractSEIModelImpl.java:171)
    at com.sun.xml.ws.model.AbstractSEIModelImpl.postProcess(AbstractSEIModelImpl.java:99)
    at com.sun.xml.ws.model.RuntimeModeler.buildRuntimeModel(RuntimeModeler.java:250)
    at com.sun.xml.ws.server.EndpointFactory.createSEIModel(EndpointFactory.java:343)
    at com.sun.xml.ws.server.EndpointFactory.createEndpoint(EndpointFactory.java:205)
    at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:513)
    at org.jvnet.jax_ws_commons.spring.SpringService.getObject(SpringService.java:333)
    at org.jvnet.jax_ws_commons.spring.SpringService.getObject(SpringService.java:45)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142)
    ... 58 more
Caused by: java.security.PrivilegedActionException: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
com.eks.sel.service.IUserService is an interface, and JAXB can't handle interfaces.
    this problem is related to the following location:
        at com.eks.sel.service.IUserService
        at public com.eks.sel.service.IUserService com.eks.sel.web.service.jaxws.SetUserService.arg0
        at com.eks.sel.web.service.jaxws.SetUserService
com.eks.sel.service.IUserService does not have a no-arg default constructor.
    this problem is related to the following location:
        at com.eks.sel.service.IUserService
        at public com.eks.sel.service.IUserService com.eks.sel.web.service.jaxws.SetUserService.arg0
        at com.eks.sel.web.service.jaxws.SetUserService
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.xml.ws.model.AbstractSEIModelImpl.createJAXBContext(AbstractSEIModelImpl.java:158)
    ... 66 more
Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
com.eks.sel.service.IUserService is an interface, and JAXB can't handle interfaces.
    this problem is related to the following location:
        at com.eks.sel.service.IUserService
        at public com.eks.sel.service.IUserService com.eks.sel.web.service.jaxws.SetUserService.arg0
        at com.eks.sel.web.service.jaxws.SetUserService
com.eks.sel.service.IUserService does not have a no-arg default constructor.
    this problem is related to the following location:
        at com.eks.sel.service.IUserService
        at public com.eks.sel.service.IUserService com.eks.sel.web.service.jaxws.SetUserService.arg0
        at com.eks.sel.web.service.jaxws.SetUserService
    at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:106)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:466)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:298)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:141)
    at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1157)
    at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:188)
    at com.sun.xml.bind.api.JAXBRIContext.newInstance(JAXBRIContext.java:111)
    at com.sun.xml.ws.developer.JAXBContextFactory$1.createJAXBContext(JAXBContextFactory.java:113)
    at com.sun.xml.ws.model.AbstractSEIModelImpl$1.run(AbstractSEIModelImpl.java:166)
    at com.sun.xml.ws.model.AbstractSEIModelImpl$1.run(AbstractSEIModelImpl.java:159)
    ... 68 more

我无法理解这个问题。如果它是 servlet 的 bcoz 或其他问题生成的?

4

1 回答 1

1

您还没有真正发布您的完整配置(例如 web.xml)和/或您的问题到底是什么。另外,我不确定您所说的“自下而上”原则是什么意思。

对于 Web 服务设计,我们通常谈论“契约优先”或“代码优先”的方法,每一种都如其名称所暗示的那样:

  • 首先编写您的合同(wsdl + xsd),然后创建符合该合同的代码,或者相反
  • 首先编写您的代码(将服务公开为 Web 服务),然后从中创建(通常而不是编写只是自动生成)合同

说到 Spring,有一个由 Spring 家伙创建的 Web 服务框架,称为Spring Web Services,它大力提倡契约优先的方法。另一个流行的选择是CXF,它是一个非常成熟的框架,由 Apache 基金会的优秀程序员开发,具有一流的 Spring 支持。这真的取决于你选择哪一个。(也许如果您是初学者,CXF 可能更适合您使用代码优先方法,但是 CXF 也支持契约优先,对于更复杂的场景,这绝对是必经之路)

使用 Spring Web 服务的分步教程:http: //static.springsource.org/spring-ws/sites/2.0/reference/html/tutorial.html

如何使用 CXF:http ://cxf.apache.org/docs/writing-a-service-with-spring.html

于 2013-02-07T08:30:22.607 回答