package org.eh.core.http; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URI; import java.net.URLDecoder; import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eh.core.annotation.AnnocationHandler; import org.eh.core.common.Constants; import org.eh.core.common.ReturnType; import org.eh.core.model.ResultInfo; import org.eh.core.util.FileUploadContentAnalysis; import org.eh.core.util.IOUtil; import org.eh.core.util.StringUtil; import org.eh.core.web.controller.Controller; import org.eh.core.web.view.ViewHandler; import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; /** * 处理Http请求 * @author guojing * @date 2014-3-3 */ public class EHHttpHandler implements HttpHandler { private final Log log = LogFactory.getLog(EHHttpHandler.class); public void handle(HttpExchange httpExchange) throws IOException { try { String path = httpExchange.getRequestURI().getPath(); log.info("Receive a request,Request path:" + path); // 设置sessionId String sessionId = ApplicationContext.getApplicationContext() .getSessionId(httpExchange); if (StringUtil.isEmpty(sessionId)) { sessionId = StringUtil.creatSession(); ApplicationContext.getApplicationContext().addSession(sessionId); } httpExchange.getResponseHeaders().set("Set-Cookie", "EH_SESSION=" + sessionId + "; path=/"); // 根据后缀判断是否是静态资源 String suffix = path.substring(path.lastIndexOf("."), path.length()); if (Constants.STATIC_SUFFIXS.contains(suffix)) { byte[] bytes = IOUtil.readFileByBytes(Constants.CLASS_PATH + "static" + path); responseStaticToClient(httpExchange, 200, bytes); return; } // 调用对应处理程序controller ResultInfo resultInfo = invokController(httpExchange); // 返回404 if (resultInfo == null || StringUtil.isEmpty(resultInfo.getView())) { responseToClient(httpExchange, 200, "<h1>页面不存在<h1>"); return; } String viewPath = resultInfo.getView(); if (viewPath.startsWith(ReturnType.redirect.name())) {// redirect跳转 String redirectUrl = viewPath.replace(ReturnType.redirect.name() + ":", ""); responseToClient(httpExchange, 302, redirectUrl); return; } else if (viewPath.startsWith(ReturnType.json.name())) { // 返回json数据 String jsonContent = viewPath.replace(ReturnType.json.name() + ":", ""); responseToClient(httpExchange, 200, jsonContent); return; } else if (viewPath.startsWith(ReturnType.velocity.name())) { // 解析对应view并返回 String content = invokViewHandler(resultInfo); if (content == null) { content = ""; } responseToClient(httpExchange, 200, content); return; } else { responseToClient(httpExchange, 200, resultInfo.getView()); return; } } catch (Exception e) { httpExchange.close(); log.error("响应请求失败:", e); } } /** * 响应请求 * @param httpExchange 请求-响应的封装 * @param code 返回状态码 * @param msg 返回信息 * @throws IOException */ private void responseToClient(HttpExchange httpExchange, Integer code, String msg) throws IOException { switch (code) { case 200: { // 成功 byte[] bytes = msg.getBytes(); httpExchange.sendResponseHeaders(code, bytes.length); OutputStream out = httpExchange.getResponseBody(); out.write(bytes); out.flush(); httpExchange.close(); } break; case 302: { // 跳转 Headers headers = httpExchange.getResponseHeaders(); headers.add("Location", msg); httpExchange.sendResponseHeaders(code, 0); httpExchange.close(); } break; case 404: { // 错误 byte[] bytes = "".getBytes(); httpExchange.sendResponseHeaders(code, bytes.length); OutputStream out = httpExchange.getResponseBody(); out.write(bytes); out.flush(); httpExchange.close(); } break; default: break; } } /** * 响应请求,返回静态资源 * @param httpExchange * @param code * @param bytes * @throws IOException */ private void responseStaticToClient(HttpExchange httpExchange, Integer code, byte[] bytes) throws IOException { httpExchange.sendResponseHeaders(code, bytes.length); OutputStream out = httpExchange.getResponseBody(); out.write(bytes); out.flush(); httpExchange.close(); } /** * 调用对应Controller处理业务 */ @SuppressWarnings("rawtypes") private ResultInfo invokController(HttpExchange httpExchange) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException { String path = httpExchange.getRequestURI().getPath(); String classPath = Constants.UrlClassMap.get(path.substring(0, path.lastIndexOf("/") + 1)); if (classPath == null || classPath.length() == 0) { return null; } Class controllerClass = Class.forName(classPath); Controller controller = (Controller) controllerClass.newInstance(); String methodName = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")); //通过反射获取对应方法 AnnocationHandler annocationHandler = new AnnocationHandler(); Method method = annocationHandler.getMethod(controllerClass, methodName); Map<String, Object> map = null; // 参数 // 判断表单类型,若是multipart/form-data,则是文件上传;否则做普通处理 Headers headers = httpExchange.getRequestHeaders(); // 获取ContentType String contentType = ""; if(null != headers.get("Content-type")){ contentType = headers.get("Content-type").toString().replace("[", "") .replace("]", ""); } if (contentType.indexOf("multipart/form-data") != -1) { // 获取content长度 int length = Integer.parseInt(headers.get("Content-length").toString().replace("[", "") .replace("]", "")); map = FileUploadContentAnalysis.parse(httpExchange.getRequestBody(), contentType, length); } else { map = analysisParms(httpExchange); } // 设置session HttpSession httpSession = ApplicationContext.getApplicationContext().getSession( httpExchange); map.put("session", httpSession); return (ResultInfo) method.invoke(controller, new Object[] { map }); } /** * 调用ViewHandler渲染视图 */ private String invokViewHandler(ResultInfo resultInfo) throws IOException { ViewHandler viewHandler = new ViewHandler(); // return viewHandler.processView(resultInfo); return viewHandler.processVelocityView(resultInfo); } /** * 解析参数 */ private Map<String, Object> analysisParms(HttpExchange httpExchange) throws UnsupportedEncodingException { Map<String, Object> map = new HashMap<String, Object>(); URI requestedUri = httpExchange.getRequestURI(); String queryGet = requestedUri.getRawQuery(); String queryPost = IOUtil.getRequestContent(httpExchange.getRequestBody()); String query = ""; if (!StringUtil.isEmpty(queryGet)) { query = queryGet; } if (!StringUtil.isEmpty(queryPost)) { query = StringUtil.isEmpty(query) ? queryPost : (query + "&" + queryPost); } if (StringUtil.isEmpty(query)) { return map; } for (String kv : query.split("&")) { String[] temp = kv.split("="); map.put(temp[0], URLDecoder.decode(temp[1], "utf-8")); } return map; } }