【问题标题】:Can I use SOAP Webservices and Spring MVC together我可以一起使用 SOAP Webservices 和 Spring MVC
【发布时间】:2013-06-12 22:27:06
【问题描述】:

我有一个 Spring MVC 项目。我写了一个类似的代码

@Controller
@RequestMapping("CallBack")
@WebService(name = "NotificationToCP", targetNamespace = "http://SubscriptionEngine.ibm.com")
public class CallbackController {

    @RequestMapping("")
    @ResponseBody
    @WebMethod(action = "notificationToCP")
    @RequestWrapper(localName = "notificationToCP", targetNamespace = "http://SubscriptionEngine.ibm.com", className = "in.co.mobiz.airtelVAS.model.NotificationToCP_Type")
    @ResponseWrapper(localName = "notificationToCPResponse", targetNamespace = "http://SubscriptionEngine.ibm.com", className = "in.co.mobiz.airtelVAS.model.NotificationToCPResponse")
    public NotificationToCPResponse index(
            @WebParam(name = "notificationRespDTO", targetNamespace = "") CPNotificationRespDTO notificationRespDTO) {
        return new NotificationToCPResponse();
    }
}

我可以同时使用 Spring MVC + Webservices 吗?我想要的只是一个接受 SOAP 请求并处理它的控制器。 url 需要是 /CallBack。作为一个新手,我仍然有点困惑。会不会像上面那样工作。否则我该怎么办。

【问题讨论】:

  • 这可能会奏效。 (“可能”是因为我从未尝试过,但由于这些只是注释,它们不会产生副作用:不认识它们的人只会忽略它们。)请注意将处理 SOAP 请求的实例与处理 Spring MVC 请求的实例不同。
  • 你有示例程序吗?可以分享一下吗?

标签: java web-services spring


【解决方案1】:

我不会将 Spring MVC 和 SOAP webservice (JAX-WS) 混合在一起,因为它们的用途不同。

更好的做法是将您的业务操作封装在一个服务类中,并使用 MVC 控制器和 JAX-WS 将其公开。例如:

HelloService

@Service
public class HelloService {
    public String sayHello() {
        return "hello world";
    }
}

HelloController 通过自动装配注入了 HelloService 引用。这是标准的 Spring MVC 控制器,它调用服务并将结果作为模型传递给视图(例如:hello.jsp 视图)

@Controller
@RequestMapping("/hello")
public class HelloController {
    @Autowired private HelloService helloService;

    @RequestMapping(method = RequestMethod.GET)
    public String get(Model model) {
        model.addAttribute("message", helloService.sayHello());
        return "hello";
    }
}

JAX-WS 端点也调用相同的服务。不同之处在于服务公开为 SOAP Web 服务

@WebService(serviceName="HelloService")
public class HelloServiceEndpoint {
    @Autowired private HelloService helloService;

    @WebMethod
    public String sayHello() {
        return helloService.sayHello();
    }
}

请注意,上述 JAX-WS 样式的 Web 服务不能保证在所有 Spring 部署中自动运行,尤其是在部署在非 Java EE 环境 (tomcat) 上时。可能需要额外的设置。

【讨论】:

    【解决方案2】:

    是的,您可能希望将 Web 服务端点添加到现有 Spring MVC 应用程序中是有原因的。问题是您可能需要为每个路径设置不同的路径,这很好。

    您将需要两个 servlet,一个用于处理 HTTP/MVC 的标准调度程序 servlet 和一个用于处理 SOAP 调用的 MessageDispatcherServlet。

    配置可能很棘手。首先要明白,当你添加 Spring-ws 依赖时,你会遇到与 Spring MVC 的依赖不匹配。您需要在 pom 中排除 Spring-web,如下所示:

    <dependency>
        <groupId>org.springframework.ws</groupId>
        <artifactId>spring-ws-core</artifactId>
        <version>2.2.1.RELEASE</version>
        <exclusions>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    

    处理完这些后,您需要添加两个 servlet,一个通过 Spring MVC 处理 Web 请求,一个用于处理 SOAP。

    我假设使用 Spring 4 的 no-xml 配置,SpringBoot 也是可能的。

    这是您将添加到 Web 初始化程序的关键代码:

    DispatcherServlet servlet = new DispatcherServlet();
    
    // no explicit configuration reference here: everything is configured in the root container for simplicity
    servlet.setContextConfigLocation("");
    
    /* TMT From Java EE 6 API Docs:
     * Registers the given servlet instance with this ServletContext under the given servletName.
     * The registered servlet may be further configured via the returned ServletRegistration object. 
     */
    
    ServletRegistration.Dynamic appServlet = servletContext.addServlet("appServlet", servlet);
    appServlet.setLoadOnStartup(1);
    appServlet.setAsyncSupported(true);
    
    Set<String> mappingConflicts = appServlet.addMapping("/web/*");
    
    MessageDispatcherServlet mds = new MessageDispatcherServlet();
    mds.setTransformWsdlLocations(true);
    mds.setApplicationContext(context);
    mds.setTransformWsdlLocations(true);
    
    ServletRegistration.Dynamic mdsServlet = servletContext.addServlet("mdsServlet", mds);
    mdsServlet.addMapping("/wsep/*");
    mdsServlet.setLoadOnStartup(2);
    mdsServlet.setAsyncSupported(true);
    

    这就是它的全部内容。配置的其余部分是标准的东西,可以在任意数量的示例中找到。

    例如,您可以轻松地将 Spring MVC 和 Spring-WS 的 Spring IO 示例混合为测试平台。只要确保您相应地设置了WebMvcConfigurerAdapterWsConfigurerAdapter。它们将是两个独立的类,分别用@Configuration @EnableWebMvc@EnableWs @Configuration 进行注释。它们必须与您的 @Endpoint 类一起添加到组件扫描中。

    使用浏览器编译、运行和测试通过/web/* 关闭根上下文的MVC 内容,并使用SoapUI 通过导入WSDL 并点击根目录下的/wsep/* 进行SOAP 调用。每个 servlet 处理的每个路径。

    【讨论】:

    • 如何在示例中定义上下文?为每个 servlet 定义单独的 bean 的最佳方法是什么?
    猜你喜欢
    • 1970-01-01
    • 2016-02-12
    • 1970-01-01
    • 2018-03-20
    • 2011-05-03
    • 1970-01-01
    • 2022-08-20
    • 1970-01-01
    • 2011-11-30
    相关资源
    最近更新 更多