Struts2学习总结(1)--基本原理,开发步骤,配置详解

本文包括以下三个部分:

  1. 模拟Struts2框架,了解基本原理。
  2. Struts2的开发步骤。
  3. Struts2的配置详解

一、模拟Struts2框架,了解基本原理

        在学习Struts2框架以前,我们一直采用servlet进行网站的开发。最开始是一个功能使用一个servlet程序;后来创建BaseServlet进行简化,可以实现一个模块使用一个servlet程序;为了开发更加快捷,代码更加简洁,达到一个项目只使用一个servlet程序的目的,我们可以模拟一个简易的Struts2框架,并在此基础上了解Struts2的基本原理。

        具体步骤如下:

        1、创建一个模拟用户等录和注册的项目。

             

        2、编写entity包代码。

              User.Java

[html]  view plain  copy
 print ?
  1. package edu.scut.entity;  
  2. //用户  
  3. public class Users {  
  4.     private int id;  
  5.     private String name;  
  6.     private String password;  
  7.     public int getId() {  
  8.         return id;  
  9.     }  
  10.     public void setId(int id) {  
  11.         this.id = id;  
  12.     }  
  13.     public String getName() {  
  14.         return name;  
  15.     }  
  16.     public void setName(String name) {  
  17.         this.name = name;  
  18.     }  
  19.     public String getPassword() {  
  20.         return password;  
  21.     }  
  22.     public void setPassword(String password) {  
  23.         this.password = password;  
  24.     }  
  25.     public Users() {  
  26.         super();  
  27.         // TODO Auto-generated constructor stub  
  28.     }  
  29.     public Users(int id, String name, String password) {  
  30.         super();  
  31.         this.id = id;  
  32.         this.name = name;  
  33.         this.password = password;  
  34.     }  
  35.     @Override  
  36.     public String toString() {  
  37.         return "Users [id=" + id + "name=" + name + "password=" + password  
  38.                 + "]";  
  39.     }  
  40.       
  41. }  

           3、编写dao层代码。

              UserDao.java

[java]  view plain  copy
 print ?
  1. package edu.scut.dao;  
  2. import edu.scut.entity.Users;  
  3. public class UserDao {  
  4.     //查询用户  
  5.     public Users findByName(String name){  
  6.         Users users = null;  
  7.   
  8.         if("jack".equals(name)){  
  9.             users = new Users(1,"jack","666666");  
  10.         }  
  11.         return users;  
  12.     }  
  13.       
  14.     //添加用户  
  15.     public void addUser(Users users){  
  16.         System.out.println("注册成功! "+users);  
  17.     }  
  18. }  
         4、编写service层代码。

              UserService.java

[html]  view plain  copy
 print ?
  1. package edu.scut.service;  
  2.   
  3. import edu.scut.dao.UserDao;  
  4. import edu.scut.entity.Users;  
  5. import edu.scut.exception.LoginFailureException;  
  6.   
  7. public class UserService {  
  8.     UserDao userDao = new UserDao();  
  9.     //登录  
  10.     public Users Login(Users users) throws LoginFailureException{  
  11.         Users loginUsers = userDao.findByName(users.getName());  
  12.           
  13.         //判断name   
  14.         if(loginUsers == null){  
  15.             throw new LoginFailureException("用户不存在!");  
  16.         }  
  17.           
  18.         //判断密码  
  19.         if(!loginUsers.getPassword().equals(users.getPassword())){  
  20.             throw new LoginFailureException("密码错误!");  
  21.         }  
  22.           
  23.         return loginUsers;  
  24.     }  
  25.       
  26.     //注册  
  27.     public void Reg(Users users){  
  28.         userDao.addUser(users);  
  29.     }  
  30. }  

          5、编写exception包代码。

               LoginFailureException.java

[html]  view plain  copy
 print ?
  1. package edu.scut.exception;  
  2.   
  3. public class LoginFailureException extends Exception {  
  4.   
  5.     public LoginFailureException() {  
  6.         super();  
  7.         // TODO Auto-generated constructor stub  
  8.     }  
  9.   
  10.     public LoginFailureException(String message, Throwable cause) {  
  11.         super(message, cause);  
  12.         // TODO Auto-generated constructor stub  
  13.     }  
  14.   
  15.     public LoginFailureException(String message) {  
  16.         super(message);  
  17.         // TODO Auto-generated constructor stub  
  18.     }  
  19.   
  20.     public LoginFailureException(Throwable cause) {  
  21.         super(cause);  
  22.         // TODO Auto-generated constructor stub  
  23.     }  
  24.       
  25. }  

          6、编写web层代码。

              UserAction.java

[java]  view plain  copy
 print ?
  1. package edu.scut.web;  
  2.   
  3. import java.io.IOException;  
  4.   
  5. import javax.servlet.ServletException;  
  6. import javax.servlet.http.HttpServletRequest;  
  7. import javax.servlet.http.HttpServletResponse;  
  8.   
  9. import edu.scut.entity.Users;  
  10. import edu.scut.exception.LoginFailureException;  
  11. import edu.scut.service.UserService;  
  12.   
  13. //用户模块的操作类  
  14. public class UserAction {  
  15.     UserService userService = new UserService();  
  16.     //URL:userLogin.action  
  17.     public String login(HttpServletRequest request, HttpServletResponse response)  
  18.             throws ServletException, IOException {  
  19.         String name = request.getParameter("name");  
  20.         String password = request.getParameter("password");  
  21.           
  22.         //封装成对象  
  23.         Users users = new Users();  
  24.         users.setName(name);  
  25.         users.setPassword(password);  
  26.           
  27.         try {  
  28.             //调用登录方法  
  29.             Users loginUsers = userService.Login(users);  
  30.               
  31.             //如果登录成功,将数据存储在域对象  
  32.             request.getSession().setAttribute("loginInfo", loginUsers);  
  33.               
  34.             //主页  
  35.             return "success";  
  36.               
  37.         } catch (LoginFailureException e) {  
  38.             //如果登录失败,将信息存储在域对象  
  39.             request.setAttribute("msg", e.getMessage());  
  40.             return "fail";  
  41.         }  
  42.           
  43.     }  
  44.       
  45.     //URL:userReg.action  
  46.     public String reg(HttpServletRequest request, HttpServletResponse response)  
  47.             throws ServletException, IOException {  
  48.         //获取表单数据  
  49.         String name = request.getParameter("name");  
  50.         String password = request.getParameter("password");  
  51.           
  52.         //封装成对象  
  53.         Users users = new Users();  
  54.         users.setName(name);  
  55.         users.setPassword(password);  
  56.           
  57.         //执行方法  
  58.         userService.Reg(users);  
  59.           
  60.         //保存数据  
  61.         request.setAttribute("regSuc""注册成功,请登录!");  
  62.           
  63.         //跳转到登录页面  
  64.         return "success";  
  65.       
  66.     }  
  67. }  


 
           7、编写配置文件mystruts.xml。 

               mystruts.xml

[html]  view plain  copy
 print ?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <struts>  
  3.     <!-- 登录请求 -->  
  4.     <!-- name:请求名称  
  5.          class:执行的操作类类名  
  6.          method:执行操作类的方法      
  7.      -->  
  8.     <action name="userLogin" className="edu.scut.web.UserAction" method="login">  
  9.         <result name="fail" type="dispatcher">/login.jsp</result>  
  10.         <result name="success" type="redirect">/index.jsp</result>  
  11.     </action>  
  12.       
  13.     <!-- 注册请求 -->  
  14.     <action name="userReg" className="edu.scut.web.UserAction" method="reg" >  
  15.         <result name="success" type="dispatcher">/login.jsp</result>  
  16.     </action>  
  17. </struts>  

          8、编写framework包代码。

              8.1、编写Action的映射类即,ActionMapping.java

[java]  view plain  copy
 print ?
  1. package edu.scut.framework;  
  2.   
  3. import java.util.List;  
  4.   
  5. //action类  
  6. public class ActionMapping {  
  7.     private String name;  
  8.     private String className;  
  9.     private String method;  
  10.     private List<Result> results;  
  11.       
  12.     public List<Result> getResults() {  
  13.         return results;  
  14.     }  
  15.     public void setResults(List<Result> results) {  
  16.         this.results = results;  
  17.     }  
  18.     public String getName() {  
  19.         return name;  
  20.     }  
  21.     public void setName(String name) {  
  22.         this.name = name;  
  23.     }  
  24.     public String getClassName() {  
  25.         return className;  
  26.     }  
  27.     public void setClassName(String className) {  
  28.         this.className = className;  
  29.     }  
  30.     public String getMethod() {  
  31.         return method;  
  32.     }  
  33.     public void setMethod(String method) {  
  34.         this.method = method;  
  35.     }  
  36.       
  37.       
  38. }  

            8.2、创建结果视图的类,即Result.java

[java]  view plain  copy
 print ?
  1. package edu.scut.framework;  
  2. //视图类型  
  3. public class Result {  
  4.     private String name;  
  5.     private String type;  
  6.     private String path;  
  7.     public String getName() {  
  8.         return name;  
  9.     }  
  10.     public void setName(String name) {  
  11.         this.name = name;  
  12.     }  
  13.     public String getType() {  
  14.         return type;  
  15.     }  
  16.     public void setType(String type) {  
  17.         this.type = type;  
  18.     }  
  19.     public String getPath() {  
  20.         return path;  
  21.     }  
  22.     public void setPath(String path) {  
  23.         this.path = path;  
  24.     }  
  25. }  

            8.3、编写ActionServlet.java,读取配置文件:mystruts.xml,UserAction的访问,以及结果视图的跳转。

[java]  view plain  copy
 print ?
  1. package edu.scut.framework;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5. import java.lang.reflect.Method;  
  6. import java.util.ArrayList;  
  7. import java.util.HashMap;  
  8. import java.util.List;  
  9. import java.util.Map;  
  10.   
  11. import javax.management.RuntimeErrorException;  
  12. import javax.servlet.ServletException;  
  13. import javax.servlet.http.HttpServlet;  
  14. import javax.servlet.http.HttpServletRequest;  
  15. import javax.servlet.http.HttpServletResponse;  
  16.   
  17. import org.dom4j.Document;  
  18. import org.dom4j.DocumentException;  
  19. import org.dom4j.Element;  
  20. import org.dom4j.io.SAXReader;  
  21.   
  22. import com.sun.org.apache.xml.internal.dtm.ref.sax2dtm.SAX2RTFDTM;  
  23. import com.sun.org.apache.xml.internal.resolver.helpers.FileURL;  
  24.   
  25. import edu.scut.web.UserAction;  
  26.   
  27. public class ActionServlet extends HttpServlet {  
  28.     //在Action初始化时就加载配置文件并且将其封装成对象  
  29.     //创建Map集合封装actionMapping  
  30.     Map<String, ActionMapping> actionMappings = null;  
  31.     @Override  
  32.     public void init() throws ServletException {  
  33.         //创建actionMappings的实例  
  34.         actionMappings = new HashMap<String, ActionMapping>();  
  35.           
  36.         try {  
  37.             //读取mystruts.xml文件  
  38.             SAXReader reader = new SAXReader();  
  39.             //获取文件   
  40.             Document doc = reader.read(ActionServlet.class.getResourceAsStream("/mystruts.xml"));  
  41.             //获取根元素  
  42.             Element root = doc.getRootElement();  
  43.             //获取所有的action标签  
  44.             List<Element> actionElements = (List<Element>)root.selectNodes("//action");  
  45.               
  46.             //遍历action集合  
  47.             for (Element actionElement : actionElements) {  
  48.                 //获取属性值  
  49.                 String name = actionElement.attributeValue("name");  
  50.                 String className = actionElement.attributeValue("className");  
  51.                 String method = actionElement.attributeValue("method");  
  52.                   
  53.                 //创建actionMapping的对象  
  54.                 ActionMapping actionMapping = new ActionMapping();  
  55.                 actionMapping.setName(name);  
  56.                 actionMapping.setClassName(className);  
  57.                 actionMapping.setMethod(method);  
  58.                   
  59.                 //获取action当中的result对象  
  60.                 List<Element> resultElements = actionElement.elements("result");  
  61.                   
  62.                 //创建resultElements集合  
  63.                 List<Result> resultList = new ArrayList<Result>();  
  64.                   
  65.                 //遍历集合  
  66.                 for (Element resultElement : resultElements) {  
  67.                     //获取属性值  
  68.                     String resName = resultElement.attributeValue("name");  
  69.                     String resType = resultElement.attributeValue("type");  
  70.                     String resPath = resultElement.getText();  
  71.                       
  72.                     //创建Result对象  
  73.                     Result result = new Result();  
  74.                     result.setName(resName);  
  75.                     result.setType(resType);  
  76.                     result.setPath(resPath);  
  77.                       
  78.                     //封装进集合  
  79.                     resultList.add(result);  
  80.                 }  
  81.                   
  82.                 //将结果集封装进对象  
  83.                 actionMapping.setResults(resultList);  
  84.                   
  85.                 //将actionMapping封装进actionMappings集合  
  86.                 actionMappings.put(name, actionMapping);  
  87.                   
  88.                 System.out.println("mystruts.xml文件加载完毕!");  
  89.             }  
  90.               
  91.         } catch (DocumentException e) {  
  92.             //e.printStackTrace();  
  93.             System.out.println("配置文件加载失败!");  
  94.             throw new RuntimeException("配置文件读取失败!");  
  95.         }  
  96.     }  
  97.   
  98.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  99.             throws ServletException, IOException {  
  100.         //url  /userLogin.action  
  101.         //1 得到路径 /day27_01_mystruts2_test/userLogin.action  
  102.         String uri = request.getRequestURI();  
  103.           
  104.         //2 截取action的名字  
  105.         String pathName = uri.substring(uri.lastIndexOf("/")+1, uri.lastIndexOf(".action"));  
  106.           
  107.         //3 根据action的名字获取className  
  108.         ActionMapping actionMapping = actionMappings.get(pathName);  
  109.           
  110.         //创建一个变量接受返回值  
  111.         String FURL = null;  
  112.         try {  
  113.             //4 根据action获取类名称  
  114.             String className = actionMapping.getClassName();  
  115.               
  116.             //5 根据className创建实例  
  117.             //获取字节码文件  
  118.             Class clazz = Class.forName(className);  
  119.             //创建对象  
  120.             Object actionClass = clazz.newInstance();  
  121.               
  122.             //6 获取方法名称,调用响应的方法  
  123.             String method = actionMapping.getMethod();  
  124.             Method m = clazz.getDeclaredMethod(method, HttpServletRequest.class,HttpServletResponse.class);  
  125.               
  126.             //7 调用方法  
  127.             FURL = (String) m.invoke(actionClass, request,response);  
  128.               
  129.         } catch (Exception e) {  
  130.             // TODO Auto-generated catch block  
  131.             e.printStackTrace();  
  132.         }  
  133.           
  134.         //8 根据返回值字符串返回响应的视图  
  135.         List<Result> results = actionMapping.getResults();  
  136.         //遍历集合  
  137.         for (Result result : results) {  
  138.             if(FURL.equals(result.getName())){  
  139.                 //获取返回视图的类型  
  140.                 String type = result.getType();  
  141.                 //获取返回视图的路径  
  142.                 String path = result.getPath();  
  143.                   
  144.                 //9 判断视图的类型执行响应的结果  
  145.                 if(type.equals("dispatcher")){  
  146.                     //转发  
  147.                     request.getRequestDispatcher(path).forward(request, response);  
  148.                 }else if(type.equals("redirect")){  
  149.                     //重定向  
  150.                     response.sendRedirect(request.getContextPath()+path);  
  151.                 }  
  152.                   
  153.             }  
  154.         }  
  155.           
  156.         //3 判断执行响应的方法  
  157.         /*if("userLogin".equals(pathName)){ 
  158.             UserAction userAction = new UserAction(); 
  159.             userAction.login(request, response); 
  160.         }else if("userReg".equals(pathName)){ 
  161.             UserAction userAction = new UserAction(); 
  162.             userAction.reg(request, response); 
  163.         }*/  
  164.           
  165.           
  166.     }  
  167.   
  168.   
  169.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  170.             throws ServletException, IOException {  
  171.   
  172.         doGet(request, response);  
  173.     }  
  174.   
  175. }  

              9、配置ActionServlet.java的访问路径。

                    web.xml

[html]  view plain  copy
 print ?
  1. <servlet>  
  2.   <servlet-name>ActionServlet</servlet-name>  
  3.   <servlet-class>edu.scut.framework.ActionServlet</servlet-class>  
  4. </servlet>  
  5. <servlet-mapping>  
  6.   <servlet-name>ActionServlet</servlet-name>  
  7.   <url-pattern>*.action</url-pattern>  
  8. </servlet-mapping>    

             10、登录、注册和主页的jsp。

                   login.jsp:

[html]  view plain  copy
 print ?
  1. <body>  
  2.     <font color="red">${msg}</font>  
  3.     <form action="${pageContext.request.contextPath }/userLogin.action" method="post">  
  4.     <%--<form action="${pageContext.request.contextPath }/users?action=login" method="post">--%>  
  5.         用户名:<input type="text" name="name"><br>  
  6.         密码:<input type="password" name="password"><br>  
  7.         <input type="submit" value="登录"/>  
  8.     </form>  
  9. </body>  
                 reg.jsp:

[html]  view plain  copy
 print ?
  1. <body>  
  2.     <form action="${pageContext.request.contextPath }/userReg.action" method="post">  
  3.     <%-- <form action="${pageContext.request.contextPath }/users?action=reg" method="post">--%>  
  4.         用户名:<input type="text" name="name"><br>  
  5.         密码:<input type="password" name="password"><br>  
  6.         <input type="submit" value="注册"/>  
  7.     </form>  
  8. </body>  
                index.jsp:

[html]  view plain  copy
 print ?
  1. <body>  
  2.       欢迎您,用户名:${sessionScope.loginInfo.name }  
  3. </body>  
             11、访问。

                      注册:http://localhost:8080/day27_01_mystruts2_test/reg.jsp

                      登录:http://localhost:8080/day27_01_mystruts2_test/login.jsp


             访问之后的执行过程:

             a. 创建ActionServlet实例;

             b. 调用ActionServlet的init()方法;

             c. 加载mystruts.xml配置文件,根据action的name找到对应的action,用反射的方式,创建UserAction的实例,再根据method的名称调用UserAction的同名方法;

             d. 根据方法的返回值和result标签的name属性,找到result,实现页面跳转。

二、Struts2的开发步骤

             1、导jar包。8个jar包。

              2、配置struts2的核心过滤器。注意:在web.xml文件中配置,该核心过滤器用于处理项目的所有请求。

[html]  view plain  copy
 print ?
  1. <filter>  
  2.     <filter-name>struts2</filter-name>  
  3.     <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>  
  4. </filter>  
  5. <filter-mapping>  
  6.     <filter-name>struts2</filter-name>  
  7.     <url-pattern>/*</url-pattern>  
  8. </filter-mapping>  

              3、编写操作类。

[html]  view plain  copy
 print ?
  1. package edu.scut.web;  
  2. //用户操作类,表现层  
  3. public class UserAction {  
  4.     //构造方法  
  5.     public UserAction(){  
  6.         System.out.println("useraction对象创建了!");  
  7.     }  
  8.       
  9.     //userLogin.action  
  10.     //登录方法  
  11.     public String login(){  
  12.         System.out.println("登录成功!");  
  13.         return "success";  
  14.     }  
  15.       
  16.     //userReg.action  
  17.     public String reg(){  
  18.         System.out.println("注册成功!");  
  19.         return "success";  
  20.     }  
  21.       
  22. }  

                4、编写struts2的业务配置文件。 注意:名称一定为struts.xml,位置一定放在src目录下。

[html]  view plain  copy
 print ?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.  <!DOCTYPE struts PUBLIC  
  3.     "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"  
  4.     "http://struts.apache.org/dtds/struts-2.3.dtd">  
  5. <struts>  
  6.     <package name="user" extends="struts-default" namespace="/user">  
  7.         <!-- 登陆的action -->  
  8.         <action name="userLogin" class="edu.scut.web.UserAction" method="login">  
  9.             <result name="success" type="redirect">/index.jsp</result>  
  10.         </action>  
  11.         <!-- 注册的action -->  
  12.         <action name="userReg" class="edu.scut.web.UserAction" method="reg">  
  13.             <result name="success">/index.jsp</result>  
  14.         </action>  
  15.     </package>  
  16. </struts>  

                 Struts2的执行过程:

                  a. 项目启动时:
                         1)加载web.xml文件,创建org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter核心过滤器对象
                         2)调用核心过滤器中的init方法
                              2.1 读取default.properties     【struts2的默认常量文件】
                                   (struts2-core.jar: /org/apache/struts2/default.properties)
                             2.2 读取struts-default.xml    【struts2的默认核心配置文件】
                                  (struts2-core.jar:/struts-default.xml)
                             2.3 读取struts-plugin.xml    【struts2的插入配置文件】
                                  (一般不会用到)
                             2.4 读取struts.xml            【struts2的业务配置文件,开发时经常修改】
                                    (项目的src:struts.xml)
            
                  b. 发出请求:
                         1)根据请求名称,在struts.xml文件中对应的action标签(根据action的name属性值)
                         2)查找结果
                               失败:
                                      如果没有匹配成功,则页面抛出There is no Action mapped 异常    
                               成功:
                                     2.1 根据action标签的class的字符串去创建一个Action(操作)类实例
                                     2.2 根据action标签的method去调用Action类里面对应的方法
                                     2.3 执行完操作方法后,返回一个视图标记的字符串
                        3)根据视图标记字符串在当前action标签中查找对应的result标签(根据result的name属性值)
                        4)找到对应的result,则跳转到对应的页面    

三、Struts2的配置详解

         1、struts-default.xml : struts2的核心默认配置文件

           第一部分:创建struts2框架自身需要的对象
             <bean class="com.opensymphony.xwork2.ObjectFactory" name="xwork" />
             。。。。。。
           第二部分:一个默认包
            <package name="struts-default" abstract="true">
                name: 包名称
                abstract: 抽象包
                
                1) 定义struts2支持的视图类型
              <result-types>
                    <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
              。。。。。

                常用的视图类型:
                dispatcher: 转发到页面  (默认类型) (可以通过request带数据)
                redirect:重定向到页面  
                chain:转发到其他Action   (可以通过request带数据)
                redirectAction:重定向到其他Action
                stream: 以流的形式进行输出  (用于文件下载)
                plainText:以纯文本方法进行输出  (ajax技术)

                2) 定义了struts2的支持的拦截器

                    <interceptors>
                        <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>        
                    。。。。。。

                        struts2除了基本功能以外,还提供了如下实用功能:
                        传递页面参数数据
                        文件上传
                        国际化
                        数据共享
                        类型转换
                        表单数据校验
                        ....
                        拦截器只能拦截action
                        过滤器可以拦截任何请求
               3)定义了默认的拦截器栈
                        <interceptor-stack name="basicStack">        
                            拦截栈中包含多个拦截器

               4)定义当前包使用的默认拦截器
                         <default-interceptor-ref name="defaultStack"/>
                            当前包下的所有action都可以使用该拦截器栈下的所有拦截器

               5)定义当前包的默认操作类
                            <default-class-ref class="com.opensymphony.xwork2.ActionSupport" />
                            当前包下的action如果不写class就使用默认类

        2、  struts.xml:  业务配置文件
                     
           <package>:区分不用的action
                name:包名。通常不同的包使用不同的名称(如果同名则报错)
                extends:当前包的父包的包名。通常为struts-default默认包,继承了struts-default默认包就可以使用该包下定义的元素。
                namespace: 名称空间(命名空间),为了区分不同包的访问路径。
                    
                注意:
                有了namespace后,action的访问路径必须带上namespace。

                   <action> : 操作配置
                        name(必须): 请求名称,通常同一个包下不要出现同名的action。
                        class(可选): 操作类的全名(包+类名),默认类:com.opensymphony.xwork2.ActionSupport。
                        method(可选): 执行的操作方法,默认方法:execute。

                        <result> : 视图
                             name: 视图名称。跟操作方法返回的字符串匹配, 默认值:success。(其他名称都需要写)
                             type:视图类型, 默认值:dispatcher。
                             内容:跳转路径,如果是页面必须带斜杠,如果是action不需要。(没有默认值)
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值