2011-12-02 2 views
1

나는이 서비스를 편안하고 웹 서비스 아파치 CXF 설정 업로드 크기

를 만들기 위해 CXF 2.4.4을 사용하고 있습니다.

첨부 파일 크기를 제한하고 싶습니다. this documentation을 찾았습니다. 단, 작업 결과는 HTTP 500 status입니다.

다른 상태 (예 : HTTP 413 status)를 반환하는 방법을 알고 싶거나이 예외를 잡아서 다시 제기하는 방법을 알고 싶습니다.

편집
내가이

@Service("remote") 
@InInterceptors(interceptors = {"myCompany.AttachmentInInterceptor"}) 
public class RemoteImpl implements Remote { 
    ... 
} 

및 인터셉터처럼 인터셉터를 통해이 작업을 수행하기 위해 관리 :

public class AttachmentInInterceptor extends AbstractPhaseInterceptor<Message> { 

    public AttachmentInInterceptor() { 
     super(Phase.RECEIVE); 
    } 

    public void handleMessage(Message message) { 
     String contentType = (String) message.get(Message.CONTENT_TYPE); 
     Map<String, List<String>> headers; 

     if (contentType != null && contentType.toLowerCase().indexOf("multipart/form-data") >= 0) { 
      AttachmentDeserializer ad = new AttachmentDeserializer(message); 

      headers = (Map<String, List<String>>) message.get(Message.PROTOCOL_HEADERS); 
      String len = headers.get("Content-Length").toString(); 
      len = len.replaceAll("\\[", ""); 
      len = len.replaceAll("\\]", ""); 

      Long length = Long.valueOf(len); 
      if (length > 100000000) { 
       throw new Fault(new CustomException("Archivo grande", ErrorCode.ERROR.getCode())); 
      } 
      try { 
       ad.initializeAttachments(); 
      } catch (IOException e) { 
       throw new Fault(e); 
      } 
     } 
    } 

    @Override 
    public void handleFault(Message message) { 
    } 
} 

하지만 나는 여전히 필요한 응답을 보낼 수 없습니다 (HTTP 413 status)

사전에 도움을 주셔서 감사합니다.

답변

2

CXF source code을 검사하면 javax.ws.rs.WebApplicationException을 던져서 500이 아닌 결과가 반환됨을 알 수 있습니다. 그것은 RuntimeException 하위 클래스입니다. 따라서 선언 할 필요가 없습니다. 응답 코드를 취하는 하나의 인수로 구성된 생성자가 있습니다 (또는 Response을 구성하거나 실제로 멋지게 구성 할 수 있습니다).

+0

안녕하세요, 감사를 반환합니다. 나는 당신이 말한 것을 시도했지만, 클라이언트로부터 http 요청을 실행할 때 나는 여전히 500을 얻는다. 내가 뭘 잘못하고 있는지 모르겠다. –

+0

@MHero : 아주 이상하다. 어쩌면 당신은 CXF에 대한 버그를 제기해야한다. (예를 들어, 500 번으로의 변환을 일으키는 또 다른 필터를 설치하지 않았다면, 나는 과거에 비슷한 바보 같은 일을했다.) –

0

코드는 아래 답변에 대한 413

import java.io.IOException; 
import java.io.OutputStream; 
import java.net.HttpURLConnection; 
import java.util.List; 
import java.util.Map; 

import org.apache.cxf.endpoint.Endpoint; 
import org.apache.cxf.helpers.CastUtils; 
import org.apache.cxf.message.Exchange; 
import org.apache.cxf.message.Message; 
import org.apache.cxf.message.MessageImpl; 
import org.apache.cxf.phase.AbstractPhaseInterceptor; 
import org.apache.cxf.phase.Phase; 
import org.apache.cxf.transport.Conduit; 
import org.apache.cxf.ws.addressing.EndpointReferenceType; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

public class AttachmentInInterceptor extends AbstractPhaseInterceptor<Message> { 

private static final Long MAX_SIZE = 2048L * 1024L; 
private static final Logger LOGGER = LoggerFactory.getLogger(BaseCxfInterceptor.class); 

public AttachmentInInterceptor() { 
    super(Phase.RECEIVE); 
} 

public void handleMessage(Message message) { 
    String contentType = (String) message.get(Message.CONTENT_TYPE); 
    if (contentType != null && contentType.toLowerCase().indexOf("multipart/form-data") >= 0) { 
     Map<String, List<String>> headers = CastUtils.cast((Map<?,?>)message.get(Message.PROTOCOL_HEADERS)); 
     String len = headers.get("Content-Length").toString(); 
     len = len.replaceAll("\\[", ""); 
     len = len.replaceAll("\\]", ""); 
     Long length = Long.valueOf(len); 
     if (length > MAX_SIZE) { 
      replyEntityTooLarge(message); 
     } 
    } 
} 

private void replyEntityTooLarge(Message message) { 
    Message outMessage = getOutMessage(message); 
    outMessage.put(Message.RESPONSE_CODE, 
      HttpURLConnection.HTTP_ENTITY_TOO_LARGE); 

    message.getInterceptorChain().abort(); 
    try { 
     getConduit(message).prepare(outMessage); 
     OutputStream os = message.getContent(OutputStream.class); 
     os.flush(); 
     os.close(); 
    } catch (IOException e) { 
     LOGGER.error("Erro no interceptor do cxf {}",e); 
     throw new RuntimeException(e); 
    } 
} 

private Message getOutMessage(Message message) { 
    Exchange exchange = message.getExchange(); 
    Message outMessage = exchange.getOutMessage(); 
    if (outMessage == null) { 
     Endpoint endpoint = exchange.get(Endpoint.class); 
     outMessage = new MessageImpl(); 
     outMessage.setExchange(exchange); 
     outMessage = endpoint.getBinding().createMessage(outMessage); 
     exchange.setOutMessage(outMessage); 
    } 
    outMessage.putAll(message); 
    return outMessage; 
} 

private Conduit getConduit(Message message) throws IOException { 
    Exchange exchange = message.getExchange(); 
    EndpointReferenceType target = 
     exchange.get(EndpointReferenceType.class); 
    Conduit conduit = 
     exchange.getDestination().getBackChannel(message, null, target); 
    exchange.setConduit(conduit); 
    return conduit; 
} 
} 
+0

os.flush()에서 java.lang.NullPointerException : null 예외가 발생합니다. – Eduardo