osgi中暂时不支持springmvc等mvc框架,我们每写一个方法的时候,就需要新建一个servlet,这样很麻烦,所以想自己实现一个在osgi环境下能够运行的mvc框架,模仿springmvc或者struts2的框架。
1.首先我们看看web.xml的配置。里面定义了一个servlet,去过滤所有带.do的uri,初始化参数有controller类。当容器启动的时候,会执行servlet的init方法,然后把controller类初始化。以便后来调用。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>com.yyc.servlet.Dispatcher</servlet-class>
<init-param>
<param-name>login</param-name>
<param-value>com.yyc.controller.Login</param-value>
</init-param>
<init-param>
<param-name>main</param-name>
<param-value>com.yyc.controller.Main</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
2.Dispatchar.java继承了servlet,覆盖了init方法,doGet doPost方法。init把controller类实例化后放入map,如果后面有uir请求,去截取请求的uir获取里面的类,和方法名。
然后用java反射机制去执行。
package com.yyc.servlet;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Dispatcher extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
Map<String , Object> controllers = new HashMap<String , Object>();
private ServletContext application = null;//一个web应用程序对应一个ServletContext
private ServletConfig config = null; //一个Servlet对应一个ServletConfig
@Override
public void init() throws ServletException{
//创建controller bean
//读取web.xml配置参数 放入controllers
application = getServletContext();
config = getServletConfig();
Enumeration<String> enumeration = config.getInitParameterNames();
while(enumeration.hasMoreElements()){
String className = enumeration.nextElement();
//通过获取init获取参数
BeanFactory(className, config.getInitParameter(className));
}
super.init();
}
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String uri = request.getRequestURI();
String classMethodName = uri.substring(uri.lastIndexOf("/")+1,uri.lastIndexOf(".do"));
String className = classMethodName.split("_")[0];
String methodName = classMethodName.split("_")[1];
Object controller = controllers.get(className);
try {
controller.getClass().getMethod(methodName,new Class[]{HttpServletRequest.class,HttpServletResponse.class}).invoke(controller.getClass().newInstance(),new Object[]{request,response});
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void BeanFactory(String className,String classPath){
try {
Class<?> clazz = Class.forName(classPath);
controllers.put(className, clazz.newInstance());
System.out.println("初始化类"+className);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
下面是controller的类
login.java
package com.yyc.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Login {
public void in(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("登陆!");
response.sendRedirect("index.jsp");
}
public void out(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.getWriter().print("you logout!");
System.out.println("退出!");
}
}
main.java
package com.yyc.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Main {
public void index(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("进入主页!");
}
}
启动后,可以这样调用:
http://localhost:8080/dispatcher/login_in.do login需要对应web.xml里面的servlet对应参数的值,in是对应类里面的方法名
http://localhost:8080/dispatcher/login_out.do
http://localhost:8080/dispatcher/main_index.do
这里实现了最简单的分发功能,目的是减少多余的配置 ,下次研究osgi' blueprint里面进行配置处理,以及依赖注入
BlueprintContainer container = (BlueprintContainer) getServletContext().getAttribute(BlueprintContextListener.CONTAINER_ATTRIBUTE);
List<Account> accounts = (List<Account>) container.getComponentInstance("accounts");