Apache CXF настройка размера загрузки - PullRequest
1 голос
/ 03 декабря 2011

Я использую cxf 2.4.4 для создания веб-сервисов RESTful

У меня есть этот сервис:

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

, который потребляет MULTIPART_FORM_DATA.

Я хочуограничить размер вложений.Я нашел эту документацию , и она работает, за исключением того, что она возвращает 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 ]

2 голосов
/ 04 декабря 2011

Изучение исходного кода CXF указывает, что результаты, отличные от 500, возвращаются путем выдачи javax.ws.rs.WebApplicationException;это RuntimeException подкласс - так что вам не нужно его объявлять - и у него есть конструктор с одним аргументом, который принимает код ответа (или вы можете создать полный Response, или любой другой, который вам действительно нравится).

0 голосов
/ 05 декабря 2013

код ниже возвращает 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;
}
}
...