MVC框架
1.在web.xml文件配置
<servlet>
<servlet-name>ActionServlet</servlet-name>
<servlet-class>com.d.servlet.ActionServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ActionServlet</servlet-name>
//只接受以.do结尾的服务请求
<url-pattern>*.do</url-pattern>
</servlet-mapping>
2.在WEB-INF文件夹下写一个config.xml文件
path:客户端的请求命令
type:处理请求的全限定名
path:提交页面数据的实体类路径
<actions>
//可有多个action
<action path="" type="" name=""></action>
</actions>
3.写一个ActionServlet.java文件继承Httpservlet
在dopost方法内
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取properties中的值对象
String uri = req.getRequestURI();
String actionname = uri.substring(uri.lastIndexOf("/")+1, uri.indexOf("."));
//通过值对象获取到对应的全限定名
ActionMapping am = m.get(actionname);
HttpSession session = req.getSession();
session.removeAttribute("path");
session.setAttribute("path", actionname);
try {
//通过执行类路径获取执行类
Class c2 = Class.forName(am.getType());
if(am.getName().equals("com.d.Action.ActionForm")) {
System.out.println(am.getType());
Action o = (Action)c2.newInstance();
ActionForward tz = o.execute(null, req, resp);
if(tz!=null) {
tz.forward(req, resp);
}
}else{
System.out.println("有实体类");
//通过实体类路径获取实体类
Class c= Class.forName(am.getName());
//获取类对象的实例化对象,因为实体类都继承了ActionForward 在这里使用到了多态
ActionForm af= (ActionForm) c.newInstance();
//收集页面提交数据
Map<String, String> map=new HashMap<String, String>();
//获取到表单提交的数据
Enumeration<String> enu = req.getParameterNames();
while(enu.hasMoreElements()){
//获取到表单的属性名
String name = enu.nextElement();
//根据属性名获取属性信息
String value = req.getParameter(name);
map.put(name, value);
}
//通过populate给实体类赋值,af里面的值就是con表单提交上来的值了
BeanUtils.populate(map, af);
Action o = (Action)c2.newInstance();
ActionForward tz = o.execute(af, req, resp);
if(tz!=null) {
tz.forward(req, resp);
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
在文件内定义一个
Map<String, ActionMapping> m=new HashMap<>();
然后重写init方法获取config.xml文件里的属性与值
@Override
public void init() throws ServletException {
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db=dbf.newDocumentBuilder();
Document doc = db.parse(this.getServletContext().getResourceAsStream("/WEB-INF/config.xml"));
NodeList actions = doc.getElementsByTagName("action");
for (int i = 0; i < actions.getLength(); i++) {
Element action = (Element) actions.item(i);
String path = action.getAttribute("path");
String type = action.getAttribute("type");
String name = action.getAttribute("name");
m.put(path, new ActionMapping(path, type, name));
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
*注意:要写一个BeanUtils .java文件用于通过设置的实体类将页面获取的值赋值到实体类对象中
public class BeanUtils {
public static void populate(Map<String, String> map,Object obj) {
Class c = obj.getClass();
Field[] ff = c.getDeclaredFields();
for(String name:map.keySet()){
//name==属性名
//value==表单提交的数据
String value=map.get(name);
//我要将value的值通过set方法放入传入的object类中
try {
//先获取属性,因为后面咱们要获取属性的数据类型
System.out.println(name);
Field field=c.getDeclaredField(name);
field.setAccessible(true);
//获取set方法
StringBuffer sb=new StringBuffer("set");
sb.append(name.substring(0,1).toUpperCase());
sb.append(name.substring(1));
//获取类的set方法
Method method=c.getDeclaredMethod(sb.toString(), field.getType());
//判断传入的参数是什么类型的,因为传值的时候会有转型错误
//而且有多种数据类型,所以用object接受
Object os;
if(field.getType().getName().equals("java.sql.Date")) {
//判断是否是sql.date类型
os=Date.valueOf(value);
}else {
//调用当前属性的数据类型的构造方法并且构造方法的参数类型是string类型的
//获取之后实例化 :Integer i=new Integer("11111");
os=field.getType().getConstructor(String.class).newInstance(value);
}
//赋值,调用方法,
method.invoke(obj, os);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
4.写一个Action.java文件
将该文件设置成接口,然后作为作为各个完成请求的文件的接口规范
public interface Action {
public ActionForward execute(ActionForm form,HttpServletRequest req,HttpServletResponse resp);
}
5.写一个ActionForm.java文件
将所有实体类都继承ActionForm,在ActionForm里面不写任何东西
6.写一个ActionForward.java文件
用于判断处理请求之后是请求转发还是重定向
isRedirect:false 重定向
isRedirect:true 请求转发
public class ActionForward {
private String path;
private boolean isRedirect=false;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public boolean isRedirect() {
return isRedirect;
}
public void setRedirect(boolean isRedirect) {
this.isRedirect = isRedirect;
}
public void forward(HttpServletRequest req,HttpServletResponse resp) {
try {
if(isRedirect) {
req.getRequestDispatcher(path).forward(req, resp);
}else {
resp.sendRedirect(path);
}
} catch (Exception e) {
// TODO: handle exception
}
}
public ActionForward(String path, boolean isRedirect) {
super();
this.path = path;
this.isRedirect = isRedirect;
}
}
7.写一个ActionMapping.java文件
用于接受config.xml里action标签里的属性:path,name,type
public class ActionMapping {
private String path;
private String type;
private String name;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ActionMapping(String path, String type, String name) {
super();
this.path = path;
this.type = type;
this.name = name;
}
}
8.在处理请求的实体类中,将该类实现Action接口
用于接受config.xml里action标签里的属性:path,name,type
public ActionForward execute(ActionForm form, HttpServletRequest req, HttpServletResponse resp) {方法体}