2017-11-24 2 views
0

HTTP POST 요청을 통해받은 XML의 유효성을 Spring MVC 컨트롤러에 알려주고 싶지만 ServletFilter로 유효성을 검사해야합니다.자바 필터 입력 컨트롤러 이전의 XML

입력 스트림에서 DocumentBuilderFactory를 사용하는 데 아무런 문제가 없습니다. ServletFilter에서 입력을 올바르게 구문 분석하고 분석합니다.

내 필터를 넘겨 주면 디버거가 다양한 라이브러리 및 클래스에서 발생하는 것을 볼 수는 없지만 Spring Controller로 착륙 할 수 없으며 직접 "400 Bad Request"를 응답으로받습니다.없이

코드 행 (모든 이후의 구문 분석 및 XML 파일의 검증없이) 내 필터: 요청이 매핑 봄 컨트롤러에 문제없이 제공

Document doc = builder.parse(xml); 

객체에 대한 입력 XML은 RequestModel.java

라고하지만 필터의 구문 분석 및 유효성 검사를 추가 할 때, 탐색 블록 승, 컨트롤러에 착륙하기 전에 Exception을 던지면서. (탐색 전에 차단됩니다, 구문 분석과)

InputStream xml = request.getInputStream(); 
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
    try { 
     DocumentBuilder builder = factory.newDocumentBuilder(); 

     Document doc = builder.parse(xml); //ADDING THIS LINE IT FAILS! 

     //method continues with xml parsing and validation... 

이 내 컨트롤러 방법의 시작입니다 :

는 내 필터에 전화를 실패하게 조각입니다

@Controller 
@EnableSwagger2 
@RequestMapping("/listaprocessi") 
@Api(description = "Lista processi ammessi", tags="Lista processi") 
public class ListaProcessiController { 

    @RequestMapping(produces = MediaType.APPLICATION_XML_VALUE, consumes = MediaType.APPLICATION_XML_VALUE, method = RequestMethod.POST) 
    @ResponseBody 
    @ApiOperation(value="Lista processi") 
    public BusinessListaProcessiModel listaProcessi(@RequestBody RequestModel requestModel) throws RemoteException{ ...} 

필터가 스트림을 닫을 때까지 기다려야한다는 입력을 분석하기 때문입니까? 어떤 제안이 있으십니까?

답변

1

ServletInputStream은 한 번만 처리 할 수 ​​있습니다. 따라서 필터에서 처리 할 때 컨트롤러 용 Spring MVC 프레임 워크에서 처리 할 수 ​​없습니다.

나는이 여러 번 발생했습니다. 이 문제를 해결하기 위해 HttpServletRequest를 새로운 클래스 (아래 참조)에 랩핑하여 InputStream을 다시 읽도록합니다. 아래 클래스의 인스턴스에서 HttpServletRequest를 래핑하고 DocumentBuilder에서 사용하고 필터의 doFilter 메서드에 전달하면 좋은 결과를 얻을 수 있습니다.

public class CachingRequestWrapper extends HttpServletRequestWrapper { 

    private final String cachedMsgBody; 

    public CachingRequestWrapper(HttpServletRequest request) throws HttpErrorException { 
     super(request); 
     cachedMsgBody = ServletUtils.extractMsgBodyToString(request); 
    } 

    public CachingRequestWrapper(HttpServletRequest request, String msgBody) throws HttpErrorException { 
     super(request); 
     cachedMsgBody = msgBody; 
    } 

    public String getCachedMsgBody() { 
     return cachedMsgBody; 
    } 

    @Override 
    public BufferedReader getReader() throws IOException { 
     InputStreamReader isr = new InputStreamReader(new ByteArrayInputStream(cachedMsgBody.getBytes())); 
     return new BufferedReader(isr); 
    } 

    @Override 
    public ServletInputStream getInputStream() throws IOException { 
     ServletInputStream sis = new ServletInputStream() { 
      private int i = 0; 
      byte[] msgBodyBytes = cachedMsgBody.getBytes(); 

      @Override 
      public int read() throws IOException { 
       byte b; 
       if (msgBodyBytes.length > i) { 
        b = msgBodyBytes[i++]; 
       } else { 
        b = -1; 
       } 
       return b; 
      } 

      public boolean isFinished() { 
       return i == msgBodyBytes.length; 
      } 

      public boolean isReady() { 
       return true; 
      } 

      public void setReadListener(ReadListener rl) { 
       throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. 
      } 
     }; 

     return sis; 
    } 

} 

참조 : http://stackoverflow.com/a/6322667/1490322