복붙노트

[SPRING] Spring REST 서비스 : 요청에서 JSON 검색하기

SPRING

Spring REST 서비스 : 요청에서 JSON 검색하기

Spring 3.1에서 REST 서비스를 빌드하고있다. 내가 그것에 대한 @EnableWebMVC 주석을 사용하고 있습니다. 내 서비스는 JSON 요청 만 받아들이므로 들어오는 요청을 MongoDB 컬렉션에 덤프하여 (나중에 데이터 변환을 위해) 덤프하고 싶습니다. 원시 JSON 요청 (메서드 매개 변수로 "@Content HttpServletRequest 요청"을 사용하여 비 스프링 구현에서 수행 할 수 있음)에 액세스하려고합니다.

나는 봄의 초보자이다. 그러니 친절하게 도와주세요. 감사!

업데이트 : 문제가 완전히 해결되지 않았습니다. 오직 GET을 사용한 나의 테스트 만이 효과가있었습니다. POST와 함께 실패합니다. 따라서 승인 된 답변의 선택을 취소했습니다.

문제는 HttpServletRequestWrapper를 생성하더라도 요청을 처리하고 래핑 한 후에 요청을 전달할 수 없다는 것입니다. 다음과 같이됩니다.

인터셉터 :

public class DBLogInterceptor extends HandlerInterceptorAdapter {
    MyRequestWrapper requestWrapper;

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

    @Override
    public boolean preHandle(
            HttpServletRequest request,
            HttpServletResponse response,
            Object handler) throws Exception 
    {
        requestWrapper = new MyRequestWrapper(request);
        // Code removed, but it just dumps requestWrapper.getBody() into DB
        return super.preHandle(requestWrapper, response, handler);
    }
}

HTTP POST 서비스 방법

@RequestMapping(method = RequestMethod.POST, consumes="application/json", produces="application/json", value = "employee")
@ResponseBody
public String updateEntity(@RequestBody Employee emp) {
    // Do some DB Stuff. Anyway, the control flow does not reach this place.
    return "Employee " + emp.getName() + " updated successfully!";
}

이제 POST를 보낼 때마다 예외가 발생합니다.

12:04:53,821 DEBUG DBLogInterceptor:22 - {"name":"Van Damme","dept":"Applied Martial Arts"}
12:04:53,843 DEBUG RequestResponseBodyMethodProcessor:117 - Reading [com.test.webapp.login.domain.Employee] as "application/json" using [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter@154174f9]
12:04:53,850 DEBUG ExceptionHandlerExceptionResolver:132 - Resolving exception from handler [public java.lang.String com.test.webapp.controller.EmployeeService.updateEntity(com.test.webapp.login.domain.Employee)]: java.io.IOException: Stream closed
12:04:53,854 DEBUG ResponseStatusExceptionResolver:132 - Resolving exception from handler [public java.lang.String com.test.webapp.controller.EmployeeService.updateEntity(com.test.webapp.login.domain.Employee)]: java.io.IOException: Streamclosed
12:04:53,854 DEBUG DefaultHandlerExceptionResolver:132 - Resolving exception from handler [public java.lang.String com.test.webapp.controller.EmployeeService.updateEntity(com.test.webapp.login.domain.Employee)]: java.io.IOException: Streamclosed
12:04:53,859 DEBUG DispatcherServlet:910 - Could not complete request
java.io.IOException: Stream closed
        at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:312)
        at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:200)
        at org.codehaus.jackson.impl.ByteSourceBootstrapper.ensureLoaded(ByteSourceBootstrapper.java:507)
        at org.codehaus.jackson.impl.ByteSourceBootstrapper.detectEncoding(ByteSourceBootstrapper.java:129)
        at org.codehaus.jackson.impl.ByteSourceBootstrapper.constructParser(ByteSourceBootstrapper.java:224)
        at org.codehaus.jackson.JsonFactory._createJsonParser(JsonFactory.java:785)
        at org.codehaus.jackson.JsonFactory.createJsonParser(JsonFactory.java:561)
        at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1914)
        at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readInternal(MappingJacksonHttpMessageConverter.java:124)
        at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:153)
        at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:120)
        at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:91)
        at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:71)
        at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:75)
        at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:156)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:117)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

HttpServletRequestWrapper가 요청 캐싱을 처리 할 것으로 예상했습니다. 그러나 그것은 어떻게 든 일어나지 않습니다.

해결법

  1. ==============================

    1.HttpServletRequest 객체를 사용하면 클라이언트가 요청에 사용한 URL, 사용 된 메소드 (GET, POST, PUT 등), 쿼리 문자열 및 헤더에 액세스 할 수 있습니다.

    HttpServletRequest 객체를 사용하면 클라이언트가 요청에 사용한 URL, 사용 된 메소드 (GET, POST, PUT 등), 쿼리 문자열 및 헤더에 액세스 할 수 있습니다.

    RequestBody를 얻는 것은 다소 번거롭고 HttpServletRequestWrapper 객체를 사용해야 할 수도 있습니다. 요청 본문은 한 번만 읽을 수 있기 때문에 대상 컨트롤러가 POONO 객체로 JSON을 deserialize하기 위해 나중에 액세스 할 수 있도록 액세스하기 위해 래퍼를 확장해야합니다.

    public class MyRequestWrapper extends HttpServletRequestWrapper {
     private final String body;
     public MyRequestWrapper(HttpServletRequest request) throws IOException {
       super(request);
       StringBuilder stringBuilder = new StringBuilder();
       BufferedReader bufferedReader = null;
       try {
         InputStream inputStream = request.getInputStream();
         if (inputStream != null) {
           bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
           char[] charBuffer = new char[128];
           int bytesRead = -1;
           while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
             stringBuilder.append(charBuffer, 0, bytesRead);
           }
         } else {
           stringBuilder.append("");
         }
       } catch (IOException ex) {
           throw ex;
       } finally {
         if (bufferedReader != null) {
           try {
             bufferedReader.close();
           } catch (IOException ex) {
             throw ex;
           }
         }
       }
       body = stringBuilder.toString();
     }
    
     @Override
     public ServletInputStream getInputStream() throws IOException {
       final ByteArrayInputStream byteArrayInputStream = new     ByteArrayInputStream(body.getBytes());
       ServletInputStream servletInputStream = new ServletInputStream() {
         public int read() throws IOException {
           return byteArrayInputStream.read();
         }
       };
       return servletInputStream;
     }
    
     @Override
     public BufferedReader getReader() throws IOException {
       return new BufferedReader(new InputStreamReader(this.getInputStream()));
     }
    
     public String getBody() {
       return this.body;
     }
    }
    

    중앙 위치에서 요청에 액세스하려면 필터 또는 Spring 인터셉터를 사용할 수 있습니다. 이 두 가지 모두 요청이 컨트롤러에 위임되기 전에 호출되며 둘 다 서블릿에 대한 액세스 권한을가집니다.

    다음은 Spring 인터셉터를 사용하는 실제 로깅 예제입니다.

    package com.vaannila.interceptor;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.apache.log4j.BasicConfigurator;
    import org.apache.log4j.Logger;
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.handler. HandlerInterceptorAdapter;
    
    public class LoggerInterceptor extends HandlerInterceptorAdapter {
        static Logger logger = Logger.getLogger(LoggerInterceptor.class);
    
        static {
            BasicConfigurator.configure();
        }
    
        @Override
    
        public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
    
            logger.info("Before handling the request");
            return super.preHandle(request, response, handler);
        }
    
        @Override
        public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
                ModelAndView modelAndView) throws Exception {
    
            logger.info("After handling the request");
            super.postHandle(request, response, handler, modelAndView);
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
                throws Exception {
    
            logger.info("After rendering the view");
            super.afterCompletion(request, response, handler, ex);
        }
    }
    
    
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="viewResolver" class="org.springframework.web.servlet.view.    InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />
    
        <bean id="handlerMapping" class="org.springframework.web.servlet.handler. BeanNameUrlHandlerMapping" p:interceptors-ref="loggerInterceptor" />
    
        <bean id="loggerInterceptor" class="com.vaannila.interceptor.LoggerInterceptor" />
    
        <bean id="userService" class="com.vaannila.service.UserServiceImpl" />
    
        <bean name="/userRegistration.htm" class="com.vaannila.web.UserController" p:userService-ref="userService" p:formView="userForm" p:successView="userSuccess" />
    
    </beans>
    

    LoggerInterceptor에서 다음 코드를 사용하여 요청에 액세스 할 수 있습니다.

    MyRequestWrapper myRequestWrapper = new MyRequestWrapper((HttpServletRequest) request);
    
    String body = myRequestWrapper.getBody();
    String clientIP = myRequestWrapper.getRemoteHost();
    int clientPort = request.getRemotePort();
    String uri = myRequestWrapper.getRequestURI();
    
    System.out.println(body);
    System.out.println(clientIP);
    System.out.println(clientPort);
    System.out.println(uri);
    
  2. ==============================

    2.HttpServletRequestWrapper가 작동 할 수 있는지 의심 스럽습니다 ... DispatcherServlet 구현을 살펴보십시오.

    HttpServletRequestWrapper가 작동 할 수 있는지 의심 스럽습니다 ... DispatcherServlet 구현을 살펴보십시오.

                HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();
                if (interceptors != null) {
                    for (int i = 0; i < interceptors.length; i++) {
                        HandlerInterceptor interceptor = interceptors[i];
                        if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {
                            triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
                            return;
                        }
                        interceptorIndex = i;
                    }
                }
    
                // Actually invoke the handler.
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
    

    "processedRequest"에 대한 참조를 여전히 전달합니다.이 요청은 스트림이 이미 읽힌 HttpServletRequest 요청을 나타냅니다.

  3. ==============================

    3.나는 이것이 오래된 질문이라는 것을 알고있다. 그러나 여전히 해결책을 찾고있는 당신들에게는 이것은 나를 위해 일했다.

    나는 이것이 오래된 질문이라는 것을 알고있다. 그러나 여전히 해결책을 찾고있는 당신들에게는 이것은 나를 위해 일했다.

    import java.io.BufferedReader;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.PrintWriter;
    import java.util.Collection;
    import java.util.Enumeration;
    import java.util.HashMap;
    import java.util.Locale;
    import java.util.Map;
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletInputStream;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    import javax.servlet.http.HttpServletResponse;
    import org.apache.commons.io.output.TeeOutputStream;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class HttpLoggingFilter implements Filter {
    
        private static final Logger logger = LoggerFactory.getLogger(HttpLoggingFilter.class);
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response,
                FilterChain chain) throws IOException, ServletException {
            try {
                HttpServletRequest httpServletRequest = (HttpServletRequest) request;
                HttpServletResponse httpServletResponse = (HttpServletResponse) response;
    
                Map<String, String> requestMap = this
                        .getTypesafeRequestMap(httpServletRequest);
                BufferedRequestWrapper bufferedRequest = new BufferedRequestWrapper(
                        httpServletRequest);
                BufferedResponseWrapper bufferedResponse = new BufferedResponseWrapper(
                        httpServletResponse);
    
                final StringBuilder logMessage = new StringBuilder(
                        "REST Request - ").append("[HTTP METHOD:")
                        .append(httpServletRequest.getMethod())
                        .append("] [PATH INFO:")
                        .append(httpServletRequest.getPathInfo())
                        .append("] [REQUEST PARAMETERS:").append(requestMap)
                        .append("] [REQUEST BODY:")
                        .append(bufferedRequest.getRequestBody())
                        .append("] [REMOTE ADDRESS:")
                        .append(httpServletRequest.getRemoteAddr()).append("]");
    
                chain.doFilter(bufferedRequest, bufferedResponse);
                logMessage.append(" [RESPONSE:")
                        .append(bufferedResponse.getContent()).append("]");
                logger.debug(logMessage.toString());
            } catch (Throwable a) {
                logger.error(a.getMessage());
            }
        }
    
        private Map<String, String> getTypesafeRequestMap(HttpServletRequest request) {
            Map<String, String> typesafeRequestMap = new HashMap<String, String>();
            Enumeration<?> requestParamNames = request.getParameterNames();
            while (requestParamNames.hasMoreElements()) {
                String requestParamName = (String) requestParamNames.nextElement();
                String requestParamValue = request.getParameter(requestParamName);
                typesafeRequestMap.put(requestParamName, requestParamValue);
            }
            return typesafeRequestMap;
        }
    
        @Override
        public void destroy() {
        }
    
        private static final class BufferedRequestWrapper extends
                HttpServletRequestWrapper {
    
            private ByteArrayInputStream bais = null;
            private ByteArrayOutputStream baos = null;
            private BufferedServletInputStream bsis = null;
            private byte[] buffer = null;
    
            public BufferedRequestWrapper(HttpServletRequest req)
                    throws IOException {
                super(req);
                // Read InputStream and store its content in a buffer.
                InputStream is = req.getInputStream();
                this.baos = new ByteArrayOutputStream();
                byte buf[] = new byte[1024];
                int read;
                while ((read = is.read(buf)) > 0) {
                    this.baos.write(buf, 0, read);
                }
                this.buffer = this.baos.toByteArray();
            }
    
            @Override
            public ServletInputStream getInputStream() {
                this.bais = new ByteArrayInputStream(this.buffer);
                this.bsis = new BufferedServletInputStream(this.bais);
                return this.bsis;
            }
    
            String getRequestBody() throws IOException {
                BufferedReader reader = new BufferedReader(new InputStreamReader(
                        this.getInputStream()));
                String line = null;
                StringBuilder inputBuffer = new StringBuilder();
                do {
                    line = reader.readLine();
                    if (null != line) {
                        inputBuffer.append(line.trim());
                    }
                } while (line != null);
                reader.close();
                return inputBuffer.toString().trim();
            }
    
        }
    
        private static final class BufferedServletInputStream extends
                ServletInputStream {
    
            private ByteArrayInputStream bais;
    
            public BufferedServletInputStream(ByteArrayInputStream bais) {
                this.bais = bais;
            }
    
            @Override
            public int available() {
                return this.bais.available();
            }
    
            @Override
            public int read() {
                return this.bais.read();
            }
    
            @Override
            public int read(byte[] buf, int off, int len) {
                return this.bais.read(buf, off, len);
            }
    
        }
    
        public class TeeServletOutputStream extends ServletOutputStream {
    
            private final TeeOutputStream targetStream;
    
            public TeeServletOutputStream(OutputStream one, OutputStream two) {
                targetStream = new TeeOutputStream(one, two);
            }
    
            @Override
            public void write(int arg0) throws IOException {
                this.targetStream.write(arg0);
            }
    
            public void flush() throws IOException {
                super.flush();
                this.targetStream.flush();
            }
    
            public void close() throws IOException {
                super.close();
                this.targetStream.close();
            }
        }
    
        public class BufferedResponseWrapper implements HttpServletResponse {
    
            HttpServletResponse original;
            TeeServletOutputStream tee;
            ByteArrayOutputStream bos;
    
            public BufferedResponseWrapper(HttpServletResponse response) {
                original = response;
            }
    
            public String getContent() {
                return bos.toString();
            }
    
            public PrintWriter getWriter() throws IOException {
                return original.getWriter();
            }
    
            public ServletOutputStream getOutputStream() throws IOException {
                if (tee == null) {
                    bos = new ByteArrayOutputStream();
                    tee = new TeeServletOutputStream(original.getOutputStream(),
                            bos);
                }
                return tee;
    
            }
    
            @Override
            public String getCharacterEncoding() {
                return original.getCharacterEncoding();
            }
    
            @Override
            public String getContentType() {
                return original.getContentType();
            }
    
            @Override
            public void setCharacterEncoding(String charset) {
                original.setCharacterEncoding(charset);
            }
    
            @Override
            public void setContentLength(int len) {
                original.setContentLength(len);
            }
    
            @Override
            public void setContentType(String type) {
                original.setContentType(type);
            }
    
            @Override
            public void setBufferSize(int size) {
                original.setBufferSize(size);
            }
    
            @Override
            public int getBufferSize() {
                return original.getBufferSize();
            }
    
            @Override
            public void flushBuffer() throws IOException {
                tee.flush();
            }
    
            @Override
            public void resetBuffer() {
                original.resetBuffer();
            }
    
            @Override
            public boolean isCommitted() {
                return original.isCommitted();
            }
    
            @Override
            public void reset() {
                original.reset();
            }
    
            @Override
            public void setLocale(Locale loc) {
                original.setLocale(loc);
            }
    
            @Override
            public Locale getLocale() {
                return original.getLocale();
            }
    
            @Override
            public void addCookie(Cookie cookie) {
                original.addCookie(cookie);
            }
    
            @Override
            public boolean containsHeader(String name) {
                return original.containsHeader(name);
            }
    
            @Override
            public String encodeURL(String url) {
                return original.encodeURL(url);
            }
    
            @Override
            public String encodeRedirectURL(String url) {
                return original.encodeRedirectURL(url);
            }
    
            @SuppressWarnings("deprecation")
            @Override
            public String encodeUrl(String url) {
                return original.encodeUrl(url);
            }
    
            @SuppressWarnings("deprecation")
            @Override
            public String encodeRedirectUrl(String url) {
                return original.encodeRedirectUrl(url);
            }
    
            @Override
            public void sendError(int sc, String msg) throws IOException {
                original.sendError(sc, msg);
            }
    
            @Override
            public void sendError(int sc) throws IOException {
                original.sendError(sc);
            }
    
            @Override
            public void sendRedirect(String location) throws IOException {
                original.sendRedirect(location);
            }
    
            @Override
            public void setDateHeader(String name, long date) {
                original.setDateHeader(name, date);
            }
    
            @Override
            public void addDateHeader(String name, long date) {
                original.addDateHeader(name, date);
            }
    
            @Override
            public void setHeader(String name, String value) {
                original.setHeader(name, value);
            }
    
            @Override
            public void addHeader(String name, String value) {
                original.addHeader(name, value);
            }
    
            @Override
            public void setIntHeader(String name, int value) {
                original.setIntHeader(name, value);
            }
    
            @Override
            public void addIntHeader(String name, int value) {
                original.addIntHeader(name, value);
            }
    
            @Override
            public void setStatus(int sc) {
                original.setStatus(sc);
            }
    
            @SuppressWarnings("deprecation")
            @Override
            public void setStatus(int sc, String sm) {
                original.setStatus(sc, sm);
            }
    
            @Override
            public String getHeader(String arg0) {
                return original.getHeader(arg0);
            }
    
            @Override
            public Collection<String> getHeaderNames() {
                return original.getHeaderNames();
            }
    
            @Override
            public Collection<String> getHeaders(String arg0) {
                return original.getHeaders(arg0);
            }
    
            @Override
            public int getStatus() {
                return original.getStatus();
            }
    
        }
    }
    

    그런 다음 web.xml에 필터를 등록하기 만하면됩니다. 모든 크레디트 : http://wetfeetblog.com/servlet-filer-to-log-request-and-response-details-and-payload/431 (방금 약간의 수정을했습니다).

  4. ==============================

    4.현재 spring-mvc repo에서 DispatcherServlet # doDispatch (...)에서 인터셉터가 호출됩니다.

    현재 spring-mvc repo에서 DispatcherServlet # doDispatch (...)에서 인터셉터가 호출됩니다.

    https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java

    ...
            if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                return;
            }
    
            try {
                // Actually invoke the handler.
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
            }
            finally {
                if (asyncManager.isConcurrentHandlingStarted()) {
                    return;
                }
            }
    
            applyDefaultViewName(request, mv);
            mappedHandler.applyPostHandle(processedRequest, response, mv);
    ...
    

    내 자신의 DispatcherServlet을 정의하고 doDispatch (...)를 재정 의하여 getInputStream ()에 ByteArrayInputStream이있는 HttpRequestWrapper를 삽입 할 수 있습니까?

    ...
    
    @Override
        protected void doDispatch(HttpServletRequest request, HttpServletResponse response)
                throws Exception {
    
            RequestWrapper wrappedRequest = new RequestWrapper(request);
            logger.debug("injecting RequestWrapper: " + wrappedRequest);
    
            super.doDispatch(wrappedRequest, response);
    
        }
    ...
    

    위의 상황에서이 방법이 효과가 있습니까?

  5. ==============================

    5.더 쉽게 재사용 할 수 있도록 타사 라이브러리에 의존하지 않고 Ouputstream 버전을 만듭니다. 이 2 래퍼 클래스를 사용하여 요청 및 응답 본문을 쉽게 얻을 수 있습니다. 그러나 어쨌든 요격기 대신에 필터를 사용해야합니다. 왜냐하면 @ user1323865에서 언급했듯이, spring 4에서는 processedRequest가 인터셉터와 핸들러에서 모두 사용되기 때문에 이러한 메소드를 인터셉터에 사용할 수 없습니다. Writer 버전을 대신 사용한다면이 링크에서 도움을 얻을 수 있습니다. 응답 본문 캡처 및 기록

    더 쉽게 재사용 할 수 있도록 타사 라이브러리에 의존하지 않고 Ouputstream 버전을 만듭니다. 이 2 래퍼 클래스를 사용하여 요청 및 응답 본문을 쉽게 얻을 수 있습니다. 그러나 어쨌든 요격기 대신에 필터를 사용해야합니다. 왜냐하면 @ user1323865에서 언급했듯이, spring 4에서는 processedRequest가 인터셉터와 핸들러에서 모두 사용되기 때문에 이러한 메소드를 인터셉터에 사용할 수 없습니다. Writer 버전을 대신 사용한다면이 링크에서 도움을 얻을 수 있습니다. 응답 본문 캡처 및 기록

    
    public class BufferedRequestWrapper extends HttpServletRequestWrapper
    {
        private static final class BufferedServletInputStream extends ServletInputStream
        {
            private ByteArrayInputStream bais;
    
            public BufferedServletInputStream(ByteArrayInputStream bais)
            {
                this.bais = bais;
            }
    
            @Override
            public int available()
            {
                return this.bais.available();
            }
    
            @Override
            public int read()
            {
                return this.bais.read();
            }
    
            @Override
            public int read(byte[] buf, int off, int len)
            {
                return this.bais.read(buf, off, len);
            }
    
        }
    
        private byte[] mBodyBuffer;
    
        public BufferedRequestWrapper(HttpServletRequest request) throws IOException
        {
            super(request);
    
            InputStream in = request.getInputStream();
    
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int bytesRead = -1;
            while ((bytesRead = in.read(buffer)) > 0)
            {
                baos.write(buffer, 0, bytesRead);
            }
            mBodyBuffer = baos.toByteArray();
        }
    
        public String getRequestBody()
        {
            return new String(mBodyBuffer, Charset.forName("UTF-8"));
        }
        @Override
        public BufferedReader getReader() throws IOException
        {
            return new BufferedReader(new InputStreamReader(this.getInputStream()));
        }
    
        @Override
        public ServletInputStream getInputStream()
        {
            ByteArrayInputStream in = new ByteArrayInputStream(mBodyBuffer);
            return new BufferedServletInputStream(in);
        }
    }
    
    
    public class BufferedResponseWrapper extends HttpServletResponseWrapper
    {
        private TeeServletOutputStream mTeeOutputStream;
    
        private static class TeeOutputStream extends OutputStream
        {
            private OutputStream mChainStream;
            private OutputStream mTeeStream;
    
            public TeeOutputStream(OutputStream chainStream, OutputStream teeStream)
            {
                mChainStream = chainStream;
                mTeeStream = teeStream;
            }
    
            @Override
            public void write(int b) throws IOException
            {
                mChainStream.write(b);
                mTeeStream.write(b);
                mTeeStream.flush();
            }
    
            @Override
            public void close() throws IOException
            {
                flush();
                mChainStream.close();
                mTeeStream.close();
            }
    
            @Override
            public void flush() throws IOException
            {
                mChainStream.close();
            }
        }
    
        public class TeeServletOutputStream extends ServletOutputStream
        {
            private final TeeOutputStream targetStream;
    
            public TeeServletOutputStream(OutputStream one, OutputStream two)
            {
                targetStream = new TeeOutputStream(one, two);
            }
    
            @Override
            public void write(int b) throws IOException
            {
                this.targetStream.write(b);
            }
    
            @Override
            public void flush() throws IOException
            {
                super.flush();
                this.targetStream.flush();
            }
    
            @Override
            public void close() throws IOException
            {
                super.close();
                this.targetStream.close();
            }
        }
    
        private ByteArrayOutputStream mByteArrayOutputStream;
    
        public BufferedResponseWrapper(HttpServletResponse response) throws IOException
        {
            super(response);
            mByteArrayOutputStream = new ByteArrayOutputStream();
            mTeeOutputStream = new TeeServletOutputStream(super.getResponse().getOutputStream(), mByteArrayOutputStream);
        }
    
        @Override
        public PrintWriter getWriter() throws IOException
        {
            return super.getResponse().getWriter();
        }
    
        @Override
        public ServletOutputStream getOutputStream() throws IOException
        {
            return mTeeOutputStream;
        }
    
        public String getResponseBody()
        {
            return mByteArrayOutputStream.toString();
        }
    
    }
    
  6. ==============================

    6.이봐, 이걸로해볼 수 있니?

    이봐, 이걸로해볼 수 있니?

    @RequestMapping(method = RequestMethod.POST, consumes="application/json", produces="application/json", value = "/employee")
    @ResponseBody
    public String updateEntity(@RequestBody Employee emp) {
        // Do some DB Stuff. Anyway, the control flow does not reach this place.
        return "Employee " + emp.getName() + " updated successfully!";
    }
    

    여기에서는 URI를 '/'로 증명하여 모든 작업을 수행 할 수 있습니다. 동일한 URI 값으로 업데이트를 가져오고 삭제할 수 있습니다.

  7. ==============================

    7.다음과 같이 requestWrapper를 구현해야합니다.

    다음과 같이 requestWrapper를 구현해야합니다.

    public class DocVerificationRequestWrapper extends HttpServletRequestWrapper {
     private final String body;
     public DocVerificationRequestWrapper(HttpServletRequest request) throws IOException {
       super(request);
       StringBuilder stringBuilder = new StringBuilder();
       BufferedReader bufferedReader = null;
       try {
         InputStream inputStream = request.getInputStream();
         if (inputStream != null) {
           bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
           char[] charBuffer = new char[128];
           int bytesRead = -1;
           while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
             stringBuilder.append(charBuffer, 0, bytesRead);
           }
         } else {
           stringBuilder.append("");
         }
       } catch (IOException ex) {
           throw ex;
       } finally {
         if (bufferedReader != null) {
           try {
             bufferedReader.close();
           } catch (IOException ex) {
             throw ex;
           }
         }
       }
       body = stringBuilder.toString();
     }
    
     @Override
     public ServletInputStream getInputStream() throws IOException {
       final ByteArrayInputStream byteArrayInputStream = new     ByteArrayInputStream(body.getBytes());
       ServletInputStream servletInputStream = new ServletInputStream() {
         public int read() throws IOException {
           return byteArrayInputStream.read();
         }
    
        @Override
        public boolean isFinished() {
            // TODO Auto-generated method stub
            return false;
        }
    
        @Override
        public boolean isReady() {
            // TODO Auto-generated method stub
            return false;
        }
    
        @Override
        public void setReadListener(ReadListener listener) {
            // TODO Auto-generated method stub
    
        }
       };
       return servletInputStream;
     }
    
     @Override
     public BufferedReader getReader() throws IOException {
       return new BufferedReader(new InputStreamReader(this.getInputStream()));
     }
    
     public String getBody() {
       return this.body;
     }
    }
    

    그리고 필터 클래스의 chain.doFilter 메소드 내부에서 다음과 같이 request 객체 대신 requestWrapper 객체를 전달합니다.

    @Override
    public void doFilter(ServletRequest arg0, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
    
        logger.info("checking token in filter");
        HttpServletRequest request = (HttpServletRequest) arg0;
    
        DocVerificationRequestWrapper myRequestWrapper = new DocVerificationRequestWrapper((HttpServletRequest) request);
    
        String body = myRequestWrapper.getBody();
        logger.info("body = "+body);
        Token token = null;
        try {
            JSONObject jsonObj = new JSONObject(body);
            JSONObject tokenObj = (JSONObject) jsonObj.get("token");
            Gson gson = new Gson();
            token = gson.fromJson(tokenObj.toString(), Token.class);
    
            if(null != token) {
                    if(userVerificationService==null){
                    ServletContext servletContext = request.getServletContext();
                    WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
                    userVerificationService = webApplicationContext.getBean(UserVerificationService.class);
                }
                    String verStatus = userVerificationService.verifyUser(token);
                    logger.info("verStatus = "+verStatus);
                    if(verStatus != null && verStatus.equalsIgnoreCase("success")) {
                        chain.doFilter(myRequestWrapper, response); //here replacing request with requestWrapper 
                    }else
                        logger.error("Invalid token");
            }else {
                    logger.error("token missing.");
            }
        } catch (JSONException e) {
                logger.error("exception in authetication filter " + e);
        }
    }
    

    따라서 IOStream을 해결하면 예외가 발생합니다.

  8. ==============================

    8.이렇게하는 간단한 방법은 요청 본문을 String으로 가져온 다음 Java 객체로 파싱하는 것입니다. 원하는 경우이 문자열을 사용할 수 있습니다.

    이렇게하는 간단한 방법은 요청 본문을 String으로 가져온 다음 Java 객체로 파싱하는 것입니다. 원하는 경우이 문자열을 사용할 수 있습니다.

    그래서 당신의 예제에서 :

    @RequestMapping(method = RequestMethod.POST, consumes="application/json", produces="application/json", value = "employee")
    @ResponseBody
    public String updateEntity(@RequestBody String empAsString) {
    
        // Do whatever with the json as String 
        System.out.println(empAsString);
    
        // Transform it into the Java Object you want
        ObjectMapper mapper = new ObjectMapper();
        Employee emp = mapper.readValue(empAsString, Employee.class);
    
        // Do some DB Stuff. Anyway, the control flow does not reach this place.
        return "Employee " + emp.getName() + " updated successfully!";
    }
    

    참고로, 목록으로 필요하면 다음을 사용할 수 있습니다.

    List<Employee> eventsList =
                    mapper.readValue(jsonInString, mapper.getTypeFactory().constructCollectionType(List.class, Employee.class));
    
  9. ==============================

    9.다음과 같이 간단하게 사용할 수 있습니다.

    다음과 같이 간단하게 사용할 수 있습니다.

    import org.apache.commons.io.IOUtils;
    import java.nio.charset.Charset;
    
    String requestBody = IOUtils.toString(request.getInputStream(), Charset.forName("UTF-8").toString());
    
  10. ==============================

    10.내 경험으로는 다음과 같이 개발하십시오. ServletRequest를 래퍼하기 위해 필터를 사용하면 반복적으로 요청 입력 스트림을 가져올 수 있습니다.

    내 경험으로는 다음과 같이 개발하십시오. ServletRequest를 래퍼하기 위해 필터를 사용하면 반복적으로 요청 입력 스트림을 가져올 수 있습니다.

  11. from https://stackoverflow.com/questions/10457963/spring-rest-service-retrieving-json-from-request by cc-by-sa and MIT license