前置参考：

* [Web 请求处理过程示意图（AOP）](/article/242)
* [Action 结构图及两种注解处理](/article/608)


像下面这个示例，可以通过返回类型特征进行处理定制（一般不需要）：

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



### 1、接口声明


```java
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


```java
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

```java
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().chains().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);
            }
        }
    }
}
```


