You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot WS-Server自定义响应HTTP状态码实现求助(Spring Boot 2.2.7)

为Spring Boot WS SOAP服务设置自定义HTTP响应状态码

我之前也碰到过这种“不符合标准但业务必须”的需求,在Spring Boot 2.2.7版本的Spring WS里,确实有可行的实现方式,下面分享两个经过验证的方案:

方案一:自定义EndpointInterceptor拦截器(推荐)

通过Spring WS的拦截器机制,在响应发送前直接修改HTTP状态码,这是最灵活且侵入性最低的方式。

1. 实现自定义拦截器

创建一个实现EndpointInterceptor的类,在handleResponse方法中获取HTTP响应对象并设置状态码:

import org.springframework.ws.context.MessageContext;
import org.springframework.ws.server.EndpointInterceptor;
import org.springframework.ws.transport.context.TransportContext;
import org.springframework.ws.transport.context.TransportContextHolder;
import org.springframework.ws.transport.http.HttpServletConnection;

import javax.servlet.http.HttpServletResponse;

public class CustomSoapStatusInterceptor implements EndpointInterceptor {

    @Override
    public boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {
        return true; // 放行请求继续处理
    }

    @Override
    public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
        // 获取当前请求的HTTP连接上下文
        TransportContext transportContext = TransportContextHolder.getTransportContext();
        HttpServletConnection connection = (HttpServletConnection) transportContext.getConnection();
        HttpServletResponse response = connection.getHttpServletResponse();
        
        // 设置你需要的自定义状态码,比如SC_BAD_REQUEST(400)、SC_INTERNAL_SERVER_ERROR(500)
        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        return true;
    }

    @Override
    public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
        return true; // 处理Fault时也可根据需要设置状态码
    }

    @Override
    public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) throws Exception {
        // 可选:添加清理逻辑
    }
}

2. 注册拦截器到Spring WS配置

在你的Spring WS配置类中,将自定义拦截器加入拦截器列表:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ws.config.annotation.EnableWs;
import org.springframework.ws.config.annotation.WsConfigurerAdapter;
import org.springframework.ws.server.EndpointInterceptor;

import java.util.List;

@EnableWs
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter {

    // 你的其他配置,比如DefaultWsdl11Definition、EndpointMapping等...

    @Bean
    public EndpointInterceptor customSoapStatusInterceptor() {
        return new CustomSoapStatusInterceptor();
    }

    @Override
    public void addInterceptors(List<EndpointInterceptor> interceptors) {
        interceptors.add(customSoapStatusInterceptor());
        super.addInterceptors(interceptors);
    }
}

方案二:自定义MessageDispatcherServlet(底层控制)

如果拦截器无法满足需求(比如需要根据响应内容动态判断状态码),可以通过自定义Spring WS核心Servlet来实现更底层的控制:

1. 自定义Servlet类

继承MessageDispatcherServlet,重写doService方法,在父类处理完请求后修改状态码:

import org.springframework.ws.transport.http.MessageDispatcherServlet;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CustomWsDispatcherServlet extends MessageDispatcherServlet {

    @Override
    protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 先让父类处理SOAP请求和响应
        super.doService(request, response);
        
        // 这里可以根据请求参数、响应内容等动态设置状态码
        // 示例:如果响应包含SOAP Fault,设置500状态码
        // 你可以根据实际需求替换逻辑
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
    }
}

2. 注册自定义Servlet

在Spring Boot配置类中替换默认的MessageDispatcherServlet:

import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class WsServletConfig {

    @Bean
    public ServletRegistrationBean<CustomWsDispatcherServlet> customWsDispatcherServlet() {
        CustomWsDispatcherServlet servlet = new CustomWsDispatcherServlet();
        servlet.setTransformWsdlLocations(true); // 保持原有WS配置特性
        ServletRegistrationBean<CustomWsDispatcherServlet> registrationBean = new ServletRegistrationBean<>(servlet, "/ws/*");
        registrationBean.setLoadOnStartup(1);
        return registrationBean;
    }
}

注意事项

  • 这种修改HTTP状态码的做法确实不符合SOAP标准(SOAP规范中错误应该通过SOAP Fault消息体传递,而非HTTP状态码),请确认业务需求确实无法通过标准方式满足后再使用。
  • 如果之前尝试的方案没生效,大概率是没有正确获取到HttpServletResponse对象,或者拦截器注册顺序有问题,方案一中的拦截器注册方式是Spring WS推荐的正确方式。

内容的提问来源于stack exchange,提问作者BartekS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 15:07:47