2011-12-02 57 views
1

我使用CXF 2.4.4做出的RESTful Web服務的Apache CXF設置上傳大小

我有這樣的服務:

@WebService 
public interface Remote { 
    @POST 
    @Path("/create") 
    @Consumes(MediaType.MULTIPART_FORM_DATA) 
    @Produces(MediaType.APPLICATION_XML) 
    public CustomXML makerService(); 
} 

消耗一個MULTIPART_FORM_DATA

我想限制附件大小。我發現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

@Mero:這很奇怪;也許你應該提出一個針對CXF的bug,因爲這應該是可行的(另外,假設你沒有將另一個過濾器置於導致轉換爲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