update: 进一步优化uflo/urule/ureport的启动过程

This commit is contained in:
Wendal Chen 2017-12-12 23:06:21 +08:00
parent d0e454c2e3
commit dd23e18487
18 changed files with 185 additions and 373 deletions

View File

@ -5,10 +5,11 @@
* 变更:
* add: new NbApp()可以不传类名,从堆栈自动推断
* add: starter-mongodb by @qingerg
* add: starter-tomcat by @ben
* add: starter-tomcat by [@benjobs](https://github.com/wolfboys)
* add: starter-beetlsql 来自beetl的SQL解决方案
* add: starter-sharding-jdbc 分库分表
* add: starter-thymeleaf 模板引擎
* add: starter for U家三剑客(uflo工作流,ureport报表,urule规则引擎)
* fix: jetty扫描websocket的endpoint有问题
## 2.0-RC "属于"

View File

@ -18,6 +18,11 @@
<artifactId>nutzboot-starter-uflo</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter-jdbc</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzboot-starter</artifactId>
@ -27,6 +32,11 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.193</version>
</dependency>
</dependencies>
<build>
<plugins>

View File

@ -60,7 +60,6 @@
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutzmongo</artifactId>
<version>${nutz.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -22,5 +22,16 @@
<groupId>org.nutz</groupId>
<artifactId>nutz</artifactId>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutz-integration-spring</artifactId>
<version>${nutz.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>

View File

@ -1,53 +1,24 @@
package org.nutz.boot.starter.uflo;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.nutz.boot.AppContext;
import org.nutz.boot.starter.WebServletFace;
import org.nutz.ioc.Ioc;
import org.nutz.ioc.Ioc2;
import org.nutz.ioc.IocContext;
import org.nutz.ioc.ObjectProxy;
import org.nutz.ioc.impl.PropertiesProxy;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.XmlWebApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import com.bstek.uflo.console.handler.ServletHandler;
import com.bstek.uflo.console.UfloServlet;
@SuppressWarnings("serial")
@IocBean
public class UfloServletStarter extends HttpServlet implements WebServletFace {
public class UfloServletStarter extends UfloServlet implements WebServletFace {
public static final String URL="/uflo";
protected Map<String,ServletHandler> handlerMap = new HashMap<String,ServletHandler>();
@Inject
protected PropertiesProxy conf;
@Inject
protected AppContext appContext;
@Inject("refer:$ioc")
protected Ioc ioc;
protected XmlWebApplicationContext applicationContext;
protected ContextLoaderListener ctx;
public String getName() {
return "uflo";
@ -66,90 +37,16 @@ public class UfloServletStarter extends HttpServlet implements WebServletFace {
}
public void init(ServletConfig config) throws ServletException {
applicationContext = new XmlWebApplicationContext();
applicationContext.setServletContext(config.getServletContext());
applicationContext.setConfigLocation("classpath:uflo-spring-context.xml");
applicationContext.refresh();
IocContext ictx = ((Ioc2) ioc).getIocContext();
for (String name : applicationContext.getBeanDefinitionNames()) {
if (name.startsWith("uflo.")) {
switch (name) {
case "uflo.props":
case "uflo.environmentProvider":
break;
default:
Object bean = applicationContext.getBean(name);
ictx.save("app", name, new ObjectProxy(bean));
break;
}
}
ServletContext sc = config.getServletContext();
WebApplicationContext applicationContext = (WebApplicationContext) sc.getAttribute("spring.uflo");
Object pre = sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
try {
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, applicationContext);
super.init(config);
}
Collection<ServletHandler> handlers = applicationContext.getBeansOfType(ServletHandler.class).values();
for(ServletHandler handler:handlers){
String url=handler.url();
if(handlerMap.containsKey(url)){
throw new RuntimeException("Handler ["+url+"] already exist.");
}
handlerMap.put(url, handler);
finally {
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, pre);
}
}
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try{
String path=req.getContextPath()+URL;
String uri=req.getRequestURI();
String targetUrl=uri.substring(path.length());
if(targetUrl.length()<1){
resp.sendRedirect(req.getContextPath()+"/uflo/todo");
return;
}
int slashPos=targetUrl.indexOf("/",1);
if(slashPos>-1){
targetUrl=targetUrl.substring(0,slashPos);
}
ServletHandler targetHandler=handlerMap.get(targetUrl);
if(targetHandler==null){
outContent(resp,"Handler ["+targetUrl+"] not exist.");
return;
}
targetHandler.execute(req, resp);
}catch(Exception ex){
Throwable e=getCause(ex);
resp.setCharacterEncoding("UTF-8");
PrintWriter pw=resp.getWriter();
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
String errorMsg = e.getMessage();
if(StringUtils.isBlank(errorMsg)){
errorMsg=e.getClass().getName();
}
pw.write(errorMsg);
pw.close();
throw new ServletException(ex);
}
}
protected Throwable getCause(Throwable e){
if(e.getCause()!=null){
return getCause(e.getCause());
}
return e;
}
protected void outContent(HttpServletResponse resp,String msg) throws IOException {
resp.setContentType("text/html");
PrintWriter pw=resp.getWriter();
pw.write("<html>");
pw.write("<header><title>Uflo Console</title></header>");
pw.write("<body>");
pw.write(msg);
pw.write("</body>");
pw.write("</html>");
pw.flush();
pw.close();
}
@Override
public void destroy() {
applicationContext.destroy();
}
}

View File

@ -0,0 +1,14 @@
package org.nutz.boot.starter.uflo;
import org.nutz.boot.tools.SpringWebContextProxy;
import org.nutz.ioc.loader.annotation.IocBean;
@IocBean
public class UfloSpringEnvStarter extends SpringWebContextProxy {
public UfloSpringEnvStarter() {
configLocation = "classpath:uflo-spring-context.xml";
selfName = "uflo";
}
}

View File

@ -1 +1,2 @@
org.nutz.boot.starter.uflo.UfloSpringEnvStarter
org.nutz.boot.starter.uflo.UfloServletStarter

View File

@ -24,7 +24,6 @@ import org.nutz.ioc.impl.PropertiesProxy;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Files;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.util.LifeCycle;
import org.nutz.log.Log;

View File

@ -26,7 +26,7 @@
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutz-integration-spring</artifactId>
<version>1.r.65-SNAPSHOT</version>
<version>${nutz.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>

View File

@ -1,54 +1,23 @@
package org.nutz.boot.starter.ureport;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.nutz.boot.AppContext;
import org.nutz.boot.starter.WebServletFace;
import org.nutz.integration.spring.SpringIocLoader2;
import org.nutz.ioc.Ioc;
import org.nutz.ioc.impl.PropertiesProxy;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Files;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.XmlWebApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import com.bstek.ureport.console.RequestHolder;
import com.bstek.ureport.console.ServletAction;
import com.bstek.ureport.console.UReportServlet;
@SuppressWarnings("serial")
@IocBean
public class UreportServletStarter extends HttpServlet implements WebServletFace {
public class UreportServletStarter extends UReportServlet implements WebServletFace {
protected Map<String, ServletAction> handlerMap = new HashMap<String,ServletAction>();
@Inject
protected PropertiesProxy conf;
@Inject
protected AppContext appContext;
@Inject("refer:$ioc")
protected Ioc ioc;
protected XmlWebApplicationContext applicationContext;
protected ContextLoaderListener ctx;
public String getName() {
return "ureport";
}
@ -66,93 +35,15 @@ public class UreportServletStarter extends HttpServlet implements WebServletFace
}
public void init(ServletConfig config) throws ServletException {
Files.createDirIfNoExists(conf.check("ureport.repository.dir"));
applicationContext = new XmlWebApplicationContext();
applicationContext.setServletContext(config.getServletContext());
applicationContext.setConfigLocation("classpath:ureport-spring-context.xml");
applicationContext.refresh();
List<String> names = new ArrayList<>();
for (String name : applicationContext.getBeanDefinitionNames()) {
if (name.startsWith("ureport.")) {
switch (name) {
case "ureport.props":
break;
default:
names.add(name);
}
}
ServletContext sc = config.getServletContext();
WebApplicationContext applicationContext = (WebApplicationContext) sc.getAttribute("spring.ureport");
Object pre = sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
try {
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, applicationContext);
super.init(config);
}
appContext.getComboIocLoader().addLoader(new SpringIocLoader2(applicationContext, names.toArray(new String[names.size()])));
Collection<ServletAction> handlers = applicationContext.getBeansOfType(ServletAction.class).values();
for(ServletAction handler:handlers){
String url=handler.url();
if(handlerMap.containsKey(url)){
throw new RuntimeException("Handler ["+url+"] already exist.");
}
handlerMap.put(url, handler);
finally {
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, pre);
}
}
public static final String URL="/ureport";
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String path = req.getContextPath() + URL;
String uri = req.getRequestURI();
String targetUrl = uri.substring(path.length());
if (targetUrl.length() < 1) {
outContent(resp, "Welcome to use ureport,please specify target url.");
return;
}
int slashPos = targetUrl.indexOf("/", 1);
if (slashPos > -1) {
targetUrl = targetUrl.substring(0, slashPos);
}
ServletAction targetHandler = handlerMap.get(targetUrl);
if (targetHandler == null) {
outContent(resp, "Handler [" + targetUrl + "] not exist.");
return;
}
RequestHolder.setRequest(req);
try{
targetHandler.execute(req, resp);
}catch(Exception ex){
resp.setCharacterEncoding("UTF-8");
PrintWriter pw=resp.getWriter();
Throwable e=buildRootException(ex);
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
String errorMsg = e.getMessage();
if(StringUtils.isBlank(errorMsg)){
errorMsg=e.getClass().getName();
}
pw.write(errorMsg);
pw.close();
throw new ServletException(ex);
}finally{
RequestHolder.clean();
}
}
private Throwable buildRootException(Throwable throwable){
if(throwable.getCause()==null){
return throwable;
}
return buildRootException(throwable.getCause());
}
private void outContent(HttpServletResponse resp, String msg) throws IOException {
resp.setContentType("text/html");
PrintWriter pw = resp.getWriter();
pw.write("<html>");
pw.write("<header><title>UReport Console</title></header>");
pw.write("<body>");
pw.write(msg);
pw.write("</body>");
pw.write("</html>");
pw.flush();
pw.close();
}
@Override
public void destroy() {
applicationContext.destroy();
}
}

View File

@ -0,0 +1,14 @@
package org.nutz.boot.starter.ureport;
import org.nutz.boot.tools.SpringWebContextProxy;
import org.nutz.ioc.loader.annotation.IocBean;
@IocBean
public class UreportSpringEnvStarter extends SpringWebContextProxy {
public UreportSpringEnvStarter() {
configLocation = "classpath:ureport-spring-context.xml";
selfName = "ureport";
}
}

View File

@ -1 +1,2 @@
org.nutz.boot.starter.ureport.UreportSpringEnvStarter
org.nutz.boot.starter.ureport.UreportServletStarter

View File

@ -23,5 +23,16 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutz-integration-spring</artifactId>
<version>${nutz.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>

View File

@ -1,56 +1,23 @@
package org.nutz.boot.starter.urule;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.nutz.boot.AppContext;
import org.nutz.boot.starter.WebServletFace;
import org.nutz.ioc.Ioc;
import org.nutz.ioc.Ioc2;
import org.nutz.ioc.IocContext;
import org.nutz.ioc.ObjectProxy;
import org.nutz.ioc.impl.PropertiesProxy;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Files;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.XmlWebApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import com.bstek.urule.console.exception.NoPermissionException;
import com.bstek.urule.console.repository.NodeLockException;
import com.bstek.urule.console.servlet.RequestHolder;
import com.bstek.urule.console.servlet.ServletHandler;
import com.bstek.urule.console.servlet.URuleServlet;
@SuppressWarnings("serial")
@IocBean
public class UruleServletStarter extends HttpServlet implements WebServletFace {
public class UruleServletStarter extends URuleServlet implements WebServletFace {
protected Map<String,ServletHandler> handlerMap = new HashMap<String,ServletHandler>();
@Inject
protected PropertiesProxy conf;
@Inject
protected AppContext appContext;
@Inject("refer:$ioc")
protected Ioc ioc;
protected XmlWebApplicationContext applicationContext;
protected ContextLoaderListener ctx;
public String getName() {
return "urule";
}
@ -68,103 +35,15 @@ public class UruleServletStarter extends HttpServlet implements WebServletFace {
}
public void init(ServletConfig config) throws ServletException {
Files.createDirIfNoExists(conf.check("urule.repository.dir"));
applicationContext = new XmlWebApplicationContext();
applicationContext.setServletContext(config.getServletContext());
applicationContext.setConfigLocation("classpath:urule-spring-context.xml");
applicationContext.refresh();
IocContext ictx = ((Ioc2) ioc).getIocContext();
for (String name : applicationContext.getBeanDefinitionNames()) {
if (name.startsWith("urule.")) {
switch (name) {
case "urule.props":
break;
default:
Object bean = applicationContext.getBean(name);
ictx.save("app", name, new ObjectProxy(bean));
break;
}
}
ServletContext sc = config.getServletContext();
WebApplicationContext applicationContext = (WebApplicationContext) sc.getAttribute("spring.urule");
Object pre = sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
try {
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, applicationContext);
super.init(config);
}
Collection<ServletHandler> handlers = applicationContext.getBeansOfType(ServletHandler.class).values();
for(ServletHandler handler:handlers){
String url=handler.url();
if(handlerMap.containsKey(url)){
throw new RuntimeException("Handler ["+url+"] already exist.");
}
handlerMap.put(url, handler);
finally {
sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, pre);
}
}
public static final String URL="/urule";
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
RequestHolder.set(req, resp);
try{
String path=req.getContextPath()+URL;
String uri=req.getRequestURI();
String targetUrl=uri.substring(path.length());
if(targetUrl.length()<1){
resp.sendRedirect(req.getContextPath()+"/urule/frame");
return;
}
int slashPos=targetUrl.indexOf("/",1);
if(slashPos>-1){
targetUrl=targetUrl.substring(0,slashPos);
}
ServletHandler targetHandler=handlerMap.get(targetUrl);
if(targetHandler==null){
outContent(resp,"Handler ["+targetUrl+"] not exist.");
return;
}
targetHandler.execute(req, resp);
}catch(Exception ex){
Throwable e=getCause(ex);
resp.setCharacterEncoding("UTF-8");
PrintWriter pw=resp.getWriter();
if(e instanceof NoPermissionException){
resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
pw.write("<h1>Permission denied!</h1>");
pw.close();
}else{
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
String errorMsg = e.getMessage();
if(StringUtils.isBlank(errorMsg)){
errorMsg=e.getClass().getName();
}
pw.write(errorMsg);
pw.close();
if(!(e instanceof NodeLockException)){
throw new ServletException(ex);
}
}
}finally{
RequestHolder.reset();
}
}
private void outContent(HttpServletResponse resp,String msg) throws IOException {
resp.setContentType("text/html");
PrintWriter pw=resp.getWriter();
pw.write("<html>");
pw.write("<header><title>URule Console</title></header>");
pw.write("<body>");
pw.write(msg);
pw.write("</body>");
pw.write("</html>");
pw.flush();
pw.close();
}
private Throwable getCause(Throwable e){
if(e.getCause()!=null){
return getCause(e.getCause());
}
return e;
}
@Override
public void destroy() {
applicationContext.destroy();
}
}

View File

@ -0,0 +1,14 @@
package org.nutz.boot.starter.urule;
import org.nutz.boot.tools.SpringWebContextProxy;
import org.nutz.ioc.loader.annotation.IocBean;
@IocBean
public class UruleSpringEnvStarter extends SpringWebContextProxy {
public UruleSpringEnvStarter() {
configLocation = "classpath:urule-spring-context.xml";
selfName = "urule";
}
}

View File

@ -1 +1,2 @@
org.nutz.boot.starter.urule.UruleSpringEnvStarter
org.nutz.boot.starter.urule.UruleServletStarter

View File

@ -67,6 +67,18 @@
<version>4.3.11.RELEASE</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.11.RELEASE</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.nutz</groupId>
<artifactId>nutz-integration-spring</artifactId>
<version>1.r.65-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
<distributionManagement>
<snapshotRepository>

View File

@ -0,0 +1,57 @@
package org.nutz.boot.tools;
import java.util.ArrayList;
import java.util.EventListener;
import java.util.List;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.nutz.boot.AppContext;
import org.nutz.boot.starter.WebEventListenerFace;
import org.nutz.integration.spring.SpringIocLoader2;
import org.nutz.ioc.Ioc;
import org.nutz.ioc.loader.annotation.Inject;
import org.springframework.web.context.support.XmlWebApplicationContext;
public abstract class SpringWebContextProxy implements ServletContextListener, WebEventListenerFace {
@Inject("refer:$ioc")
protected Ioc ioc;
@Inject
protected AppContext appContext;
protected XmlWebApplicationContext applicationContext;
protected String configLocation;
protected String selfName;
public void contextInitialized(ServletContextEvent sce) {
applicationContext = new XmlWebApplicationContext();
applicationContext.setServletContext(sce.getServletContext());
applicationContext.setConfigLocation(configLocation);
applicationContext.refresh();
appContext.getComboIocLoader().addLoader(new SpringIocLoader2(applicationContext, getSpringBeanNames().toArray(new String[0])));
sce.getServletContext().setAttribute("spring." + selfName, applicationContext);
}
protected List<String> getSpringBeanNames() {
List<String> names = new ArrayList<>();
for (String name : applicationContext.getBeanDefinitionNames()) {
if (name.startsWith(selfName + ".")) {
names.add(name);
}
}
return names;
}
public void contextDestroyed(ServletContextEvent sce) {
if (applicationContext != null)
applicationContext.destroy();
}
public EventListener getEventListener() {
return this;
}
}