Java Apache CXF设置上载大小

Java Apache CXF设置上载大小,java,cxf,attachment,interceptor,Java,Cxf,Attachment,Interceptor,我正在使用CXF2.4.4来创建RESTful Web服务 我有以下服务: @WebService public interface Remote { @POST @Path("/create") @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.APPLICATION_XML) public CustomXML makerService(); } 使用多部分表单数据的 我想限制附

我正在使用CXF2.4.4来创建RESTful Web服务

我有以下服务:

@WebService
public interface Remote {
    @POST
    @Path("/create")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Produces(MediaType.APPLICATION_XML)
    public CustomXML makerService(); 
}
使用
多部分表单数据的

我想限制附件的大小。我找到了,它完成了工作,只不过它返回了
HTTP500状态

请告诉我如何返回其他状态(
http413status
like was expected),或者捕获此异常并重新显示它

编辑
我通过拦截器做到了这一点,就像这样

@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) {
    }
}
公共类AttachmentInterceptor扩展AbstractPhaseInterceptor{
公共附件接收者(){
超级(相位接收);
}
公共无效handleMessage(消息消息){
String contentType=(String)message.get(message.CONTENT\u TYPE);
地图标题;
if(contentType!=null&&contentType.toLowerCase().indexOf(“多部分/表单数据”)>=0){
AttachmentDeserializer ad=新的AttachmentDeserializer(消息);
headers=(映射)message.get(message.PROTOCOL_头);
字符串len=headers.get(“内容长度”).toString();
len=len.replaceAll(“\\[”,”);
len=len.replaceAll(“\\]”,“”);
Long length=Long.valueOf(len);
如果(长度>100000000){
抛出新的错误(新的CustomException(“Archivo grande”,ErrorCode.ERROR.getCode());
}
试一试{
ad.初始化附件();
}捕获(IOE异常){
抛出新的故障(e);
}
}
}
@凌驾
公共无效handleFault(消息消息){
}
}
但是我仍然无法发送所需的响应(
http413 status


我提前感谢任何帮助

检查表明非500结果通过抛出;它是一个
RuntimeException
子类-因此您不需要声明它-它有一个接受响应代码的单参数构造函数(或者您可以构造一个完整的
响应
,或者任何您喜欢的东西)。

下面的代码返回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;
}
}
import java.io.IOException;
导入java.io.OutputStream;
导入java.net.HttpURLConnection;
导入java.util.List;
导入java.util.Map;
导入org.apache.cxf.endpoint.endpoint;
导入org.apache.cxf.helpers.CastUtils;
导入org.apache.cxf.message.Exchange;
导入org.apache.cxf.message.message;
导入org.apache.cxf.message.MessageImpl;
导入org.apache.cxf.phase.AbstractPhaseInterceptor;
导入org.apache.cxf.phase.phase;
导入org.apache.cxf.transport.conductor;
导入org.apache.cxf.ws.addressing.EndpointReferenceType;
导入org.slf4j.Logger;
导入org.slf4j.LoggerFactory;
公共类AttachmentInterceptor扩展AbstractPhaseInterceptor{
专用静态最终最大长尺寸=2048L*1024L;
私有静态最终记录器Logger=LoggerFactory.getLogger(BaseCxfInterceptor.class);
公共附件接收者(){
超级(相位接收);
}
公共无效handleMessage(消息消息){
String contentType=(String)message.get(message.CONTENT\u TYPE);
if(contentType!=null&&contentType.toLowerCase().indexOf(“多部分/表单数据”)>=0){
Map headers=CastUtils.cast((Map)message.get(message.PROTOCOL_headers));
字符串len=headers.get(“内容长度”).toString();
len=len.replaceAll(“\\[”,”);
len=len.replaceAll(“\\]”,“”);
Long length=Long.valueOf(len);
如果(长度>最大尺寸){
replyEntityTooLarge(消息);
}
}
}
私有void replyEntityTooLarge(消息消息){
Message outMessage=getOutMessage(Message);
outMessage.put(Message.RESPONSE_代码,
HttpURLConnection.HTTP_实体(太大);
message.getInterceptorChain().abort();
试一试{
getconductor(message).准备(outMessage);
OutputStream os=message.getContent(OutputStream.class);
os.flush();
os.close();
}捕获(IOE异常){
LOGGER.error(“Erro no interceptor do cxf{}”,e);
抛出新的运行时异常(e);
}   
}
私有消息getOutMessage(消息消息){
Exchange=message.getExchange();
Message outMessage=exchange.getOutMessage();
if(outMessage==null){
Endpoint=exchange.get(Endpoint.class);
outMessage=newmessageimpl();
outMessage.setExchange(交换);
outMessage=endpoint.getBinding().createMessage(outMessage);
exchange.setOutMessage(outMessage);
}
outMessage.putAll(消息);
返回消息;
}
私有管道getconductor(消息消息)引发IOException{
Exchange=message.getExchange();
EndpointReferenceType目标=
get(EndpointReferenceType.class);
导管=
exchange.getDestination().getBackChannel(消息,null,目标);
交换。设置导管(导管);
回流管;
}
}

您好,谢谢您的回答。我试过你说的,但是当我执行一个来自客户端的http请求时,我仍然得到500。不知道我在干什么wrong@MHero:这很奇怪;也许您应该针对CXF提出一个bug,因为这应该是可行的(同时,假设您没有放置另一个导致转换为500的过滤器;我过去也做过类似的傻事)…这在os.flush()上给出了一个异常“java.lang.NullPointerException:null”;