請求轉發器
 
 用于處理用戶發送給的請求。
 
 
我們需要一個Servlet來處理所有的請求 
 這是HttpServlet的處理請求的service函數源碼
 
protected void service(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {String method = req.getMethod();
long errMsg;
if(method.equals(
"GET")) {errMsg = 
this.getLastModified(req);
if(errMsg == -
1L) {
this.doGet(req, resp);} 
else {
long ifModifiedSince = req.getDateHeader(
"If-Modified-Since");
if(ifModifiedSince < errMsg) {
this.maybeSetLastModified(resp, errMsg);
this.doGet(req, resp);} 
else {resp.setStatus(
304);}}} 
else if(method.equals(
"HEAD")) {errMsg = 
this.getLastModified(req);
this.maybeSetLastModified(resp, errMsg);
this.doHead(req, resp);} 
else if(method.equals(
"POST")) {
this.doPost(req, resp);} 
else if(method.equals(
"PUT")) {
this.doPut(req, resp);} 
else if(method.equals(
"DELETE")) {
this.doDelete(req, resp);} 
else if(method.equals(
"OPTIONS")) {
this.doOptions(req, resp);} 
else if(method.equals(
"TRACE")) {
this.doTrace(req, resp);} 
else {String errMsg1 = lStrings.getString(
"http.method_not_implemented");Object[] errArgs = 
new Object[]{method};errMsg1 = MessageFormat.format(errMsg1, errArgs);resp.sendError(
501, errMsg1);}} 
我們可以知道 ,這個是通過方法的類型不同進行轉向不同的函數進行出處理。 
 而我們需要把 
 get:customer_show 
 post:customer_create 
 暫時先不討論符合restful的url 
 我們可以設置一個注解@Action用來和spring的RequestMapping方法一樣 
 但是我們這個看上去不像RequestMapping中那樣的繁瑣 
 具體可參照smart-framework 點擊跳轉oschina文檔首頁
 
- 先預處理request與handler的映射 
 - 加載帶有Controller注解的類
 - 掃描Action注解來獲取到get:customer_show這個屬性的值
 - 通過正則表達式\\w:/\\w*匹配
 - 分割字符串
 - 添加一個handler用于接受請求并執行方法,返回結果
 - 添加request(格式請求方法類型:請求路徑)-handler映射
 
 
 
/*** Created by xueaohui on 2016/6/22.*/
public final class ControllerHelper {/*** 用來存放請求與處理器的映射關系(Action Map)*/private static final Map<Request,Handler> ACTION_MAP = 
new HashMap<Request, Handler>();
static {Set<Class<?>> controllerClassSet = ClassHelper.getControllerClassSet();
if(CollectionUtil.isNotEmpty(controllerClassSet)){
for(Class<?> controllerClass : controllerClassSet){Method[] methods = controllerClass.getMethods();
if(ArrayUtil.isNotEmpty(methods)) {
for (Method method : methods) {
if(method.isAnnotationPresent(Action.class)){Action action = method.getAnnotation(Action.class);String mapping = action.value();
if(mapping.matches(
"\\w+:/\\w*")){String[] array = mapping.split(
":");
if(ArrayUtil.isNotEmpty(array)){String requestMethod = array[
0];String requestPath = array[
1];Request request = 
new Request(requestMethod,requestPath);Handler handler = 
new Handler(controllerClass,method);ACTION_MAP.put(request,handler);}}}}}}}}
/*** 獲取Handler*/public static Handler 
getHandler(String requestMethod ,  String requestPath){Request request = 
new Request(requestMethod,requestPath);
return ACTION_MAP.get(request);}
}
 
獲取了我們就可以直接service方法寫業務邏輯處理請求了 
 返回結果 有兩種方式 
 json 和 jsp頁面
 
package org.smart4j.framework;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.Map;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.smart4j.framework.bean.Data;
import org.smart4j.framework.bean.Handler;
import org.smart4j.framework.bean.Param;
import org.smart4j.framework.bean.View;
import org.smart4j.framework.helper.BeanHelper;
import org.smart4j.framework.helper.ConfigHelper;
import org.smart4j.framework.helper.ControllerHelper;
import org.smart4j.framework.helper.RequestHelper;
import org.smart4j.framework.helper.ServletHelper;
import org.smart4j.framework.helper.UploadHelper;
import org.smart4j.framework.util.JsonUtil;
import org.smart4j.framework.util.ReflectionUtil;
import org.smart4j.framework.util.StringUtil;
/*** 請求轉發器**/
@WebServlet(urlPatterns = 
"/*", loadOnStartup = 
0)
public class DispatcherServlet extends HttpServlet {@Overridepublic void init(ServletConfig servletConfig) 
throws ServletException {HelpLoader.init();ServletContext servletContext = servletConfig.getServletContext();registerServlet(servletContext);UploadHelper.init(servletContext);}
private void registerServlet(ServletContext servletContext) {ServletRegistration jspServlet = servletContext.getServletRegistration(
"jsp");jspServlet.addMapping(
"/index.jsp");jspServlet.addMapping(ConfigHelper.getAppJSpPath() + 
"*");ServletRegistration defaultServlet = servletContext.getServletRegistration(
"default");defaultServlet.addMapping(
"/favicon.ico");defaultServlet.addMapping(ConfigHelper.getAppAssetPath() + 
"*");}
@Overridepublic void service(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException {ServletHelper.init(request, response);
try {String requestMethod = request.getMethod().toLowerCase();String requestPath = request.getPathInfo();Handler handler = ControllerHelper.getHandler(requestMethod, requestPath);
if (handler != 
null) {Class<?> controllerClass = handler.getControllerClass();Object controllerBean = BeanHelper.getBean(controllerClass);Param param;
if (UploadHelper.isMultipart(request)) {param = UploadHelper.createParam(request);} 
else {param = RequestHelper.createParam(request);}Object result;Method actionMethod = handler.getActionMethod();
if (param.isEmpty()) {result = ReflectionUtil.invokeMethod(controllerBean, actionMethod);} 
else {result = ReflectionUtil.invokeMethod(controllerBean, actionMethod, param);}
if (result 
instanceof View) {handleViewResult((View) result, request, response);} 
else if (result 
instanceof Data) {handleDataResult((Data) result, response);}}} 
finally {ServletHelper.destroy();}}
/*** 轉發返回頁面的請求*/private void handleViewResult(View view, HttpServletRequest request, HttpServletResponse response) 
throws IOException, ServletException {String path = view.getPath();
if (StringUtil.isNotEmpty(path)) {
if (path.startsWith(
"/")) {response.sendRedirect(request.getContextPath() + path);} 
else {Map<String, Object> model = view.getModel();
for (Map.Entry<String, Object> entry : model.entrySet()) {request.setAttribute(entry.getKey(), entry.getValue());}request.getRequestDispatcher(ConfigHelper.getAppJSpPath() + path).forward(request, response);}}}
/*** 轉發返回json數據的請求*/private void handleDataResult(Data data, HttpServletResponse response) 
throws IOException {Object model = data.getModel();
if (model != 
null) {response.setContentType(
"application/json");response.setCharacterEncoding(
"UTF-8");PrintWriter writer = response.getWriter();String json = JsonUtil.toJson(model);writer.write(json);writer.flush();writer.close();}}
}
 
點擊查看書上代碼  
 點擊查看最新代碼
                            總結
                            
                                以上是生活随笔為你收集整理的架构探险-从零开始写Javaweb框架读书笔记(4)的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                            
                                如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。