Solon v3.5.1

返回结果处理器 ReturnValueHandler

</> markdown

前置参考:

像下面这个示例,可以通过返回类型特征进行处理定制(一般不需要):

@Controller
public class DemoController {
    @Mapping("case1")
    public SseEmitter case1(){
        ...
    }
    
    @Mapping("case2")
    public Flux<User> case2(){
        ...
    }
}

1、接口声明

package org.noear.solon.core.handle;

public interface ReturnValueHandler {
    /**
     * 是否匹配
     *
     * @param ctx        上下文
     * @param returnType 返回类型
     */
    boolean matched(Context ctx, Class<?> returnType);

    /**
     * 返回处理
     *
     * @param ctx         上下文
     * @param returnValue 返回值
     */
    void returnHandle(Context ctx, Object returnValue) throws Throwable;
}

2、定制参考1

public class SseReturnValueHandler implements ReturnValueHandler {
    @Override
    public boolean matched(Context ctx, Class<?> returnType) {
        return SseEmitter.class.isAssignableFrom(returnType);
    }

    @Override
    public void returnHandle(Context ctx, Object returnValue) throws Throwable {
        if (returnValue != null) {
            if (ctx.asyncSupported() == false) {
                throw new IllegalStateException("This boot plugin does not support asynchronous mode");
            }

            new SseEmitterHandler((SseEmitter) returnValue).start();
        }
    }
}

3、定制参考2

public class ReturnValueHandlerDefault implements ReturnValueHandler {
    public static final ReturnValueHandler INSTANCE = new ReturnValueHandlerDefault();

    @Override
    public boolean matched(Context ctx, Class<?> returnType) {
        return false;
    }

    @Override
    public void returnHandle(Context c, Object obj) throws Throwable {
        //可以通过before关掉render
        //
        obj = Solon.app().chainManager().postResult(c, obj);

        if (c.getRendered() == false) {
            c.result = obj;
        }


        if (obj instanceof DataThrowable) {
            //没有代理时,跳过 DataThrowable
            return;
        }

        if (obj == null) {
            //如果返回为空,且二次加载的结果为 null
            return;
        }

        if (obj instanceof Throwable) {
            if (c.remoting()) {
                //尝试推送异常,不然没机会记录;也可对后继做控制
                Throwable objE = (Throwable) obj;
                LogUtil.global().warn("Remoting handle failed: " + c.pathNew(), objE);

                if (c.getRendered() == false) {
                    c.render(obj);
                }
            } else {
                c.setHandled(false); //传递给 filter, 可以统一处理未知异常
                throw (Throwable) obj;
            }
        } else {
            if (c.getRendered() == false) {
                c.render(obj);
            }
        }
    }
}