渲染控制，也就是最终的输出控制。可以有多种方式。



### 1、控制器基类实现渲染接口（作用范围为子类）

示例：

1. 如果是异常，转为 Result 渲染输出
2. 其它直接渲染输出

```java
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Render;
import org.noear.solon.core.handle.Result;

public class ControllerBase implements Render { //这是个基类，其它控制器在继承它
    @Override
    public void render(Object obj, Context ctx) throws Throwable {
        if (obj instanceof Throwable) {
            ctx.render(Result.failure(500));
        } else {
            ctx.render(obj);
        }
    }
}
```

可以使用 `ctx.render(x)` （转给其它渲染器） 或 `ctx.output(x);` （最终输出）

### 2、定制渲染器组件（作用范围为全局）

组件名，是指当前渲染器的名字。可替代预置的同名渲染器（相关名字可参考 SerializerNames）。

```java
import org.noear.solon.Solon;
import org.noear.solon.annotation.Component;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Render;

@Component("@json")
public class RenderImpl implements Render {
    @Override
    public void render(Object data, Context ctx) throws Throwable {
        //用 json 序列化器生成数据
        String json = Solon.app().serializers().jsonOf().serialize(data);
        String jsonEncoded = "";//加密
        String jsonEigned = ""; //鉴名

        ctx.headerSet("E", jsonEigned);
        ctx.output(jsonEncoded);
    }
}
```

渲染器组件不能再使用 `ctx.render(obj)`，否则又会回到自己身上了。（死循环）