• 自定义MVC框架(二) -基于XML文件


    1.oracle的脚本

     1 create table STUDENT
     2 (
     3   sid   NUMBER primary key,
     4   sname VARCHAR2(20),
     5   age   NUMBER,
     6   pwd   VARCHAR2(20)
     7 )
     8 
     9 create sequence seq_student;
    10 
    11 insert into STUDENT (sid, sname, age, pwd)
    12 values (seq_student.nextval, 'holly', 18, '123');
    13 insert into STUDENT (sid, sname, age, pwd)
    14 values (seq_student.nextval, '钱涛', 108, '123');
    15 insert into STUDENT (sid, sname, age, pwd)
    16 values (seq_student.nextval, '张睿', 10, '123');
    17 insert into STUDENT (sid, sname, age, pwd)
    18 values (seq_student.nextval, '修地', 16, '123');
    19 commit;
    student.sql

    2.创建如下的项目结果

    (并在WebRoot下的lib文件夹下添加dom4j-1.6.1.jar和ojdbc14.jar)

    3.在com.javabean包下创建Student.java文件

     1 package com.javabean;
     2 /**
     3  * 学生类
     4  * @author Holly老师
     5  *
     6  */
     7 public class Student {
     8     /*学生编号*/
     9     private int sid;
    10     /*学生姓名*/
    11     private String sname;
    12     /*学生密码*/
    13     private String pwd;
    14     /*年龄*/
    15     private int age;
    16     
    17     public Student() {
    18         super();
    19     }
    20 
    21     public Student(int sid, String sname, String pwd, int age) {
    22         super();
    23         this.sid = sid;
    24         this.sname = sname;
    25         this.pwd = pwd;
    26         this.age = age;
    27     }
    28 
    29     public Student(int sid, String sname, int age) {
    30         super();
    31         this.sid = sid;
    32         this.sname = sname;
    33         this.age = age;
    34     }
    35 
    36     public int getSid() {
    37         return sid;
    38     }
    39 
    40     public void setSid(int sid) {
    41         this.sid = sid;
    42     }
    43 
    44     public String getSname() {
    45         return sname;
    46     }
    47 
    48     public void setSname(String sname) {
    49         this.sname = sname;
    50     }
    51 
    52     public int getAge() {
    53         return age;
    54     }
    55 
    56     public void setAge(int age) {
    57         this.age = age;
    58     }
    59 
    60     public String getPwd() {
    61         return pwd;
    62     }
    63 
    64     public void setPwd(String pwd) {
    65         this.pwd = pwd;
    66     }
    67     
    68 
    69 }
    Student.java

    4.在com.dao包下创建BaseDao.java

    package com.dao;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    /**
     * 链接数据库的工具类
     * @author Holly老师
     */
    public class BaseDao {
        /**链接数据库的字符串*/
        private static final String driver="oracle.jdbc.driver.OracleDriver";
        private static final String url="jdbc:oracle:thin:@127.0.0.1:1521:orcl";
        private static final String user="holly";
        private static final String password="sys";
        /**数据库操作的对象*/
        public Connection conn=null;
        public PreparedStatement pstm=null;
        public ResultSet rs=null;
        /**
         * 加载驱动
         */
        static{
            try {
                Class.forName(driver);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        
        /**
         * 获取数据库链接
         * @return
         */
        public Connection getConnection(){
            try {
                conn=DriverManager.getConnection(url, user, password);
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return conn;
        }
        
        /**
         * 查询公共方法
         * @param sql
         * @param param
         * @return
         */
        public ResultSet executeQuery(String sql,Object[] param){
            conn=this.getConnection();
            try {
                pstm=conn.prepareStatement(sql);
                if(param!=null){
                    for (int i = 0; i < param.length; i++) {
                        pstm.setObject(i+1, param[i]);
                    }
                }
                rs=pstm.executeQuery();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return rs;
        }
        /**
         * 增删改通用方法
         * @param sql
         * @param param
         * @return
         */
        public int executeUpdate(String sql,Object[] param){
            conn=this.getConnection();
            int num=0;
            try {
                pstm=conn.prepareStatement(sql);
                if(param!=null){
                    for (int i = 0; i < param.length; i++) {
                        pstm.setObject(i+1, param[i]);
                    }
                }
                num=pstm.executeUpdate();
            } catch (SQLException e) {
                e.printStackTrace();
            }finally{
                this.closeAll(conn, pstm, rs);
            }
            return num;
        }
        /**
         * 释放资源
         * @param conn
         * @param pstm
         * @param rs
         */
        public void closeAll(Connection conn,PreparedStatement pstm,ResultSet rs){
            try {
                if(rs!=null){
                    rs.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                if(pstm!=null){
                    pstm.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                if(conn!=null){
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    BaseDao.java

    5.在com.dao包下创建StudentDao.java

     1 package com.dao;
     2 
     3 
     4 import com.javabean.Student;
     5 /**
     6  * 
     7  * @author Holly老师
     8  *
     9  */
    10 public interface StudentDao {
    11     /**
    12      * 根据用户名和密码查询
    13      * @param sname
    14      * @param pwd
    15      * @return
    16      */
    17     Student getByNameAndPwd(String sname,String pwd);
    18 
    19 }
    StudentDao.java

    6.在com.dao.impl包下创建StudentDaoImpl.java

     1 package com.dao.impl;
     2 
     3 import java.sql.SQLException;
     4 import java.util.ArrayList;
     5 import java.util.List;
     6 
     7 import com.dao.BaseDao;
     8 import com.dao.StudentDao;
     9 import com.javabean.Student;
    10 /**
    11  * 
    12  * @author Holly老师
    13  *
    14  */
    15 public class StudentDaoImpl extends BaseDao implements StudentDao {
    16     /**
    17      * 根据用户名和密码查询
    18      * @param sname
    19      * @param pwd
    20      * @return
    21      */
    22     public Student getByNameAndPwd(String sname,String pwd) {
    23         Student stu=null;
    24         String sql="select * from student where sname=? and pwd=?";
    25         
    26         Object[] param={sname,pwd};
    27         rs=this.executeQuery(sql, param);
    28         try {
    29             while(rs.next()){
    30                 stu=new Student(
    31                         rs.getInt("sid"),
    32                         rs.getString("sname"),
    33                         rs.getString("pwd"),
    34                         rs.getInt("age"));
    35             }
    36         } catch (SQLException e) {
    37             e.printStackTrace();
    38         }finally{
    39             this.closeAll(conn, pstm, rs);
    40         }
    41         return stu;
    42     }
    43 
    44     
    45 
    46 }
    StudentDaoImpl.java

    7.在com.service包下创建StudentService.java

    package com.service;
    
    import com.javabean.Student;
    /**
     * 服务器接口
     * @author Holly老师
     *
     */
    public interface StudentService {
        Student loginUser(String name,String pwd);
    
    }
    StudentService.java

    8.在com.service包下创建StudentServiceImp.java

    package com.service.impl;
    
    import com.dao.StudentDao;
    import com.dao.impl.StudentDaoImpl;
    import com.javabean.Student;
    import com.service.StudentService;
    /**
     * 
     * @author Holly老师
     *
     */
    public class StudentServiceImpl implements StudentService{
        StudentDao dao=new StudentDaoImpl();
        
        public Student loginUser(String name, String pwd) {
            return dao.getByNameAndPwd(name, pwd);
        } 
        
    
    }
    StudentServiceImp.java

    9.在src下创建mystruts.xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mystruts[
        <!ELEMENT mystruts (actions)>
        <!ELEMENT actions (action*)>
        <!ELEMENT action (result*)>
        <!ATTLIST action
          name CDATA #REQUIRED
          class CDATA #REQUIRED
        >
        <!ELEMENT result (#PCDATA)>
        <!ATTLIST result
          name CDATA #IMPLIED
          redirect (true|false) "false" 
        >
    ]>
    <mystruts>
      <actions>
        <!-- 登录 -->
        <action name="login" class="com.action.LoginAction">
          <result name="success">page/index.jsp</result>
          <result name="input">page/login.jsp</result>
        </action>
        
        <!-- 注册 -->
        <action name="register" class="com.action.RegisterAction">
          <result name="success">page/login.jsp</result>
          <result name="input">page/register.jsp</result>
        </action>
      </actions>
    </mystruts>
    
    
    <!-- 
      (1) 声明DTD:<!doctype 根元素 [定义内容]>
      (2)定义DTD元素标签节点 :<!ELEMENT 标签名称 元素类型>
      (3)定义DTD元素标签属性:<!ATTLIST 元素名称 属性名称 属性类型 属性默认值> 
      
      ELEMENT 定义标签节点
      ATTLIST 定义标签的属性
      CDATA 表示属性类型是字符数据
      #REQUIRED 属性值是必须的
      #IMPLIED 属性值不是必须的
      #FIXED 属性值是固定的
      ()给元素分组
      A|B 必须选择A或B
      A,B A和B按顺序出现 
      A* A出现0到n次
      A? A出现0到1次
      A+ A出现一次或n次
      
    
     -->
    mystruts.xml

    10.在com.action包下创建Action.java

     1 package com.action;
     2 
     3 import javax.servlet.http.HttpServletRequest;
     4 import javax.servlet.http.HttpServletResponse;
     5 /**
     6  * 
     7  * @author Holly老师
     8  *
     9  */
    10 public interface Action {
    11     /**
    12      * 返回处理结果
    13      * @param request 请求
    14      * @param response  响应
    15      * @return 失败或成功页面的字符串
    16      * @throws Exception
    17      */
    18     String execute(HttpServletRequest request,
    19             HttpServletResponse response) throws Exception;
    20 
    21 }
    Action.java

    11.在com.action包下创建LoginAction.java

    package com.action;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    import com.javabean.Student;
    import com.service.StudentService;
    import com.service.impl.StudentServiceImpl;
    /**
     * 
     * @author Holly老师
     *
     */
    public class LoginAction implements Action {
        /**
         * 处理请求返回处理结果
         */
        public String execute(HttpServletRequest request,
                HttpServletResponse response) throws Exception {
            //1.处理乱码
            request.setCharacterEncoding("UTF-8");  
            response.setCharacterEncoding("UTF-8");  
            response.setContentType("text/html;charset=UTF-8");
            
            //2.获取请求中的参数
            String name=request.getParameter("user");
            String pwd=request.getParameter("pwd");
            
            //3.业务处理
            StudentService service=new StudentServiceImpl();
            Student stu=service.loginUser(name, pwd);
            
            //4.业务判断
            if(stu!=null){
                HttpSession session=request.getSession();
                session.setAttribute("stu", stu);
                return "success";
            }else{
                return "input";
            }
        }
    
    }
    LoginAction.java

    12.在com.mapper包下创建ActionMapping.java

    package com.mapper;
    
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * Action节点的映射类
     * @author Holly老师
     *
     */
    public class ActionMapping {
        /**action节点的name属性*/
        private String name;
        
        /**action节点的class属性*/
        private String className;
        
        /**保存配置的result属性*/
        private Map<String,String> resultMap=new HashMap<String,String>();
    
        /**
         * 通过result-name属性,返回对应的某个result节点
         * @param name
         * @return
         */
        public String getResult(String name){
            return resultMap.get(name);
        }
        /**
         *在Map添加result节点=一个view*/
        public void addResult(String name,String result){
            this.resultMap.put(name, result);
        }
        
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getClassName() {
            return className;
        }
    
        public void setClassName(String className) {
            this.className = className;
        }
    
        public Map<String, String> getResultMap() {
            return resultMap;
        }
    
        public void setResultMap(Map<String, String> resultMap) {
            this.resultMap = resultMap;
        }
        
        
    
    }
    Mapping.java

    13.在com.mapper包下创建

    package com.mapper;
    
    import java.io.InputStream;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    
    import org.dom4j.Document;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    
    /**
     * Action的管理类
     * @author Holly老师
     *
     */
    public class ActionMappingManager {
        /**map里放入多个action节点,key是action的name属性值,
         * value是整个的action节点,也就是action映射类ActionMapping*/
        private static Map<String,ActionMapping> actionMappings
               =new HashMap<String,ActionMapping>();
        
        /**
         * init方法加载action的配置信息
         * @param configureFileName  配置文件的名字
         */
        public void init(String configureFileName){
           try {
              if(configureFileName==null ||configureFileName.isEmpty()){
                   throw new Exception("configureFileName为空");
               }
              
              //1.获取配置文件信息
              InputStream is=this.getClass().getResourceAsStream("/"+configureFileName);
              
              //2.读取xml文件内容
              Document doc=new SAXReader().read(is);
              
              //3.获取xml文件的根节点
              Element root=doc.getRootElement();
              
              //4.获取根节点mystrusts的下的所有actions节点
              Iterator<Element> actionsIt=root.elements("actions").iterator();
              
              //5.获取第一个actions节点
              Element actions=actionsIt.next();
              
              //6.获取actions下的所有action节点
              Iterator<Element> actionIt=actions.elementIterator("action");
              
              //7.循环取出action
              while(actionIt.hasNext()){
                  //取出下一个action
                  Element action=actionIt.next();
                  
                  //创建action对应映射类ActionMapping对象
                  ActionMapping mapping=new ActionMapping();
                  
                  //将action节点的name属性值赋值给ActionMapping映射类的name属性
                  mapping.setName(action.attributeValue("name"));
                  
                  //将action节点的class属性值赋值给ActionMapping映射类的className属性
                  mapping.setClassName(action.attributeValue("class"));
                  
                  //获取action节点下所有的result集合
                  Iterator<Element> resultIt=action.elementIterator("result");
                  
                  //循环取得result节点内容
                  while(resultIt.hasNext()){
                      //取得下一个result节点
                      Element resultElement=resultIt.next();
                      
                      //获取result节点上的name属性值
                      String name=resultElement.attributeValue("name");
                      
                      //获取result开始标签和结束标签之间的文本=跳转的页面地址
                      String result=resultElement.getText();
                      
                      if(name==null ||name.equals("")){
                          name="success";
                      }
                      //在我们映射类里添加result节点
                      mapping.addResult(name, result);
                  }
                  //把整个action节点添加到action管理类的集合中
                  actionMappings.put(mapping.getName(), mapping);
              }
          } catch (Exception e) {
                    e.printStackTrace();
          }        
        }
        /**
         * 通过构造方法来加载Action配置文件
         * @param 配置文件名数组
         */
        public ActionMappingManager(String[] configureFileNames){
            for (String configureFileName : configureFileNames) {
                init(configureFileName);
            }
        }
        
        /**
         * 根据actionName查询对应的ActionMapping实例
         * @param actionName
         * @return
         * @throws Exception 
         */
        public ActionMapping getActionMappingByName(String actionName) throws Exception{
            if(actionName==null || actionName.isEmpty()){
                return null;
            }
            ActionMapping mapping=this.actionMappings.get(actionName);
            if(mapping==null){
                throw new Exception("mapping为空:["+actionName+"]");
            }
            return mapping;
            
        }
        
        
        public static Map<String, ActionMapping> getActionMappings() {
            return actionMappings;
        }
    
        public static void setActionMappings(Map<String, ActionMapping> actionMappings) {
            ActionMappingManager.actionMappings = actionMappings;
        }
        
     
    }
    ActionMappingManager.java

    14.在com.action包下创建ActionManager.java

    package com.action;
    /**
     * 通过反射获取某个Action的实例/对象
     * @author Holly老师
     *
     */
    public class ActionManager {
        /**
         * 通过反射获取Class对象
         * @param className action的名字
         * @return Class对象
         * @throws ClassNotFoundException
         */
        public static Class loadClass(String className) throws ClassNotFoundException{
            Class clazz=null;
            //通过反射Class对象
            clazz=Class.forName(className);
            return clazz;
        }
        
        /**
         * 用来动态获取Action类对象
         * @param className  Action的名字
         * @return
         */
        public static Action createAction(String className){
            try {
                //通过class对象动态创建对象
                return (Action) loadClass(className).newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            return null;
        }
    
    }
    ActionManager.java

    15.在com.filter包下创建ActionFilter.java

    package com.filter;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.action.Action;
    import com.action.ActionManager;
    import com.action.LoginAction;
    import com.mapper.ActionMapping;
    import com.mapper.ActionMappingManager;
    /**
     * 
     * @author Holly老师
     *
     */
    public class ActionFilter implements Filter {
        //定义储存拦截器初始化参数的成员变量
        private FilterConfig config=null;
        
        //创建action映射文件管理类对象
        private ActionMappingManager mappingManager=null;
        
        /**资源回收*/
        public void destroy() {}
        
        /**初始化方法:获取拦截器的参数*/
        public void init(FilterConfig conf) throws ServletException {
            this.config=conf;
            //获取xml文件中的参数值,:mystruts.xml
            String conStr=config.getInitParameter("config");
            String[] configFiles=null;
            if(conStr==null || conStr.isEmpty()){
                configFiles=new String[]{"mystruts.xml"};
            }else{
                //拆分配置文件名称字符串
                configFiles=conStr.split(",");
            }
            //向多个action管理类的构造中传入xml文件的名
            mappingManager=new ActionMappingManager(configFiles);
            
                
        }
        
        /**过滤请求*/ 
        public void doFilter(ServletRequest sr, ServletResponse sp,
                FilterChain chain) throws IOException, ServletException {
            //1.获取request和response对象
            HttpServletRequest request=(HttpServletRequest) sr;
            HttpServletResponse response=(HttpServletResponse) sp;
            
            try {
                //获取整个action节点
                ActionMapping mapping=this.getActionMapping(request);
                
                //通过反射获取Action对象
                Action action=ActionManager.createAction(mapping.getClassName());
                
                //获取action类里处理请求返回的字符串,result的name属性,success或fail等
                String resultName=action.execute(request, response);
                
                //通过返回的reuslt的name属性值获取result开始标签和结束标签之间的文本,跳转的页面
                String result=mapping.getResult(resultName);
                if(result==null){
                    return;
                }
                
                //页面跳转(重定向)
                response.sendRedirect(result);
                
            } catch (Exception e) {
                e.printStackTrace();
            }
            
        }
        
        /**
         * 获取不同的Action
         * @return
         * @throws Exception 
         */
        public ActionMapping getActionMapping(HttpServletRequest request) throws Exception {
            //1.获取请求的uri地址:项目名/Xxx.action
            String uri=request.getRequestURI();
            
            //2.获取上下文路径:项目名
            String contextpath=request.getContextPath();
            
            //3.获取Xxx.action,从某个位置截取到最后
            String actionPath=uri.substring(contextpath.length());
            
            //4.获取Action的名字:Xxx
            String actionName=actionPath.substring(1,
                    actionPath.lastIndexOf('.')).trim();
            
            //5.获取某个Action的name属性值key获取整个acton类节点对象
            ActionMapping mapping=null;
            mapping=mappingManager.getActionMappingByName(actionName);
            
            return mapping;
        }
    
        
    
    }
    ActionFilter.java

    16.在WebRoot下WEB-INF下编辑web.xml文件

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <web-app version="2.5" 
     3     xmlns="http://java.sun.com/xml/ns/javaee" 
     4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
     6     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
     7   <welcome-file-list>
     8     <welcome-file>page/login.jsp</welcome-file>
     9   </welcome-file-list>
    10   <filter>
    11     <filter-name>requestFilter</filter-name>
    12     <!-- 拦截器的类路径 -->
    13     <filter-class>com.filter.ActionFilter</filter-class>
    14     <init-param>
    15        <param-name>config</param-name>
    16        <param-value>mystruts.xml</param-value>
    17     </init-param>
    18   </filter>
    19   
    20   <filter-mapping>
    21     <filter-name>requestFilter</filter-name>
    22     <!-- 拦截所有以.action结尾的请求 -->
    23     <url-pattern>*.action</url-pattern>
    24   </filter-mapping>
    25 </web-app>
    web.xml

    17.在WebRoot下创建page文件夹并编辑login.jsp

     1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
     2 <%
     3     String path = request.getContextPath();
     4     String basePath = request.getScheme() + "://"
     5             + request.getServerName() + ":" + request.getServerPort()
     6             + path + "/";
     7 %>
     8 
     9 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    10 <html>
    11     <head>
    12         <base href="<%=basePath%>">
    13 
    14         <title>My JSP 'index.jsp' starting page</title>
    15         <meta http-equiv="pragma" content="no-cache">
    16         <meta http-equiv="cache-control" content="no-cache">
    17         <meta http-equiv="expires" content="0">
    18         <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    19         <meta http-equiv="description" content="This is my page">
    20         <!--
    21     <link rel="stylesheet" type="text/css" href="styles.css">
    22     -->
    23     </head>
    24 
    25     <body>
    26         <fieldset style=" 400px">
    27             <legend>
    28                 登录
    29             </legend>
    30             <form action="login.action" method="post">
    31                 <table>
    32                     <tr>
    33                         <td>
    34                             用户名:
    35                         </td>
    36                         <td>
    37                             <input type="text" name="user" />
    38                         </td>
    39                     </tr>
    40                     <tr>
    41                         <td>
    42                             密码:
    43                         </td>
    44                         <td>
    45                             <input type="password" name="pwd" />
    46                         </td>
    47                     </tr>
    48                     <tr>
    49                         <td>
    50                             <input type="submit" value="登录" />
    51                         </td>
    52                         <td>
    53                             <input type="reset" value="重置" />
    54                         </td>
    55                     </tr>
    56 
    57                 </table>
    58             </form>
    59         </fieldset>
    60     </body>
    61 </html>
    login.jsp

    18.在WebRoot下创建page文件夹并编辑index.jsp

     1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
     2 <%
     3 String path = request.getContextPath();
     4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
     5 %>
     6 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
     7 <html>
     8   <head>
     9     <base href="<%=basePath%>">
    10     
    11     <title>My JSP 'index.jsp' starting page</title>
    12     <meta http-equiv="pragma" content="no-cache">
    13     <meta http-equiv="cache-control" content="no-cache">
    14     <meta http-equiv="expires" content="0">    
    15     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    16     <meta http-equiv="description" content="This is my page">
    17     <!--
    18     <link rel="stylesheet" type="text/css" href="styles.css">
    19     -->
    20   </head>
    21   
    22   <body>
    23      欢迎${stu.sname}登录首页!
    24   </body>
    25 </html>
    index.jsp


    19.写完了

    自己测试一下

  • 相关阅读:
    Python的优点和缺点
    如何在sed中使用变量方法及其简单
    shell脚本练习,创建数据文件注册用户并将用户信息存入文件内,用于模拟登录时使用
    shell脚本常用参数与格式
    运维方向和运维需要掌握的基本面
    linux系统awk命令精解
    数组去重方式
    原生js封装cookie获取、设置及删除
    sublime 浏览器快捷键设置
    background-image实现border效果及多图png如何实现background-size为原图一半
  • 原文地址:https://www.cnblogs.com/holly8/p/5497683.html
Copyright © 2020-2023  润新知