struts2从入门到精通

一、简单例子

说明:本例基于struts2 2.1.6。

1.引入jar包,struts2-core-2.1.6.jar、xwork-2.1.2.jar、ognl-2.6.11.jar、freemarker-2.3.13.jar、commons-logging-1.1.jar、commons-io-1.3.2.jar、commons-fileupload-1.2.1.jar。

2.在web.xml中添加:

   <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

3.在src下新建struts.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
 <package name="default" namespace="/" extends="struts-default">
        <action name="hello">
            <result>/hello.jsp</result>
        </action>
 </package>
</struts>

4.在地址栏中输入".../hello.action"就会进入hello.jsp页面。(".action"可省略)

二、进一步探索

1.新建com.hanjun.action.HelloAction类:

public class HelloAction {
 public String execute(){
  return "success";
 }
}

说明:可实现Action接口或继承已实现Action接口的类ActionSupport。

配置action时指定class属性:

    <action name="hello" class="com.hanjun.action.HelloAction">
        <result name="success">/hello.jsp</result>
    </action>

说明:进入hello.jsp前会执行HelloAction的execute方法,根据execute方法的返回值,在该action的配置中打到name为对应值的result,进入指定页面。如果返回值为success,result的name可不配置。

2.action不指定class属性时,默认执行ActionSupport类。action不指定执行方法时,默认为execute方法。action的method属性可指定进入什么方法。

3.可以通过url来指定进入什么方法:hello!addUser.action、hello!deleteUser.action:

public class HelloAction {
 public String addUser(){
  return "addUser";
 }
 public String deleteUser(){
  return "deleteUser";
 }
}

    <action name="hello" class="com.hanjun.action.HelloAction">
        <result name="addUser">/adduser_success.jsp</result>
        <result name="deleteUser">/deleteuser_success.jsp</result>
    </action>

4.通配符(精确配置优先于通配符配置):

        <action name="Student*" class="com.hanjun.action.StudentAction" method="{1}">
            <result>/Student{1}_success.jsp</result>
        </action>
        <action name="*_*" class="com.hanjun.action.{1}Action" method="{2}">
            <result>/{1}_{2}_success.jsp</result>
        </action>

说明:Studentadd.action(符合Student*)进入add方法返回Studentadd_success.jsp页面;

Student_delete.action(符合*_*)进入delete方法,返回Student_delete.jsp页面;(*_*中的_不能用!)

5.多个struts配置文件:在struts.xml中:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <constant name="struts.devMode" value="true" />
    <include file="login.xml" />
</struts>

login.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <package name="login" extends="struts-default" namespace="/login">
        <action name="login*" class="com.hanjun.action.LoginAction{1}">
            <result>/user_login_success.jsp</result>
        </action>
    </package>
</struts>

6.如果action不存在则进入默认action(不会拦截web.xml中配置的首页或jsp页面):

     <default-action-ref name="index"></default-action-ref>
     <action name="index">
      <result>/default.jsp</result>
     </action>

7.result的type属性:

dispatcher : forward到一个页面

redirect : sendRedirect到一个页面

chain : forward到另一个action(值为另一个aciton的name值)

redirectAction : sendRedirect到另一个actoion

说明:如果转到另一个包的action,则配置为:

      <result type="redirectAction">
       <param name="actionName">r2</param>
       <param name="namespace">/包名</param>
      </result>

8.共用的result,配置在package内:

<global-results>
   <result name="mainpage">/main.jsp</result>
</global-results>

说明:如果另一个包也想用:则把另一个package的extends设为本包的name值。(包继承)

9.可以在result中使用${变量名}获取action中的值。

10.配置异常映射,当所请求的antion方法出现异常时进入指定页面:

 <global-results>
   <result name="error">/error.jsp</result>
 </global-results>
 <global-exception-mappings>
   <exception-mapping result="error" exception="java.lang.Exception"></exception-mapping>
 </global-exception-mappings>

也可以单独使用:

 <action name="*_*" class="com.hanjun.action.{1}Action" method="{2}">
   <result>/{1}_{2}.jsp</result>
   <exception-mapping result="error" exception="java.sql.SQLException" />  
   <result name="error">/error.jsp</result>
 </action>

三、URL参数接收

1.在action中声明变量:

 private String name;
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }

说明:可接收url参数name的值:如url?name=zhangsan

2.在action中声明实体类:

 private User user;
 public User getUser() {
  return user;
 }
 public void setUser(User user) {
  this.user = user;
 }

说明:可接收url参数user.name、user.age ...的值(User类的属性也要有对应的get、set方法)。

3.action实现ModelDriven接口(不常用):

public class UserAction extends ActionSupport implements ModelDriven<User>{
 
 private User user = new User();
 
 public String add() {
  System.out.println("name=" + user.getName());
  System.out.println("age=" + user.getAge());
  return SUCCESS;
 }
 @Override
 public User getModel() {
  return user;
 }
}

说明:这样还可以直接接收name、age参数。注意:user属性必须手动初使化。

四、常用属性

struts2常量读取的先后顺序(后读取的覆盖先读取的):

struts-default.xml、struts-plugin.xml、struts.xml、struts.properties、web.xml

1.开发模式,设为true修改struts2配置后不用重启服务器:

<constant name="struts.devMode" value="true" />

2.设置接收参数时的编码:

<constant name="struts.i18n.encoding" value="GBK" />

说明:struts2.1.6在web.xml中配置的org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter 对此配置无效。配置为struts2.0的filter:org.apache.struts2.dispatcher.FilterDispatcher就可以。

3.设置后缀:

<constant name="struts.action.extension" value="action,," />

4.设置可以调用静态方法:

<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>

五、数据效验

1.进入方法后手动效验:

 public String add() {
  if(name == null || !name.equals("admin")) {
   this.addFieldError("name", "name is error");
   this.addFieldError("name", "name is too long");
   return ERROR;
  } 
  return SUCCESS;
 }

在错误页面引入struts2的标签:

<%@taglib uri="/struts-tags" prefix="s" %>

打印错误信息的两种方法:

<s:fielderror fieldName="name"/>  //以ul方法展示,两个错误信息各为一个li

<s:property value="fieldErrors.name[1]"/> //打印key为name的第一个错误信息"name is error"

六、获取JSP对象

1. 获取jsp对象有四种方法,第一种:

  Map request = (Map)ActionContext.getContext().get("request");
  Map session = ActionContext.getContext().getSession();
  Map application = ActionContext.getContext().getApplication();

2.第二种是第一种的注入形式,实现RequestAware,SessionAware, ApplicationAwar接口:

 private Map<String, Object> request;
 private Map<String, Object> session;
 private Map<String, Object> application;
 @Override
 public void setRequest(Map<String, Object> request) {
  this.request = request;
 }
 @Override
 public void setSession(Map<String, Object> session) {
  this.session = session;
 }
 @Override
 public void setApplication(Map<String, Object> application) {
  this.application = application;
 }

3.第三种:

  HttpServletRequest request = ServletActionContext.getRequest();
  HttpSession session = request.getSession();
  ServletContext application = session.getServletContext();

4.第四种是第三种的注入形式,实现ServletRequestAware接口:

 private HttpServletRequest request;
 private HttpSession session;
 private ServletContext application;
 @Override
 public void setServletRequest(HttpServletRequest request) {
  this.request = request;
  this.session = request.getSession();
  this.application = session.getServletContext();
 }

5.说明:

第1种和第2种获取的request不能获取从页面传过来的参数值。

七、OGNL

在jsp中引入<%@ taglib uri="/struts-tags" prefix="s" %>

1. 获取并打印username属性:

<s:property value="username"/>  //完整写法为:<s:property value="%{username}"/>

2.获取并打印user的age属性:

<s:property value="user.age"/> 

3.获取并打印cat的friend的name属性:

<s:property value="cat.friend.name"/>

4.直接使用java的方法:

<s:property value="password.length()"/>

5.防问静态方法:

<s:property value="@com.hanjun.struts2.ognl.S@s()"/>

说明:需要在struts.xml中配置:

<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>

6.防问静态变量:

<s:property value="@com.hanjun.struts2.ognl.S@STR"/>

7.访问Math类的静态方法:

<s:property value="@@max(2,3)" />

8.访问普通类的构造方法:

<s:property value="new com.hanjun.struts2.ognl.User(8)"/>

9.防问集合:

  <li>访问List:<s:property value="users"/></li>
  <li>访问List中某个元素:<s:property value="users[1]"/></li>
  <li>访问List中元素某个属性的集合:<s:property value="users.{age}"/></li>
  <li>访问List中元素某个属性的集合中的特定值:<s:property value="users.{age}[0]"/> | <s:property value="users[0].age"/></li>
  <li>访问Set:<s:property value="dogs"/></li>
  <li>访问Map:<s:property value="dogMap"/></li>
  <li>访问Map中某个元素:<s:property value="dogMap.dog101"/> | <s:property value="dogMap['dog101']"/> | <s:property value="dogMap[\"dog101\"]"/></li>
  <li>访问Map中所有的key:<s:property value="dogMap.keys"/></li>
  <li>访问Map中所有的value:<s:property value="dogMap.values"/></li>
  <li>访问容器的大小:<s:property value="dogMap.size()"/> | <s:property value="users.size"/> </li>

10.投影:

  <li>获取age=1的第一个user:<s:property value="users.{?#this.age==1}[0]"/></li>
  <li>获取age大于1的第一个user:<s:property value="users.{^#this.age>1}"/></li>
  <li>投影age大于1的最后一个user:<s:property value="users.{$#this.age>1}"/></li>

  获取当前堆栈中的第一个元素:<s:property value="[0]"/>  //[0]也可以用top

11.lambda表达式:

#fact=:[#this<=1?1:#this*fact(#this-1)],#fact(30H) //声明一个使用递归来计算阶乘的函数然后调用它

八、常用标签

在jsp中引入<%@ taglib uri="/struts-tags" prefix="s" %>

1.property:

<s:property value="username"/>  //获取属性username的值

<s:property value="admin" default="管理员"/> //default设置默认值

<s:property value="'<hr/>'" escape="false"/> //解析并输出html元素。

<s:property value="#request.adminName" /> //从request中取值

<s:property value="#adminName" /> //从ActionContext中取值

<s:property value="#parameters.age[0]" /> //获取url参数的值

2.set:

<s:set var="adminPassword" value="password" scope="session"/>

说明:scope的值有:page、request、session、action、application

3.bean:

   <s:bean name="com.hanjun.struts2.tags.Dog" var="myDog">
    <s:param name="name" value="'oudy'"></s:param>
   </s:bean>
   拿出值:
   <s:property value="#myDog.name"/>

4.if:

  <s:if test="#age < 0">wrong age!</s:if>
  <s:elseif test="#parameters.age[0] < 20">too young!</s:elseif>
  <s:else>yeah!</s:else>

5.iterator:

  <s:iterator value="{'aaa', 'bbb', 'ccc'}" var="x">
   <s:property value="#x.toUpperCase()"/> |
  </s:iterator>

  <s:iterator value="{'aaa', 'bbb', 'ccc'}" status="status">
   <s:property/> | 
   遍历过的元素总数:<s:property value="#status.count"/> |
   遍历过的元素索引:<s:property value="#status.index"/> |
   当前是偶数(从1开始)?:<s:property value="#status.even"/> |
   当前是奇数(从1开始)?:<s:property value="#status.odd"/> |
   是第一个元素吗?:<s:property value="#status.first"/> |
   是最后一个元素吗?:<s:property value="#status.last"/>
   <br />
  </s:iterator>

6.date:

<s:date name="date" format="yyyy-MM-dd HH:mm:ss"/>  //name指定ognl

九、转换器

1.例如在MyAction中有Point point类,Point类有int x,int y属性。页面表单有一文本框 name="point",用户输入"3,4"。那么就需要写一个转换器将3和4分别装入point的x和y。

2.新建PointConverter类,继承org.apache.struts2.util.StrutsTypeConverter类:

public class MyPointConverter extends StrutsTypeConverter {
 public Object convertFromString(Map context, String[] values, Class toClass) {
  Point p = new Point();
  String[] strs = (String[]) values;
  String[] xy = strs[0].split(",");
  p.x = Integer.parseInt(xy[0]);
  p.y = Integer.parseInt(xy[1]);
  return p;
 }
 public String convertToString(Map context, Object o) {
  Point p =(Point) o;
  return p.getX()+","+p.getY();
 }
}

3.在MyAction同包下新建文件MyAction-conversion.properties:

point=com.hanjun.converter.MyPointConverter

十、拦截器

1.新建类实现com.opensymphony.xwork2.interceptor.Interceptor:

public class MyInterceptor implements Interceptor {
 public void destroy() {
  // TODO Auto-generated method stub
 }
 public void init() {
  // TODO Auto-generated method stub
 }
 public String intercept(ActionInvocation invocation) throws Exception {
  long start = System.currentTimeMillis(); //action方法执行前
  String result = invocation.invoke();
  long end = System.currentTimeMillis(); //action方法执行后
  System.out.println("action time = " + (end - start));
  return result;
 }
}

2.struts.xml中:

  <interceptors>
   <interceptor name="myInterceptor" class="com.hanjun.interceptor.MyInterceptor"></interceptor>
  </interceptors>
  <action name="test" class="com.hanjun.action.TestAction">
   <result>/test.jsp</result>
   <interceptor-ref name="myInterceptor"></interceptor-ref>
   <interceptor-ref name="defaultStack"></interceptor-ref>
  </action>

或:

  <interceptors>
   <interceptor name="myInterceptor" class="com.hanjun.interceptor.MyInterceptor"></interceptor>
   <interceptor-stack name="myStack">
    <interceptor-ref name="myInterceptor"></interceptor-ref>
    <interceptor-ref name="defaultStack"></interceptor-ref>
   </interceptor-stack>
  </interceptors>
  <action name="test" class="com.hanjun.action.TestAction">
   <result>/test.jsp</result>
   <interceptor-ref name="myStack"></interceptor-ref>
  </action>

注:当package的extends="struts-default"时,action默认的拦截器为defaultStack。但在action内指定自定义拦截器或拦截器堆栈后,需手动添加defaultStack。

3.指定拦截的方法:

MyInterceptor继承MethodFilterInterceptor类,此类有两个set属性:excludeMethods(要排除的方法名集合);includeMethods(要拦截的方法集合);

   <interceptor name="myInterceptor" class="com.bjsxt.interceptor.MyInterceptor">
    <param name="includeMethods">doLogin,doRegister</param>
   </interceptor>

或在action设置拦截器时指定拦截方法:

  <action name="test" class="com.bjsxt.action.TestAction">
   <result>/test.jsp</result>
   <interceptor-ref name="myStack">
    <param name="myInterceptor.includeMethods">doLogin,doRegister</param>
   </interceptor-ref>
  </action>

十一、禁止重复提交

1.在页面的form中添加:

<s:token></s:token>

注:每次生成一个不同的标识存入session,提交后会校验。

2.struts.xml:

  <action name="user" class="com.hanjun.action.UserAction">
   <result>/addOK.jsp</result>
   <interceptor-ref name="defaultStack"></interceptor-ref>
   <interceptor-ref name="token"></interceptor-ref>
   <result name="invalid.token">/error.jsp</result>
  </action>

注:token为struts2定义好的拦截器,如果是重复提交则返回"invalid.token",所以定义一个result,重复提交时进入指定页面。

十二、国际化

1.在src下新建msg_en_US.properties和msg_zh_CN.properties。(msg自定义)

login.username=用户名://msg_en_US.properties中

login.username=username:  //msg_zh_CN.properties中

2.struts.xml中添加:

<constant name="struts.custom.i18n.resources" value="msg"></constant>

3.jsp页面(显示结果根据网页设置的语言而不同):

<s:text name="login.username"/> 或 <s:property value="getText('login.username')"/>

注:也可以使用url参数request_locale=en_US或request_locale=zh_CN手动指定,不过此url必须为struts的url。struts拦截到此参数后会存入session,session失效前不用重新设置。

4.使用占位符:

welcome.msg=欢迎你:{0}  //properties中

 <s:text name="welcome.msg">
  <s:param value="username"></s:param>  //value指定ognl表达式
 </s:text>  

十三、文件上传

1.页面:

 <form action="uploadAction.action" method="post" enctype="multipart/form-data">
  <input type="file" name="file" value="请选择"><br/>
  <input type="submit" value="提交">
 </form>

2.UploadAction:

 private File file;
 private String fileFileName;
 private String fileContentType;
 
 //上面三个属性get、set方法...
 public String execute() throws Exception {
  String path = ServletActionContext.getServletContext().getRealPath(
    "/upload");
  File dir = new File(path);
  if (!dir.exists()) {
   dir.mkdir();
  }
  FileInputStream fis = new FileInputStream(file);
  BufferedInputStream bis = new BufferedInputStream(fis);
  FileOutputStream fos = new FileOutputStream(new File(dir, fileFileName));
  BufferedOutputStream bos = new BufferedOutputStream(fos);
  byte[] buf = new byte[1024];
  for (int len = bis.read(buf); len != -1; len = bis.read(buf)) {
   bos.write(buf, 0, len);
  }
  bos.flush();
  bos.close();
  bis.close();
  return super.execute();
 }

3.struts2默认上传文件的最大限制为2M,可以修改全局的上传大小限制:

<constant name="struts.multipart.maxSize" value="999000000"></constant> //999M

注:当上传的文件超过限制大小时,后台报"the request was rejected because its size (文件大小) exceeds the configured maximum (2097152)"并返回input。

可以重写ActionSupport类的addActionError方法将错误信息存入ActionError:

 public void addActionError(String anErrorMessage) {
  // 这里要先判断一下,是我们要替换的错误,才处理
  if (anErrorMessage.startsWith("the request was rejected because its size")) {
   Matcher m = Pattern.compile("\\d+").matcher(anErrorMessage);
   String s1 = "";
   if (m.find()){
    s1 = m.group();
   }
   String s2 = "";
   if (m.find()){
    s2 = m.group();
   }
   // 偷梁换柱,将信息替换掉
   super.addActionError("你上传的文件大小(" + s1 + ")超过允许的大小(" + s2 + ")");
  } else {// 否则按原来的方法处理
   super.addActionError(anErrorMessage);
  }
 }

4.单独设置一个action的上传文件最大值:

  <action name="uploadAction" class="com.hanjun.action.UploadAction">
   <result>/upload_success.jsp</result>
   <result name="input">/test.jsp</result>
   <interceptor-ref name="defaultStack"> 
    <param name="fileUpload.maximumSize">5000000</param> 
   </interceptor-ref> 
  </action>

注:这里设置的大小应小于全局大小。如果文件大于这里设置的大小而小于全局设置的大小,直接返回input,没有错误信息(我的试验结果)。

十四、文件下载

1.jsp:

    <form action="download.action" method="post">
     <input name="filename" value="tisr.log">
     <input type="submit" value="下载">
    </form>

2.DownloadAction:

public class DownloadAction extends ActionSupport {
 private String filename;
 private String directory;
 public String execute() throws Exception {
  return SUCCESS;
 }
 public InputStream getInputStream() throws Exception {
  String dir = directory + filename;
  return new FileInputStream(dir); // 如果dir是绝对路径
  //如果dir是Resource下的相对路径
  //return ServletActionContext.getServletContext().getResourceAsStream(dir);
 }
 public String getFilename() {
  return filename;
 }
 public void setFilename(String filename) {
  this.filename = filename;
 }
 public void setDirectory(String directory) {
  this.directory = directory;
 }
}

3.struts.xml:

 <action name="download" class="com.bjsxt.action.DownloadAction" >
     <param name="directory">D:/</param>
     <result name="success" type="stream">
         <!--- 指定下载文件的内容类型,text/plain是默认类型 application/octet-stream为无限制-->
         <param name="contentType">application/octet-stream</param>
         <!--- inputName默认值是inputStream,代表从getInputStream方法获取流 -->
         <param name="inputName">inputStream</param>
         <!---动态获取文件名,从Action中的取得filename-->
         <param name="contentDisposition">
             attachment;filename="${filename}"
         </param>
         <param name="bufferSize">2048</param>
     </result>
     <result name="input">/downloadError.jsp</result>
 </action>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、准备工作及实例 3 1.解压struts-2.1.6-all.zip 3 2.六个基本包 3 3.初识struts2配置文件 4 (1).web.xml文件 4 (2).struts.xml文件 4 (3).struts.properties(参default.properties) 4 (4)struts-default.xml 4 (5)其它配置文件 4 4.让MyEclipse提示xml信息 4 5.如何使用alt+/提示 4 6.实例 4 7.开启struts2自带的开发模式常量 6 8.vo传参模式 7 9.ModerDriven传参模式(不建议采用) 7 10.为什么要使用struts2代替struts1.x 7 二、struts.xml配置及例程 7 1.配置文件的优先级 7 2.配置形式 8 3.package配置相关 8 4.分工合作include:指定多个配置文件 10 5.tomcat认证访问 10 6.初识拦截器 11 7.Action中的method属性 12 8.使用ForwardAction实现页面屏蔽。 13 8.使用default-Action配置统一访问 14 小结Action 14 9.使用通配符 14 10.使用0配置:ZERO Annotation 15 11.Result配置详解 15 探讨type类型: 16 Type类型值 16 作用说明 16 对应类 16 chain 16 用来处理Action链 16 com.opensymphony.xwork2.ActionChainResult 16 dispatcher 16 用来转向页面,通常处理JSP 16 org.apache.struts2.dispatcher.ServletDispatcherResult 16 redirect 16 重定向到一个URL 16 org.apache.struts2.dispatcher.ServletRedirectResult 16 redirectAction 16 重定向到一个Action 16 org.apache.struts2.dispatcher.ServletActionRedirectResult 16 plainText 16 显示源文件内容,如文件源码 16 org.apache.struts2.dispatcher.PlainTextResult 16 freemarker 16 处理FreeMarker模板 16 org.apache.struts2.views.freemarker.FreemarkerResult 16 httpheader 16 控制特殊http行为的结果类型 16 org.apache.struts2.dispatcher.HttpHeaderResult 16 stream 16 向浏览器发送InputSream对象,通常用来处理文件下载,还可用于返回AJAX数据。 16 org.apache.struts2.dispatcher.StreamResult 16 velocity 16 处理Velocity模板 16 org.apache.struts2.dispatcher.VelocityResult 16 xslt 16 处理XML/XLST模板 16 org.apache.struts2.views.xslt.XSLTResult 16 全局result: 17 动态Result:了解 18 12.异常处理 18 三、在Action获取Scope对象 19 方式一、与Servlet解耦合的非IOC方式 20 方式二、与Servlet解耦合的IOC方式 21 方式三、与Servlet耦合的非IOC方式 21 方式四、与Servlet耦合的IOC方式 22 四、OGNL与ValueStack(VS) 22 1.值栈入门 22 2.OGNL入门 24 3.普通方法访问 24 4.静态方法访问 24 5.默认类Math的访问 24 6.调用普通类的构造方法 25 7.集合对象初步 25 8.集合对象进阶 25 9.N语法top语法 26 10.获取Stack Context中的信息 26 11.总结$ # %的区别 27 12.总结OGNL[重点] 27 五、拦截器 28 1.概述strust2中的拦截器 28 2.自定义拦截器 28 方式一,实现Interceptor接口。 28 方式二、继承AbstractInterceptor抽象类 29 方式三、继承MethodFilterInteceptor类 30 3.使用来MethodFilterInterceptor灵活拦截 32 4.使用默认的execAndWait拦截器 33 5.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值