|
|
|
package com.fr.start.server;
|
|
|
|
|
|
|
|
import com.fr.design.DesignerEnvManager;
|
|
|
|
import com.fr.log.FineLoggerFactory;
|
|
|
|
import com.fr.module.Activator;
|
|
|
|
import com.fr.module.ModuleRole;
|
|
|
|
import com.fr.stable.EncodeConstants;
|
|
|
|
import com.fr.stable.ProductConstants;
|
|
|
|
import com.fr.stable.StringUtils;
|
|
|
|
import com.fr.startup.FineWebApplicationInitializer;
|
|
|
|
import com.fr.third.guava.collect.Sets;
|
|
|
|
import com.fr.third.springframework.web.SpringServletContainerInitializer;
|
|
|
|
import com.fr.third.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
|
|
|
import com.fr.web.socketio.WebSocketEndpoint;
|
|
|
|
import com.fr.workspace.WorkContext;
|
|
|
|
import org.apache.catalina.Context;
|
|
|
|
import org.apache.catalina.LifecycleException;
|
|
|
|
import org.apache.catalina.loader.WebappLoader;
|
|
|
|
import org.apache.catalina.startup.Tomcat;
|
|
|
|
import org.apache.catalina.webresources.StandardRoot;
|
|
|
|
import org.apache.tomcat.websocket.server.WsSci;
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.Set;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Created by juhaoyu on 2018/6/5.
|
|
|
|
*/
|
|
|
|
public class FineEmbedServerActivator extends Activator {
|
|
|
|
|
|
|
|
private static final String TOMCAT_MAX_HEADER_SIZE = "tomcat-maxHttpHeaderSize";
|
|
|
|
|
|
|
|
private Tomcat tomcat;
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public synchronized void start() {
|
|
|
|
|
|
|
|
try {
|
|
|
|
FineEmbedServerMonitor.getInstance().reset();
|
|
|
|
//初始化tomcat
|
|
|
|
initTomcat();
|
|
|
|
tomcat.start();
|
|
|
|
|
|
|
|
} catch (LifecycleException e) {
|
|
|
|
FineLoggerFactory.getLogger().error(e.getMessage(), e);
|
|
|
|
} finally {
|
|
|
|
FineEmbedServerMonitor.getInstance().setComplete();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public synchronized void stop() {
|
|
|
|
|
|
|
|
try {
|
|
|
|
stopSpring();
|
|
|
|
stopServerActivator();
|
|
|
|
stopTomcat();
|
|
|
|
} catch (Exception e) {
|
|
|
|
FineLoggerFactory.getLogger().error(e.getMessage(), e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void initTomcat() {
|
|
|
|
|
|
|
|
tomcat = new Tomcat();
|
|
|
|
|
|
|
|
tomcat.setPort(DesignerEnvManager.getEnvManager().getEmbedServerPort());
|
|
|
|
// 设置解码uri使用的字符编码
|
|
|
|
tomcat.getConnector().setURIEncoding(EncodeConstants.ENCODING_UTF_8);
|
|
|
|
// 参考 https://jira.atlassian.com/browse/CONFSERVER-57582
|
|
|
|
// https://tomcat.apache.org/tomcat-8.5-doc/config/http.html
|
|
|
|
// 8.5.x 请求参数带特殊字符被tomcat拒绝 []|{}^\`"<>
|
|
|
|
tomcat.getConnector().setProperty("relaxedQueryChars", "[]|{}^\`"<>");
|
|
|
|
setMaxPostSize();
|
|
|
|
setMaxHttpHeaderSize();
|
|
|
|
String docBase = new File(WorkContext.getCurrent().getPath()).getParent();
|
|
|
|
|
|
|
|
//内置的上下文使用工程目录比如webroot
|
|
|
|
String contextPath = "/" + ProductConstants.getAppFolderName();
|
|
|
|
final Context context = tomcat.addContext(contextPath, docBase);
|
|
|
|
context.setResources(new StandardRoot(context));
|
|
|
|
Tomcat.initWebappDefaults(context);
|
|
|
|
//覆盖tomcat的WebAppClassLoader
|
|
|
|
context.setLoader(new FRTomcatLoader());
|
|
|
|
|
|
|
|
|
|
|
|
//直接指定initializer,tomcat就不用再扫描一遍了
|
|
|
|
SpringServletContainerInitializer initializer = new SpringServletContainerInitializer();
|
|
|
|
Set<Class<?>> classes = new HashSet<Class<?>>();
|
|
|
|
classes.add(FineWebApplicationInitializer.class);
|
|
|
|
context.addServletContainerInitializer(initializer, classes);
|
|
|
|
context.addServletContainerInitializer(new WsSci(), Sets.newHashSet(WebSocketEndpoint.class));
|
|
|
|
}
|
|
|
|
|
|
|
|
// tomcat的maxPostSize会影响到post参数获取,默认2M
|
|
|
|
private void setMaxPostSize() {
|
|
|
|
|
|
|
|
if (System.getProperty("tomcat-maxPostSize") != null) {
|
|
|
|
try {
|
|
|
|
tomcat.getConnector().setMaxPostSize(Integer.parseInt(System.getProperty("tomcat-maxPostSize")));
|
|
|
|
} catch (Exception e) {
|
|
|
|
FineLoggerFactory.getLogger().error("maxPostSize error: " + e.getMessage(), e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void setMaxHttpHeaderSize() {
|
|
|
|
String value = System.getProperty(TOMCAT_MAX_HEADER_SIZE);
|
|
|
|
if (StringUtils.isNotEmpty(value)) {
|
|
|
|
try {
|
|
|
|
tomcat.getConnector().setProperty("maxHttpHeaderSize", value);
|
|
|
|
} catch (Exception e) {
|
|
|
|
FineLoggerFactory.getLogger().error(e.getMessage(), e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void stopServerActivator() {
|
|
|
|
|
|
|
|
ModuleRole.ServerRoot.stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void stopSpring() {
|
|
|
|
|
|
|
|
AnnotationConfigWebApplicationContext context = ModuleRole.ServerRoot.findSingleton(AnnotationConfigWebApplicationContext.class);
|
|
|
|
if (context != null) {
|
|
|
|
context.stop();
|
|
|
|
context.destroy();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void stopTomcat() throws LifecycleException {
|
|
|
|
|
|
|
|
tomcat.stop();
|
|
|
|
tomcat.destroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Created by juhaoyu on 2018/6/5.
|
|
|
|
* 自定义的tomcat loader,主要用于防止内置服务器再加载一遍class
|
|
|
|
*/
|
|
|
|
private static class FRTomcatLoader extends WebappLoader {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public ClassLoader getClassLoader() {
|
|
|
|
|
|
|
|
return this.getClass().getClassLoader();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|