mvc-servlet

        网页每发一个不同的请求都需要一个servlet去响应,这样servlet很多很乱。可以只写一个servlet对请求作响应,但是servlet内部可以有很多方法,对不同请求作响应。

        如下,使用一个operation参数记录网页要求的操作,然后用switch语句转向不同函数进行处理:

 //设置编码方式防止汉字乱码
        req.setCharacterEncoding("UTF-8");
        //根据发送的请求中的operation字段选择方法
        String oper=req.getParameter("operation");
        if (oper==null){
            oper="index";
        }
        switch (oper){
            case "index":
                indexServlet(req,resp);
                break;
            case "edit":
                editServlet(req,resp);
                break;
            case "del":
                delServlet(req,resp);
                break;
            case "insert":
                insertServlet(req,resp);
                break;
            case "update":
                updateServlet(req,resp);
                break;
            default:
                throw new RuntimeException("illegal value for operation");
        }

   一、dispatcherServlet

        如果网页请求很多,那switch...case...语句会很长。使用反射改写:

 //获取当前类中的所有方法(反射),如果方法名和operation参数相同,就调用该方法
        Method[] methods=this.getClass().getDeclaredMethods();
        for (Method m:methods){
            System.out.println(m.getName());
        }
        for (Method m:methods){
            if(oper.equals(m.getName())){
                try {
                    m.invoke(this,req,resp);
                    return;
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }

Notations;(1)声明的方法名要和operation值相等;(2)getDeclaredMethods才是获取自己声明的方法。

        而在实际中,会有很多servlet类,而每个之中会有很多方法。会有一个dispatcherServlet(中央控制器)来接收前端的请求,然后进行转发到各个类进行处理。可以将对某个请求的所有操作写在一个Controller里面,然后使用一个中央控制器将请求转发给处理它的Controller。

        现在src下新建一个xml,将请求和Controller的对应关系写到一个标签里面:      





    
  

         然后建立一个中央控制器,获得该文件中的bean标签的对应关系,用一个map存储,这个map称为容器。然后接收到请求后,通过反射查询相应Controller中的所有方法。

//*是通配符。表示拦截所有结尾.do的请求
//通配符不能只写一个*
@WebServlet("*.do")
public class DispatcherServlet extends ViewBaseServlet {

    //创建一个Map用来存放xml的bean标签中的id和class对应。Object是其中class的实例对象
    Map beanMap=new HashMap();
    //在构造方法中解析xml配置文件
    public DispatcherServlet() throws ParserConfigurationException, IOException, SAXException, ClassNotFoundException, IllegalAccessException, InstantiationException {
        //打开配置文件的流
        InputStream is=getClass().getClassLoader().getResourceAsStream("applicationController.xml");
        //创建一个 DocumentBuilder对象
        DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
        DocumentBuilder db=dbf.newDocumentBuilder();
        //创建Document对象
        Document doc=db.parse(is);
        //获取xml中所有的bean节点
        NodeList beanList=doc.getElementsByTagName("bean");
        for(int i=0;i

  二、提取视图资源

       在经过Controller的方法处理请求后,一般方法最后会进行重定向或者对当前页面渲染。可以在中央控制器对此集中处理,让方法只返回一个字符串。这样方法可以少抛出异常,也可以不用传入response参数。如下所示:

  //oper去匹配函数名字,后面是参数对象的class
            Method m=beanObject.getClass().getDeclaredMethod(oper,HttpServletRequest.class);
                m.setAccessible(true);
                if(m!=null){
                    if(m.invoke(beanObject,req)!=null){
                        String redirectStr=(String) m.invoke(beanObject,req);
                        //将该str截取,只保留后面的请求名称
                        if(redirectStr.startsWith("redirect:")){
                            redirectStr=redirectStr.substring("redirect:".length());
                            //重定向
                            resp.sendRedirect(redirectStr);
                        }else{
                            super.processTemplate(redirectStr,req,resp);
                        }
                    }
            }else{
                throw new RuntimeException("oper值非法");
            }

三、在中央控制器处理参数

        在Controller的每个函数中都有获取请求中函数的操作,那么可以将此直接在中央控制器处理。如下:

                   //获取参数,先反射获取所有参数
                    Parameter[] p=m.getParameters();
                    //保存参数请求request中各个参数的值,所以函数的参数名要和前端发射的请求的参数名称一样
                    Object[] parameterValue=new Object[p.length];
                    //如果参数是request,response,session就是直接获取
                    for (int i=0;i

        

你可能感兴趣的:(servlet,mvc,java)