09 拦截器的使用

1.   什么是拦截器

拦截器用于访问某个方法前、后加入开发者想实现的某些操作,拦截器是aop思想的一种具体实现方式。

 

2.   新增java

       package interceptor;

 

import    com.opensymphony.xwork2.ActionInvocation;

import    com.opensymphony.xwork2.interceptor.Interceptor;

 

public class LogInterceptor implements Interceptor

{

    public String intercept(ActionInvocation invocation)

            throws Exception

        {

            System.out.println("enteraction [" +invocation.getAction().getClass() + "],method["

            + invocation.getProxy().getMethod()+"]");

       

            long beginTime = System.currentTimeMillis();

            String result = invocation.invoke();

            long endTime = System.currentTimeMillis();

      

System.out.println("exit action [" + invocation.getAction().getClass() + "], method["

            + invocation.getProxy().getMethod()+ "], costTime[" + (endTime - beginTime) + ']');

        return result;

    }

 

    public void destroy()

    {

    }

 

    public void init()

    {

    }

}

 

3.   修改struts.xml

<package name="struts"namespace="/struts"extends="struts-default">

        <interceptors>

            <interceptorname="log" class="interceptor.LogInterceptor"></interceptor>

         </interceptors>

        …

         <action name="user*"class="action.UserAction"method="{1}">

            <result>/user{1}_success.jsp</result>

             <result name="error">/error.jsp</result>

             <interceptor-ref name="log"></interceptor-ref>

             <interceptor-ref name="defaultStack"></interceptor-ref>

        </action>

</package>

4.   运行

启动tomcat

访问http://localhost:2000/Gao_struts2/struts/useradd.action?user.userName=gaoxiang&user.age=26&userName=aaaa

页面显示:

user addsuccess! 
aaaa
gaoxiang
a
userDao
addUser
8

 

控制台打印:

enter action [class action.UserAction],method[add]

exit action [class action.UserAction],method[add], costTime[2]

 

 

5.   总结

1)        实现struts2的拦截器,需要继承Interceptor接口,实现intercept(ActionInvocation invocation)方法

2)        intercept方法中需要添加invocation.invoke(),这样客户端的action请求才能继续执行struts默认的拦截器,最终访问对应服务器端的action

3)        intercept方法中invocation.invoke()的前后,我们可以添加我们需要实现的切面方法,如打印开始和结束访问对应action的对应的方法和action执行的耗时、记录访问action请求的流量等。

4)        实现的拦截器的java类后,需要在struts.xml配置拦截器,这样struts才能识别需要拦截请求,struts.xml中的拦截器关键字:interceptor

5)        配置的interceptors需要放在action上面,否则应用启动会识别。

6)        Struts2默认拦截器中实现了对执行action的耗时拦截,只需要修改struts.xml

           <action name="user*" class="action.UserAction" method="{1}">

                <result>/user{1}_success.jsp</result>

                <interceptor-ref name="timer"></interceptor-ref>

            </action>

                       即可,控制台显示:Executed action[/struts/useradd!add] took 101 ms.

<think>好的,我现在需要解决用户提到的苍穹外卖day09项目中page.getTotal方法报错的问题。首先,我得了解这个问题的具体情况。用户在使用MyBatis-Plus的分页功能时,遇到page.getTotal报错,可能是空指针或者方法不存在。 首先,我应该检查是否正确配置了MyBatis-Plus的分页插件。如果没有配置,分页查询的total字段可能无法正确获取,导致page.getTotal()返回null,从而在调用时出现空指针异常。正确的配置是在MyBatis的配置类中添加分页拦截器,比如: ```java @Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return interceptor; } } ``` 如果配置没问题,接下来检查分页查询的代码是否正确。用户可能在使用Page对象时没有正确初始化或传递参数。例如,是否在Service层创建了Page对象,并传入了当前页和每页大小: ```java Page<Order> page = new Page<>(currentPage, pageSize); orderMapper.selectPage(page, queryWrapper); ``` 另外,检查是否导入了正确的Page类。有时候可能误导入其他包的同名类,比如com.baomidou.mybatisplus.extension.plugins.pagination.Page,而错误地使用了其他包中的Page类,这会导致方法不存在或参数不匹配。 还有,检查是否在Mapper接口的方法中正确使用了分页参数。如果Mapper方法没有返回Page类型,或者没有正确使用分页参数,也会导致total值无法获取。例如: ```java @Select("SELECT * FROM order ${ew.customSqlSegment}") Page<Order> selectOrderPage(Page<Order> page, @Param(Constants.WRAPPER) QueryWrapper<Order> queryWrapper); ``` 此外,数据库方言的配置也可能影响分页插件的正常工作。如果项目使用的是非默认的数据库(如PostgreSQL),需要在分页拦截器中指定方言: ```java interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.POSTGRE_SQL)); ``` 如果用户自定义了分页SQL,需要确保SQL语句正确,并且统计总数的语句有效。MyBatis-Plus会自动生成COUNT查询,但如果存在复杂查询,可能需要手动优化COUNT语句,或者在XML中定义。 最后,考虑依赖版本问题。检查pom.xml中MyBatis-Plus的版本是否过旧,建议使用较新的稳定版本,如3.4.0以上,避免已知的分页插件bug。 通过以上步骤逐步排查,应该能找到page.getTotal报错的原因并解决。如果用户能提供具体的错误信息或代码片段,可以更精准地定位问题。</think>### 苍穹外卖day09中`page.getTotal()`报错解决方案 #### 1. 检查MyBatis-Plus分页插件配置 未配置分页插件会导致`total`字段无法统计。在MyBatis配置类中添加拦截器: ```java @Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); // 默认MySQL方言 return interceptor; } } ``` 若使用PostgreSQL等数据库需指定方言: ```java new PaginationInnerInterceptor(DbType.POSTGRE_SQL) ``` #### 2. 验证分页查询代码规范 **错误示例**(导致total为null): ```java // 错误:未将page对象传入Mapper查询 Page<Order> page = new Page<>(1,10); List<Order> list = orderMapper.selectList(queryWrapper); System.out.println(page.getTotal()); // 输出0 ``` **正确写法**: ```java Page<Order> page = new Page<>(currentPage, pageSize); orderMapper.selectPage(page, queryWrapper); // 关键:传入page对象 System.out.println(page.getTotal()); ``` #### 3. 检查Page对象导入路径 确认导入的是MyBatis-Plus的Page类: ```java import com.baomidou.mybatisplus.extension.plugins.pagination.Page; // ✅正确 // 错误:import org.springframework.data.domain.Page; ❌ ``` #### 4. 验证Mapper接口定义 Mapper接口需直接返回Page类型: ```java @Mapper public interface OrderMapper extends BaseMapper<Order> { // 自定义分页查询需显式声明返回类型 Page<Order> selectCustomPage(Page<Order> page, @Param("ew") QueryWrapper<Order> wrapper); } ``` #### 5. SQL日志分析 开启SQL日志查看是否执行COUNT查询: ```yaml # application.yml mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl ``` 正常日志应包含两条SQL: ```sql SELECT COUNT(*) FROM order WHERE ... # 总数查询 SELECT id,order_no,... FROM order WHERE ... LIMIT 10 # 数据查询 ``` #### 6. 版本兼容性检查 在`pom.xml`中确认使用稳定版本: ```xml <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3.1</version> <!-- 2023年最新稳定版 --> </dependency> ``` #### 7. 特殊场景处理 **多表联查时**需要手动指定count语句: ```java @Select("SELECT o.*,u.name FROM order o LEFT JOIN user u ON o.user_id=u.id ${ew.customSqlSegment}") Page<OrderVO> selectOrderWithUser(Page<OrderVO> page, @Param(Constants.WRAPPER) QueryWrapper<OrderVO> wrapper); ``` **XML映射文件**中定义count语句: ```xml <select id="selectOrderWithUser" resultType="OrderVO"> SELECT o.*,u.name FROM order o LEFT JOIN user u ON o.user_id=u.id ${ew.customSqlSegment} </select> <select id="selectOrderWithUserCount" resultType="java.lang.Long"> SELECT COUNT(*) FROM order o ${ew.customSqlSegment} </select> ``` ### 典型错误场景排查表 | 现象 | 可能原因 | 解决方案 | |---------|-----------|-----------| | `java.lang.NullPointerException` | 未调用`selectPage()`直接使用page对象 | 确保调用`mapper.selectPage(page,wrapper)` | | `getTotal() always returns 0` | 分页插件未生效 | 检查配置类是否被Spring扫描 | | `No such method getTotal()` | 导错Page类 | 确认导入`com.baomidou.mybatisplus.extension.plugins.pagination.Page` | | 分页参数不生效 | 方言配置错误 | 使用`PaginationInnerInterceptor(DbType.MYSQL)` | 通过上述步骤可解决95%以上的分页统计值异常问题。若仍存在问题,建议在Controller层打印`page.toString()`查看完整分页对象数据[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值