1. 程式人生 > >SpringBoot + CXF快速實現SOAP WebService(支持Basic Auth)

SpringBoot + CXF快速實現SOAP WebService(支持Basic Auth)

9.png service 手動 1.8 項目 ref tina poi 攔截器

嘮叨兩句

講真,SOAP跟現在流行的RESTful WebService比起來顯得很難用。冗余的XML文本信息太多,可讀性差,它的請求信息有時很難手動構造,不太好調試。不過說歸說,對某些企業用戶來說SOAP的使用率仍然是很高的。

需求背景

接手維護的一個項目,最近客戶想開放項目中的功能給第三方調用,而且接入方指定必須是SOAP接口。這項目原來的代碼我看著頭疼,也不想再改了,除非推倒重寫。客戶的需求雖然不難但要的很急,為了盡快交付就使用SpringBoot快速搭一個微服務。

開始動手

1.新建一個Spring Starter Project
2.加入cxf的maven配置
    
<dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-spring-boot-starter-jaxws</artifactId> <version>3.1.15</version> </dependency>

編寫服務代碼(示例代碼)

@WebService(name = "UserService", targetNamespace="http://demo.example.com/")
public interface IUserService { @WebMethod User getUserById(@WebParam(name = "id") int id); int addUser(@WebParam(name = "user") User user); }
@InInterceptors(interceptors={"com.example.demo.auth.AuthInterceptor"})
@WebService(serviceName = "UserService", targetNamespace = "http://demo.example.com/", endpointInterface = "com.example.demo.soap.IUserService")
@Component
public class UserServiceImpl implements IUserService { private Logger logger = LoggerFactory.getLogger(UserServiceImpl.class); @Autowired private IUserDAO userDAO; @Override public User getUserById(int id) { return userDAO.getUserById(id); } @Override public int addUser(User user) { logger.info("save user [" + user.getId() + "]"); userDAO.addUser(user); return 0; } }

鑒權攔截器

@Component
public class AuthInterceptor extends AbstractSoapInterceptor {

    private static final String BASIC_PREFIX = "Basic ";
    private static final String USERNAME = "lichmama";
    private static final String PASSWORD = "123456";

    public AuthInterceptor() {
        super(Phase.PRE_INVOKE);
    }

    @Override
    public void handleMessage(SoapMessage message) throws Fault {
        HttpServletRequest request = (HttpServletRequest) message.get(AbstractHTTPDestination.HTTP_REQUEST);
        String auth = request.getHeader("Authorization");
        if (auth == null) {
            throw new IllegalArgumentException("auth failed, header [Authorization] not exists");
        }
        if (!auth.startsWith(BASIC_PREFIX)) {
            throw new IllegalArgumentException("auth failed, header [Authorization] is illegal");
        }
        String plaintext = new String(Base64.getDecoder().decode(auth.substring(BASIC_PREFIX.length())));
        if (StringUtils.isEmpty(plaintext) || !plaintext.contains(":")) {
            throw new IllegalArgumentException("auth failed, header [Authorization] is illegal");
        }
        String[] userAndPass = plaintext.split(":");
        String username = userAndPass[0];
        String password = userAndPass[1];
        if (!USERNAME.equals(username) || !PASSWORD.equals(password)) {
            throw new IllegalArgumentException("auth failed, username or password is incorrect");
        }
    }
}

編寫配置類

@Configuration
public class SoapConfig {

    @Autowired
    private IUserService userService;

    @Autowired
    @Qualifier(Bus.DEFAULT_BUS_ID)
    private SpringBus bus;

    @Bean
    public Endpoint endpoint() {
        EndpointImpl endpoint = new EndpointImpl(bus, userService);
        endpoint.publish("/userService");
        return endpoint;
    }
}

修改CXF默認發布路徑(application.properties)

server.port=8000
cxf.path=/soap

啟動項目後訪問http://localhost:8000/soap/userService?wsdl

技術分享圖片

使用SoapUI測試一下,看上去沒什麽問題

技術分享圖片

最後交代一下開發環境

STS 3.7.3 + SpringBoot 2.0.1 + JDK1.8

收工下班了。

SpringBoot + CXF快速實現SOAP WebService(支持Basic Auth)