Reputation: 2870
According to official Apache CXF documentation we create SOAP services in spring in such way:
Configuration class
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.xml.ws.Endpoint;
@Configuration
public class WebServiceConfiguration {
private static final String BINDING_URI = "http://www.w3.org/2003/05/soap/bindings/HTTP/";
@Bean
public ServletRegistrationBean<CXFServlet> disServlet() {
return new ServletRegistrationBean<>(new CXFServlet(), "/soap-api/*");
}
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
SpringBus bus = new SpringBus();
bus.setProperty("org.apache.cxf.stax.maxTextLength", 1024 * 1024 * 1024);
return bus;
}
@Bean
public Endpoint userServiceEndpoint(UserService userService) {
EndpointImpl endpoint = new EndpointImpl(springBus(), userService);
endpoint.setBindingUri(BINDING_URI);
endpoint.publish("/users");
return endpoint;
}
}
Generated from WSDL SOAP interface:
/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.3.2
* Generated source version: 2.2
*
*/
@WebService(name = "UserServiceSoap", targetNamespace = "http://User.no/webservices/")
@XmlSeeAlso({ObjectFactory.class})
public interface UserServiceSoap {
@WebMethod(operationName = "GetUser", action = "http://User.no/webservices/GetUser")
@WebResult(name = "GetUserResult", targetNamespace = "http://User.no/webservices/")
@RequestWrapper(localName = "UserServiceSoap", targetNamespace = "http://User.no/webservices/", className = "no.user.webservices.generated.UserServiceSoap")
@ResponseWrapper(localName = "UserServiceSoapResponse", targetNamespace = "http://User.no/webservices/", className = "no.user.webservices.generated.UserServiceSoapResponse")
public String getUser(@WebParam(name = "username", targetNamespace = "http://User.no/webservices/") String username);
}
Service implementation:
@Service
@WebService(
endpointInterface = "no.altinn.webservices.generated.UserServiceSoap",
serviceName = "UserServiceSoapService",
targetNamespace = "http://User.no/webservices/",
portName = "UserServiceSoapPort"
)
@BindingType("http://java.sun.com/xml/ns/jaxws/2003/05/soap/bindings/HTTP/")
public class UserService implements UserServiceSoap {
@Override
public String getUser(String requestUsername) {
//logic
}
}
What do I want?
Is there any already implemented way to publish SOAP endpoint without creating bean in the spring configuration. I want to do it with annotation on service implementation, for example (@SoapEndpoint):
@Service
@SoapEndpoint(bindingUri = "http://www.w3.org/2003/05/soap/bindings/HTTP/",
publish = "/users")
@WebService(
endpointInterface = "no.altinn.webservices.generated.UserServiceSoap",
serviceName = "UserServiceSoapService",
targetNamespace = "http://User.no/webservices/",
portName = "UserServiceSoapPort"
)
@BindingType("http://java.sun.com/xml/ns/jaxws/2003/05/soap/bindings/HTTP/")
public class UserService implements UserServiceSoap {
@Override
public String getUser(String requestUsername) {
//logic
}
}
Upvotes: 3
Views: 5432
Reputation: 13113
Workaround:
Create empty interface named SoapService
and @SoapEndpoint
and initialize endpoints
manually
SoapService interface:
public interface SoapService {
}
@SoapEndpoint interface:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface SoapEndpoint {
String bindingUri() default "http://www.w3.org/2003/05/soap/bindings/HTTP/";
String publish();
}
Initialize endpoints manually
@Configuration
public class WebServiceConfiguration {
private static final String BINDING_URI = "http://www.w3.org/2003/05/soap/bindings/HTTP/";
@Autowired
private List<SoapService> endpoints;
@Bean
public ServletRegistrationBean<CXFServlet> disServlet() {
return new ServletRegistrationBean<>(new CXFServlet(), "/soap-api/*");
}
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
SpringBus bus = new SpringBus();
bus.setProperty("org.apache.cxf.stax.maxTextLength", 1024 * 1024 * 1024);
return bus;
}
@PostConstruct
public void init() {
for (SoapService bean : endpoints) {
if (bean.getClass().getAnnotation(SoapEndpoint.class) == null) {
throw new IllegalArgumentException("Missed @SoapEndpoint for " + bean.getClass().getName());
}
EndpointImpl endpoint = new EndpointImpl(springBus(), bean);
endpoint.setBindingUri(BINDING_URI);
endpoint.publish(bean.getClass().getAnnotation(SoapEndpoint.class).publish());
}
}
}
Add SoapService
into you implementation classes
@Service
@SoapEndpoint(publish = "/users")
@WebService(endpointInterface = "no.altinn.webservices.generated.UserServiceSoap", serviceName = "UserServiceSoapService", targetNamespace = "http://User.no/webservices/", portName = "UserServiceSoapPort")
@BindingType("http://java.sun.com/xml/ns/jaxws/2003/05/soap/bindings/HTTP/")
public class UserService implements UserServiceSoap, SoapService {
@Override
public String getUser(String requestUsername) {
//logic
}
}
--- Result (I've added OrganitionService
which implements OrganizationServiceSoap
) ---
Upvotes: 2