1.main class 如下;
public final class Bootstrap {
//~ Static fields/initializers =============================================
private static final String SHUTDOWN = "SHUTDOWN";
private static final String RELOAD = "RELOAD";
//~ Instance fields ========================================================
private Logger logger;
private Server server;
/**
* The port number on which we wait for shutdown commands.
*/
private int port;
/**
* A random number generator that is only used if
* the shutdown command string is longer than 1024 characters.
*/
private Random random = null;
//~ Constructors ===========================================================
private Bootstrap() {
}
//~ Methods ================================================================
private Logger getLogger() {
if (logger == null) {
logger = LoggerFactory.getLogger(getClass());
}
return logger;
}
public void init() {
String painiuHome = System.getProperty("net365.home", System.getProperty("user.dir", "."));
String configDir = System.getProperty("net365.config.dir");
if (configDir == null) {
configDir = painiuHome + File.separator + "etc" + File.separator;
}
if (!configDir.endsWith(File.separator)) {
configDir += File.separator;
}
String configFile = configDir + "net365.properties";
Map vars = new HashMap();
vars.put("home", painiuHome);
Configuration.initialize(configFile, vars);
initLoggingSystem(configDir);
port = Configuration.getInteger("server.shutdown.port", 8014);
}
private void initLoggingSystem(String configDir) {
File loggingConfigFile = new File(configDir, "logging.properties");
if (loggingConfigFile.exists()) {
System.setProperty("java.util.logging.config.file", loggingConfigFile.getAbsolutePath());
}
File log4jConfigFile = new File(configDir, "log4j.properties");
if (log4jConfigFile.exists()) {
PropertyConfigurator.configure(log4jConfigFile.getAbsolutePath());
}
}
public void startServer() throws Exception {
getLogger().info("Bootstrap: Starting Server...");
server = new Server();
server.initialize();
server.setGracefulShutdown(Configuration.getInteger("server.shutdown.timeout", 0));
server.setStopAtShutdown(true);
server.start();
}
public void stopServer() throws Exception {
getLogger().info("Bootstrap: Stopping Server...");
server.stop();
}
public static void main(String[] args) {
Bootstrap bootstrap = new Bootstrap();
try {
bootstrap.init();
String command = "start";
if (args.length > 0) {
command = args[args.length - 1];
}
if (command.equals("start")) {
bootstrap.startServer();
bootstrap.await();
bootstrap.stopServer();
} else if (command.equals("stop")) {
bootstrap.stop();
} else if (command.equals("restart")) {
bootstrap.stop();
// give me 2 seconds to shutdown the server
try {
Thread.sleep(2000);
} catch (InterruptedException e) {}
bootstrap.startServer();
bootstrap.await();
bootstrap.stopServer();
} else if (command.equals("reload")) {
bootstrap.reload();
}
System.exit(0);
} catch (Throwable t) {
t.printStackTrace();
}
}
public void stop() {
sendCommand(SHUTDOWN);
}
public void reload() {
sendCommand(RELOAD);
}
private void sendCommand(String command) {
try {
Socket socket = new Socket("127.0.0.1", port);
OutputStream stream = socket.getOutputStream();
for (int i = 0; i < command.length(); i++) {
stream.write(command.charAt(i));
}
stream.flush();
stream.close();
socket.close();
} catch (IOException e) {
getLogger().error("IOException occurred: ", e);
}
}
public void await() {
// Set up a server socket to wait on
ServerSocket serverSocket = null;
try {
serverSocket =
new ServerSocket(port, 1,
InetAddress.getByName("127.0.0.1"));
} catch (IOException e) {
getLogger().error("Bootstrap.await: create[" + port + "]: ", e);
System.exit(1);
}
// Loop waiting for a connection and a valid command
while (true) {
// Wait for the next connection
Socket socket = null;
InputStream stream = null;
try {
socket = serverSocket.accept();
socket.setSoTimeout(10 * 1000); // Ten seconds
stream = socket.getInputStream();
} catch (AccessControlException ace) {
getLogger().warn("StandardServer.accept security exception: " + ace.getMessage(), ace);
continue;
} catch (IOException e) {
getLogger().error("StandardServer.await: accept: ", e);
System.exit(1);
}
// Read a set of characters from the socket
StringBuffer command = new StringBuffer();
int expected = 1024; // Cut off to avoid DoS attack
while (expected < SHUTDOWN.length()) {
if (random == null)
random = new Random(System.currentTimeMillis());
expected += (random.nextInt() % 1024);
}
while (expected > 0) {
int ch = -1;
try {
ch = stream.read();
} catch (IOException e) {
getLogger().warn("Bootstrap.await: read: ", e);
ch = -1;
}
if (ch < 32) // Control character or EOF terminates loop
break;
command.append((char) ch);
expected--;
}
// Close the socket now that we are done with it
try {
socket.close();
} catch (IOException e) {
}
// Match against our command string
if (command.toString().equals(SHUTDOWN)) {
break;
} else if (command.toString().equals(RELOAD)) {
try {
server.reload();
} catch (Exception e) {
getLogger().error("Bootstrap.reloading failed", e);
}
} else {
getLogger().warn("Bootstrap.await: Invalid command '" +
command.toString() + "' received");
}
}
// Close the server socket and return
try {
serverSocket.close();
} catch (IOException e) {
}
}
}
2.server class 如下:
public class Server extends org.mortbay.jetty.Server {
//~ Static fields/initializers =============================================
private static final Logger logger = LoggerFactory.getLogger(Server.class);
//~ Instance fields ========================================================
private ClassPathXmlApplicationContext applicationContext;
private Handler webapp;
private RemotingServer remotingServer;
//~ Constructors ===========================================================
public Server() {
}
//~ Methods ================================================================
private void initApplicationContext() {
String configLocation = Configuration.get("spring.config.location", "applicationContext*.xml");
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext();
context.setConfigLocation(context.CLASSPATH_ALL_URL_PREFIX + configLocation);
context.refresh();
applicationContext = context;
}
//private void initYPFS() {
// YPFS.initialize(null);
//}
private SecurityHandler createSecurityHandler() {
return new SecurityHandler();
}
private SessionHandler createSessionHandler() {
//SessionManager sessionManager = (SessionManager) applicationContext.getBean("jettySessionManager");
//if (sessionManager == null) {
// logger.error("SessionManager not configured! use default: HashSessionManager");
SessionManager sessionManager = new HashSessionManager();
//}
sessionManager.setSessionDomain("." + Configuration.get("webapp.domain"));
return new SessionHandler(sessionManager);
}
private ErrorHandler createErrorHandler() {
ErrorHandler handler = new ErrorHandler();
handler.setShowStacks(Configuration.getBoolean("devmode", false));
return handler;
}
public void reload() throws Exception {
applicationContext.refresh();
webapp.stop();
webapp.start();
}
public void initialize() throws Exception {
initApplicationContext();
//initYPFS();
Connector connector = new SelectChannelConnector();
connector.setPort(Configuration.getInteger("server.port", 8080));
setConnectors(new Connector[] { connector });
webapp = initWebAppHandler();
if (Configuration.getBoolean("devmode", false)) {
// setup static context for development
List handlers = new ArrayList(3);
handlers.add(webapp);
if (Configuration.get("server.media.vhosts") != null) {
handlers.add(initStaticContext());
}
ContextHandlerCollection contexts = new ContextHandlerCollection();
contexts.setHandlers(handlers.toArray(new Handler[handlers.size()]));
setHandler(contexts);
} else {
setHandler(webapp);
}
}
private Handler initStaticContext() {
ResourceHandler staticHandler = new ResourceHandler();
ContextHandler staticContext = new ContextHandler();
staticContext.setContextPath("/");
staticContext.setResourceBase(Configuration.get("server.media.war"));
staticContext.setHandler(staticHandler);
String vhosts = Configuration.get("server.media.vhosts", "");
logger.info("Starting media server, vhosts: {}", vhosts);
staticContext.setVirtualHosts(StringUtils.split(vhosts));
return staticContext;
}
/* (non-Javadoc)
* @see org.mortbay.jetty.Server#doStop()
*/
@Override
protected void doStop() throws Exception {
logger.info("Shutting down...");
super.doStop();
if (remotingServer != null) {
logger.info("Stopping remoting server...");
remotingServer.stop();
}
applicationContext.destroy();
}
private Handler initWebAppHandler() throws IOException {
WebAppContext context = new WebAppContext(createSecurityHandler(), createSessionHandler(), null, createErrorHandler());
context.setDefaultsDescriptor("com/net365/server/jetty/webdefault.xml");
context.setContextPath(Configuration.get("webapp.contextPath", "/"));
context.setWar(Configuration.get("server.war"));
context.setExtractWAR(false);
context.setParentLoaderPriority(true);
context.setTempDirectory(new File(Configuration.get("server.tmpDir")));
context.setAttribute(B2CEshop.APPLICATION_CONTEXT_KEY, applicationContext);
if (Configuration.getBoolean("devmode", false)) {
String vhosts = Configuration.get("server.vhosts", "");
logger.info("Starting server in DevMode, vhosts: {}", vhosts);
context.setVirtualHosts(StringUtils.split(vhosts));
}
InputStream in = null;
try {
Resource resource = context.getWebInf().addPath("urlrewrite.xml");
if (resource == null || !resource.exists()) {
logger.error("Url rewrite rules not found, url rewrite will not be supported");
return context;
}
in = resource.getInputStream();
RewriteHandler handler = new RewriteHandler();
handler.setHandler(context);
handler.setRules(loadRewriteRules(in));
handler.setActionExtension(Configuration.get("webapp.action.extension"));
return handler;
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
logger.error("Error closing urlrewrite configuration file", e);
}
}
}
}
private static Rule[] loadRewriteRules(InputStream in) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true);
factory.setNamespaceAware(true);
factory.setIgnoringComments(true);
factory.setIgnoringElementContentWhitespace(true);
DocumentBuilder parser;
try {
parser = factory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
logger.error("Unable to setup XML parser for reading conf", e);
return null;
}
DefaultHandler handler = new DefaultHandler();
parser.setErrorHandler(handler);
parser.setEntityResolver(handler);
List rules = new ArrayList();
try {
Document doc = parser.parse(in);
Element rootElement = doc.getDocumentElement();
NodeList categoryList = rootElement.getChildNodes();
for (int i = 0; i < categoryList.getLength(); i++) {
Node node = categoryList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE &&
((Element) node).getTagName().equals("category")) {
String categoryName = getAttrValue(node, "name");
NodeList ruleList = node.getChildNodes();
for (int j = 0; j < ruleList.getLength(); j++) {
Node subNode = ruleList.item(j);
if (subNode.getNodeType() == Node.ELEMENT_NODE &&
((Element) subNode).getTagName().equals("rule")) {
Element ruleElement = (Element) subNode;
RewriteRegexRule rule = new RewriteRegexRule();
rule.setCategory(categoryName);
rule.setRegex(getNodeValue(ruleElement.getElementsByTagName("from").item(0)));
rule.setReplacement(getNodeValue(ruleElement.getElementsByTagName("to").item(0)));
rules.add(rule);
}
}
}
}
} catch (SAXParseException e) {
logger.error("Parse error on line " + e.getLineNumber() + " " + e.getMessage(), e);
} catch (Exception e) {
logger.error("Exception loading conf " + e.getMessage(), e);
}
return rules.toArray(new Rule[rules.size()]);
}
private static String getNodeValue(Node node) {
if (node == null) return null;
NodeList nodeList = node.getChildNodes();
if (nodeList == null) return null;
Node child = nodeList.item(0);
if (child == null) return null;
if ((child.getNodeType() == Node.TEXT_NODE)) {
String value = ((Text) child).getData();
return value.trim();
}
return null;
}
private static String getAttrValue(Node n, String attrName) {
if (n == null) return null;
NamedNodeMap attrs = n.getAttributes();
if (attrs == null) return null;
Node attr = attrs.getNamedItem(attrName);
if (attr == null) return null;
String val = attr.getNodeValue();
if (val == null) return null;
return val.trim();
}
}