渲染器 Render
前置参考:
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);
}
}