您好,登錄后才能下訂單哦!
web.xml定義
<!-- spring bean 配置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 啟動時,掃描注解,把定義的url和相應的處理class數據緩存-->
<listener>
<listener-class>com.util.listener.ContextLoaderListener</listener-class>
</listener>
<!-- 過濾 字符編碼過濾 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.util.filter.CharCodeFilter</filter-class>
<init-param>
<param-name>characterEncoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 請求派發servlet -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>com.util.dispatcher.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet>
1請求派發,web容器啟動時掃描url注解
public class ContextLoaderListener implements ServletContextListener {
Logger log =LoggerFactory.getLogger(ContextLoaderListener.class);
@Override
public void contextDestroyed(ServletContextEvent arg0) {
// TODO Auto-generated method stub
log.info("context destroyed");
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
try {
new ContextRootName().setContextRootName(arg0.getServletContext().getContextPath());
//注解掃描
new AnnotationScanner().sannClasses();
//執行完controller后跳轉試圖的配置
new AnalysisView().AnalysisActionViewProperties();
} catch (ClassNotFoundException e) {
log.error(e.getMessage());
}
log.info("context inited");
}
}
2.1.1注解掃描
public class AnnotationScanner {
private static List<String> packages = new ArrayList<String>();
static{
packages.add("com.wqf.action.impl");
}
/** 要掃描的路徑 */
private static List<String> paths = null;
//TODO 掃描到需要的類方法需要更改
public void sannClasses() throws ClassNotFoundException{
String rootPath=getClass().getResource("/").getFile().toString();
paths = getPaths();
for(String path:paths){
File rootFile = new File(path);
File [] files = rootFile.listFiles();
String packageName = path.replace(rootPath, "").replace('/', '.') + ".";
for(File f: files) {
String className = f.getName().substring(0, f.getName().indexOf(".class"));
Class<?> clazz = Class.forName(packageName+className);
parseClass(clazz);
}
}
}
public void parseClass(Class<?> clazz) {
String url1= "";
String url2= "";
Annotation[] annotations = clazz.getAnnotations();
for(Annotation annotation:annotations){
if(annotation.annotationType().getSimpleName().equals("NameSpace")){
NameSpace nameSpace = (NameSpace)annotation;
url1 = nameSpace.nameSpace();
}
}
Method[] methods = clazz.getDeclaredMethods();
for(Method method:methods){
Annotation[] methodannotations = method.getAnnotations();
for(Annotation annotation:methodannotations){
if(annotation.annotationType().getSimpleName().equals("RequestMapping")){
RequestMapping requestMapping = (RequestMapping)annotation;
url2 = requestMapping.mapping();
MapClassMethodBean data = new MapClassMethodBean();
data.setBean(clazz);
data.setM(method);
String url = modifyUrl(url1 + url2);
RequestData.setData(url, data);
}
}
}
}
private static String modifyUrl(String url){
return url;
}
//TODO 拿到路徑要改為從xml配置文件讀取
private List<String> getPaths(){
String rootPath=getClass().getResource("/").getFile().toString();
List<String> stringList = new ArrayList<String>();
for(String scanPackage:packages){
String tmpPath = scanPackage.replace('.', '/');
stringList.add(rootPath + tmpPath);
}
return stringList;
}
}
2.1.2controller和跳轉到jsp頁面的配置
///firstAction/test.do = test.jsp
public class AnalysisView {
private String viewPath = "/resource/viewNamesProp";
public void AnalysisActionViewProperties() {
Properties prop = new Properties();
FileInputStream in;
try {
String rootPath=getClass().getResource("/").getFile().toString();
in = new FileInputStream(rootPath + viewPath);
prop.load(in);
Iterator<String> it = prop.stringPropertyNames().iterator();
while (it.hasNext()) {
String key=it.next();
ViewNameData.setData(key, prop.getProperty(key));
}
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.核心派發servlet
public class DispatcherServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
Logger log = LoggerFactory.getLogger(DispatcherServlet.class);
IBaseAction action = null;
private String JSP = "jsp";
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// log.error("禁止get請求");
// return;
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/**
* 判斷請求類型分給不同的Class進行派發
*/
// String suffix = "";
// if(actionName.indexOf(".") != -1){
// suffix = actionName.substring(actionName.indexOf(".") + 1,actionName.indexOf("?")== -1 ? actionName.length():actionName.indexOf("?") -1);
// }
// if(JSP.equals(suffix)){
// JspDispatcherServlet.getInstance().doPost(req, resp);
// return;
// }
try {// 捕捉異常不拋到前臺
String actionName = req.getServletPath();
actionName = actionName.indexOf("?") == -1 ? actionName :actionName.substring(0, actionName.indexOf("?"));
/** 實際業務的class */
Class<?> clazz = null;
/** 實際業務的方法 */
Method method = null;
/** 前臺傳遞的變量統一封裝到context內 */
Context context = ContextFactory.createContext(req, resp);
// ProxyHandler handler = new ProxyHandler();
String url = actionName.indexOf(".") == -1 ?actionName:actionName.substring(0, actionName.indexOf("."));
// 根據請求找到相應的action
MapClassMethodBean classMethodBean = RequestData.getData(url);
if (classMethodBean == null) {
log.info("該URL 未配置");
sendRedirect(ViewNameData.getNotFoundPage(),req,resp);
return;
}
clazz = classMethodBean.getBean();
method = classMethodBean.getM();
CglibProxyHandler cglibProxy = new CglibProxyHandler();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
enhancer.setCallback(cglibProxy);
// Object target = clazz.cast(ac.getBean(clazz));
// handler.setTarget(target);
// Object o =
// Proxy.newProxyInstance(target.getClass().getClassLoader(),
// target.getClass().getInterfaces(),
// handler);
Object o = enhancer.create();
Method[] omethods = o.getClass().getDeclaredMethods();
for (Method omethod : omethods) {
if (omethod.getName().equals(method.getName())) {
try {
omethod.invoke(o, context);
} catch (IllegalAccessException e) {
log.warn(e.getMessage());
} catch (IllegalArgumentException e) {
log.warn(e.getMessage());
} catch (InvocationTargetException e) {
log.warn(e.getMessage());
}
}
}
// 如果有對應的視圖,跳轉的相應的視圖
String viewName = ViewNameData.getData(actionName);
if (viewName != null) {
sendRedirect(viewName,req,resp);
}
// 如果沒有對應的視圖
} catch (Exception e1) {
log.error(e1.getMessage());
sendRedirect(ViewNameData.getErrorPage(),req,resp);
}
}
private void sendRedirect(String fordardPage,HttpServletRequest req, HttpServletResponse resp) throws IOException{
String rootUrl = req.getScheme() + "://" + req.getServerName()
+ ":" + req.getServerPort()
+ req.getContextPath();
resp.sendRedirect(rootUrl + "/" + fordardPage);
}
}
總結:web容器啟動的時候通過listener掃描contrller所在包的注解,形成Map<String url, BeanMethod<Class controller, String method>>的數據,請求來的時候走DispatcherServlet,根據請求的url找到相應的controller和method處理請求。
如果請求后配置的有相應jsp頁面跳轉到相應的jsp頁面。
一個簡單實現,比較差。各位看官權當娛樂,工程代碼后續再傳,吐槽51job的審核!!!
工程代碼地址:http://down.51cto.com/data/2327225
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。