简体   繁体   English

弹簧拦截器

[英]Spring Interceptor

I need to create an interceptor that will intercept HTTP requests and responses, but it seems to me that I'm doing something wrong, can someone tell me what I should change or add?我需要创建一个拦截器来拦截 HTTP 请求和响应,但在我看来我做错了什么,有人可以告诉我应该更改或添加什么吗?

public class HttpInterceptor extends HandlerInterceptorAdapter implements ClientHttpRequestInterceptor
{
    @Override
    public ClientHttpResponse intercept(final HttpRequest httpRequest, final byte[] bytes, final ClientHttpRequestExecution clientHttpRequestExecution) throws IOException
    {

        RestTemplate restTemplate = new RestTemplate();
        final ClientHttpResponse response = clientHttpRequestExecution.execute(httpRequest, bytes);
        final String httpResponseName = response.toString();

        final HttpHeaders httpHeaders = response.getHeaders();
        final HttpStatus httpStatusCode = response.getStatusCode();
        final String statusText = response.getStatusText();

        final String body = httpHeaders.toString() + httpStatusCode.toString() + statusText;
        //And then i will put body to DB

        return response;
    }

xml xml

<bean id="httpInterceptor" class="HttpInterceptor"/>
<bean id="httpInterceptor" class="de.hybris.platform.servicelayer.interceptor.impl.InterceptorMapping">
    <property name="interceptor" ref="httpInterceptor"/>
    <property name="typeCode" value="Message"/>
</bean>

I understood that you try to create service (it can be rest, soap or any other).我知道您尝试创建服务(可以是休息、肥皂或任何其他服务)。 If I am right, you need to create controller for handling http request.如果我是对的,您需要创建控制器来处理 http 请求。

@Controller("MyController")
public class MyController extends AbstractController {
    @RequestMapping(value = "/mymethod/{id}", method = RequestMethod.GET)
    public void myMethod(@PathVariable final String id, final HttpServletRequest request, final HttpServletResponse out) throws Exception {
    try {
        if (StringUtils.isEmpty(id))
            throw new UnknownIdentifierException("id is null!");
        out.setContentType(MediaType.APPLICATION_TXT_VALUE);
        IOUtils.copy(myStream, out.getOutputStream());
    } catch (UnknownIdentifierException ex) {
        out.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        out.setContentType(MediaType.TEXT_PLAIN_VALUE);
        String message = "My error text!";
        IOUtils.copy(new ByteArrayInputStream(message.getBytes()), out.getOutputStream());
    } 
}

I recommande to implements Filter to transform or use the information contained in the requests or responses.我建议实现 Filter 来转换或使用包含在请求或响应中的信息。 and not Interceptor , it provide more information then Interceptor Here's an exemple of the use of Filter for logging :而不是 Interceptor ,它提供更多信息然后 Interceptor 这是使用过滤器进行日志记录的示例:

@Component
public class HttpLoggingFilter implements Filter {

    private static final Logger logger = LoggerFactory.getLogger(HttpLoggingFilter.class);

    @Value("${output.trace.actif}")
    private boolean isOutputActif;

    private static String getRequestData(final HttpServletRequest request) throws UnsupportedEncodingException {

        String payload = null;
        ContentCachingRequestWrapper wrapper = WebUtils.getNativeRequest(request, ContentCachingRequestWrapper.class);
        if (wrapper != null) {
            byte[] buf = wrapper.getContentAsByteArray();
            if (buf.length > 0) {
                payload = new String(buf, 0, buf.length, wrapper.getCharacterEncoding());
            }
        }
        return payload;
    }

    private static String getResponseData(final HttpServletResponse response) throws IOException {

        String payload = null;
        ContentCachingResponseWrapper wrapper = WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class);
        if (wrapper != null) {
            byte[] buf = wrapper.getContentAsByteArray();
            if (buf.length > 0) {
                payload = new String(buf, 0, buf.length, wrapper.getCharacterEncoding());
                wrapper.copyBodyToResponse();
            }
        }
        return payload;
    }

    @Override
    public void init(FilterConfig filterConfig) {
        logger.info("start http filter");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;

        ContentCachingRequestWrapper requestToCache = new ContentCachingRequestWrapper(httpServletRequest);
        ContentCachingResponseWrapper responseToCache = new ContentCachingResponseWrapper(httpServletResponse);

        HttpUtil.majMDCRestInfo(httpServletRequest);

        long start = System.currentTimeMillis();

        chain.doFilter(requestToCache, responseToCache);

        long elapsedTime = System.currentTimeMillis() - start;

        String requestBody = new String(requestToCache.getContentAsByteArray());
        String responseBody = new String(responseToCache.getContentAsByteArray());

        final StringBuilder logMessage = new StringBuilder().append("[METHOD:").append(httpServletRequest.getMethod())
                .append("] [PARAMS:")
                .append(httpServletRequest.getQueryString()).append("] [BODY:").append(requestBody).append("]");

        if (isOutputActif) {
            String respContent = responseBody;
            if (respContent.equals("")) {
                respContent = "no data";
            }
            logMessage.append(" [RESPONSE:").append(respContent).append("]");
        }

        logMessage.append(" [STATUS:").append(responseToCache.getStatus()).append("] [Time:").append(elapsedTime).append("ms]");
        String[] nonLoggingPaths = {"/api/"};
        String urlPath = httpServletRequest.getRequestURL().toString();
        if ((Arrays.stream(nonLoggingPaths).parallel().anyMatch(urlPath::contains))) {
            logger.info("{}", logMessage);
        }

        getRequestData(requestToCache);
        getResponseData(responseToCache);
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM