Solon v3.5.1

渲染器 Render

</> markdown

前置参考:

1、接口声明

package org.noear.solon.core.handle;

public interface Render {
    /**
     * 名字
     */
    default String name() {
        return this.getClass().getSimpleName();
    }

    /**
     * 是否匹配
     *
     * @param ctx  上下文
     * @param mime 媒体类型
     */
    default boolean matched(Context ctx, String mime) {
        return false;
    }

    /**
     * 渲染并返回(默认不实现)
     */
    default String renderAndReturn(Object data, Context ctx) throws Throwable {
        return null;
    }

    /**
     * 渲染
     *
     * @param data 数据
     * @param ctx  上下文
     */
    void render(Object data, Context ctx) throws Throwable;

}

2、定制参考1

public class SseRender implements Render {
    private static final SseRender instance = new SseRender();

    public static SseRender getInstance() {
        return instance;
    }

    @Override
    public boolean matched(Context ctx, String mime) {
        if (mime == null) {
            return false;
        } else {
            return mime.startsWith(MimeType.TEXT_EVENT_STREAM_VALUE);
        }
    }

    @Override
    public String renderAndReturn(Object data, Context ctx) throws Throwable {
        SseEvent event;
        if (data instanceof SseEvent) {
            event = (SseEvent) data;
        } else {
            if (data instanceof String) {
                event = new SseEvent().data(data);
            } else {
                String json = Solon.app().renderOfJson().renderAndReturn(data, ctx);
                event = new SseEvent().data(json);
            }
        }

        return event.toString();
    }

    public static void pushSseHeaders(Context ctx) {
        ctx.contentType(MimeType.TEXT_EVENT_STREAM_UTF8_VALUE);
        ctx.keepAlive(60);
        ctx.cacheControl("no-cache");
    }

    @Override
    public void render(Object data, Context ctx) throws Throwable {
        if (ctx.isHeadersSent() == false) {
            pushSseHeaders(ctx);
        }

        if (data != null) {
            ctx.output(renderAndReturn(data, ctx));
        }
    }
}

3、定制参考2

public class JspRender implements Render {
    @Override
    public void render(Object obj, Context ctx) throws Throwable {
        if(obj == null){
            return;
        }

        if (obj instanceof ModelAndView) {
            render_mav((ModelAndView) obj, ctx);
        }else{
            ctx.output(obj.toString());
        }
    }

    public void render_mav(ModelAndView mv, Context ctx) throws Throwable {
        if(ctx.contentTypeNew() == null) {
            ctx.contentType(MimeType.TEXT_HTML_UTF8_VALUE);
        }

        if (ViewConfig.isOutputMeta()) {
            ctx.headerSet(ViewConfig.HEADER_VIEW_META, "JspRender");
        }

        //添加 context 变量
        mv.putIfAbsent("context", ctx);

        HttpServletResponse response = (HttpServletResponse)ctx.response();
        HttpServletRequest request = (HttpServletRequest)ctx.request();

        mv.model().forEach(request::setAttribute);

        String view = mv.view();

        if (view.endsWith(".jsp") == true) {

            if (view.startsWith("/") == true) {
                view = ViewConfig.getViewPrefix() + view;
            } else {
                view = ViewConfig.getViewPrefix() + "/" + view;
            }
            view = view.replace("//", "/");
        }

        request.getServletContext()
               .getRequestDispatcher(view)
               .forward(request, response);
    }
}