web.xml中servlet:
<servlet> <!--接着顺序加载servlet被初始化-->
<!-- servlet获得控制文件Class的名字,类名 -->
<servlet-name>smvcCoreDispatcher</servlet-name>
<servlet-class>org.bluechant.mvc.core.CoreDispatcherController</servlet-class>
<init-param>
<param-name>templateLoaderPath</param-name>
<param-value>/WEB-INF/view</param-value>
</init-param>
<init-param>
<param-name>defaultEncoding</param-name>
<param-value>GBK</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/smvc_config/smvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup><!-- 加载路径 -->
</servlet>
<servlet-mapping>
<servlet-name>smvcCoreDispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>login.html</welcome-file>
</welcome-file-list>
web.xml对应的servlet控制java改写:
package org.bluechant.mvc.core;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Map;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.bluechant.mvc.controller.ModelAndView;
import org.bluechant.mvc.core.util.ServletUtils;
import freemarker.template.Configuration;
import freemarker.template.ObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
public class CoreDispatcherController extends HttpServlet {
private Logger logger = Logger.getLogger(CoreDispatcherController.class);
private CacheManager cache ;
private String baseControllerClass = "org.bluechant.mvc.controller.Controller";
private static final long serialVersionUID = 1L;
private Configuration cfg ;
private String templateLoaderPath ;
private String defaultEncoding ;
private String contentType ;
private String contextConfigLocation ;
private ActionConfig actionCoinfig ;
public void init(ServletConfig config) throws ServletException {
super.init(config);
//super.init(config);
String absPath = config.getServletContext().getRealPath("/");//获得系统绝对路径
System.out.println("absPath:"+absPath);
//getRealPath("/virtual_dir/file2.txt")应该返回"C:\site\a_virtual\file2.txt" getRealPath("/file3.txt")应该返回null,因为这个文件不存在。
///返回路径D:\Java\workspaces\helios\newshpt\获得文件路径
defaultEncoding = getInitParameter("defaultEncoding");
templateLoaderPath = getInitParameter("templateLoaderPath");
//");//从web.xml中获得templateLoaderPath信息,web.xml中对应的路径”/WEB-INF/view“
contextConfigLocation = getInitParameter("contextConfigLocation");
System.out.println("contextConfigLocation:"+contextConfigLocation);
///获得web.xml文件中路径WEB-INF/smvc_config/smvc-config.xml
actionCoinfig = new ActionConfig();
actionCoinfig.load(absPath+contextConfigLocation);//文档进行解析与读取,
///D:\Java\workspaces\helios\newshpt\WEB-INF/smvc_config/smvc-config.xml
contentType = "text/html;charset="+defaultEncoding ;
//创建Configuration实例,Configuration是入口,通过它来获得配置文件
cfg = new Configuration();
//设置模板路径, getServletContext(),所有是所有路径都能拿到的..
cfg.setServletContextForTemplateLoading(getServletContext(), templateLoaderPath);
//cfg.setServletContextForTemplateLoading(arg0, arg1)
//设置编码格式
cfg.setEncoding(Locale.getDefault(), defaultEncoding);
//init cache manager
cache = CacheManager.getInstance();
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
processRequest(request,response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
processRequest(request,response);
}
private void showRequestParams(HttpServletRequest request){
Enumeration en = request.getParameterNames();
while (en.hasMoreElements()) {
String paramName = (String) en.nextElement();
String[] paramValues = request.getParameterValues(paramName);
if (paramValues.length == 1) {
String paramValue = paramValues[0];
if (paramValue.length() != 0) {
//map.put(paramName, paramValue);
//System.out.println(paramName+"\t"+paramValue);
}
}else if(paramValues.length >1 ){//checkbox
//map.put(paramName, paramValues);
//System.out.println(paramName+"\t"+paramValues);
}
}
}
public void processRequest(HttpServletRequest request, HttpServletResponse response){
try {
request.setCharacterEncoding(defaultEncoding);
showRequestParams(request);//waiting back to resolve
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} // set request encoding
ModelAndView mv = analyzeRequest(request);
try {
invokeActionHandler(mv,request);
if(mv.getViewPath().endsWith(".ftl")){
invokeViewResolverHandler(mv , response , request);
}else{
response.sendRedirect(mv.getWebroot()+mv.getViewPath());
}
} catch (Exception e) {
e.printStackTrace();
}
}
public ModelAndView analyzeRequest(HttpServletRequest request){
ModelAndView modelAndView = new ModelAndView();
logger.debug("request url path is : "+request.getRequestURI());
String requestPath = request.getRequestURI(); // /newshpt/account!login.do
String webroot = request.getContextPath() ; // /newshpt
System.out.println("request url path is : "+requestPath);
System.out.println("request webroot path is : "+webroot);
modelAndView.setWebroot(webroot);
String actionFullName = requestPath.substring(webroot.length()); // /account!login.do
System.out.println("actionFullName : "+actionFullName);
String[] temp = actionFullName.split("!");
String method = "execute";
if(temp.length==2){
method = temp[1].split("\\.")[0];
}
System.out.println("method : "+method);
String actionName = temp[0]; // /demo
System.out.println("actionName : "+actionName);
String className = actionCoinfig.getClassName(actionName);
System.out.println("className :"+className);
modelAndView.setClassName(className);
modelAndView.setMethodName(method);
modelAndView.setAction(actionName);
return modelAndView ;
}
/**
* invoke the request controller's target method
* param ModelAndView will be mofified during the process
* @param mv
* @param request
* @throws Exception
*/
public void invokeActionHandler(ModelAndView mv , HttpServletRequest request) throws Exception{
String className = mv.getClassName();
String methodName = mv.getMethodName();
//load class
Class controllerClass = cache.loadClass(className);
Class parentControllerClass = cache.loadClass(baseControllerClass);
//load method
Method setRequest = cache.loadMethod(parentControllerClass, "setRequest", new Class[] { HttpServletRequest.class });
Method setModelAndView = cache.loadMethod(parentControllerClass, "setModelAndView", new Class[] { ModelAndView.class });//org.bluechant.mvc.controller.Controller-setModelAndView@6024418 public void org.bluechant.mvc.controller.Controller.setModelAndView(org.bluechant.mvc.controller.ModelAndView)
Method targetMethod = cache.loadMethod(controllerClass, methodName, new Class[]{});
//buiid controller instance and invoke target method
Object instance = controllerClass.newInstance();
setRequest.invoke(instance, new Object[] { request });//对带有指定参数的指定对象调用由此 Method 对象表示的基础方法
setModelAndView.invoke(instance, new Object[] { mv });
targetMethod.invoke(instance, new Object[]{});
}
/**
* send data to view model , and generate the view page by FreeMarker
*/
public void invokeViewResolverHandler(ModelAndView modelAndView , HttpServletResponse response ,HttpServletRequest request){
//convert session attributes to sessionModel , and push to modelAndView
Map sessionModel = ServletUtils.sessionAttributesToMap(request.getSession());// userSources=[/admin, /button/custom, /custom, /delivery, /loadShip, /unloadPickUp, /unloadShip]
modelAndView.put("Session", sessionModel);
response.setContentType(contentType);
try {//初始化FreeMarker
PrintWriter out = response.getWriter();
Template template = cfg.getTemplate(modelAndView.getViewPath());//取得生成模版文件
template.setTemplateExceptionHandler(TemplateExceptionHandler.DEBUG_HANDLER);//setTemplateExceptionHandler
//set the object wrapper , beanwrapper is the perfect useful objectWrapper instance
template.setObjectWrapper(ObjectWrapper.BEANS_WRAPPER);// 设置对象包装器
template.process(modelAndView, out);//模版环境开始载入..
out.flush();
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
}
}
smvc-config.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<smvc-config>
<action name="/account" class="com.cenin.tjport.shpt.mvc.controller.AccountController"/>
<action name="/yard" class="com.cenin.tjport.shpt.mvc.controller.DuiCunController"/>
</smvc-config>