GVKun编程网logo

第十一章 分页及 BaseController(分页实现原理)

21

如果您对第十一章分页及BaseController和分页实现原理感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解第十一章分页及BaseController的各种细节,并对分页实现原理进行深入的分

如果您对第十一章 分页及 BaseController分页实现原理感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解第十一章 分页及 BaseController的各种细节,并对分页实现原理进行深入的分析,此外还有关于Asp.NET MVC 中登录验证(BaseController自定义控制器)、BaseController、BaseController renderJson 问题、c# – ASP.Net MVC 4使用Attribute还是BaseController?的实用技巧。

本文目录一览:

第十一章 分页及 BaseController(分页实现原理)

第十一章 分页及 BaseController(分页实现原理)

  今天我们来讲分页,分页前端有控件,后端使用 pagehelper。

  从后端开始。先在 entity 里创建 base 文件夹,并在里面创建 PageVo 的类,里面包含 pageSize, pageNum, sortField, sortOrder 四个属性,并添加默认值。用来处理分页

 1 public class PageVo {
 2     private Integer pageSize = 10;
 3     private Integer pageNum = 1;
 4     private String sortField = "id";
 5     private String sortOrder = "desc";
 6  
 7     public Integer getPageSize() {
 8         return pageSize;
 9     }
10 
11     public void setPageSize(Integer pageSize) {
12         this.pageSize = pageSize;
13     }
14  
15     public Integer getPageNum() {
16         return pageNum;
17     }
18 
19     public void setPageNum(Integer pageNum) {
20         this.pageNum = pageNum;
21     }
22 
23     public String getSortField() {
24         return sortField;
25     }
26 
27     public void setSortField(String sortField) {
28         this.sortField = sortField;
29     }
30 
31     public String getSortOrder() {
32         return sortOrder;
33     }
34 
35     public void setSortOrder(String sortOrder) {
36         this.sortOrder = sortOrder;
37     }
38  
39     public String getOrderBy() {
40         if (StringUtil.isEmpty(sortField)) {
41             return "id desc";
42         }
43         return sortField + " " + sortOrder;
44     }
45 }
PageVo

  然后我们打开 UserController 里的,queryUser,添加接受参数 PageVo, service 中的接口及实现进行改造添加 pageVo 参数。

  Pom 中添加对 pagehelp 的引用

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.2.10</version>
</dependency>

 

  引用后,对 PageVo 进行修改,添加实现接口 IPage,默认前台不传排序我们按 id desc 进行排序

public class PageVo implements IPage {

 

  在 entity/base 中创建 PageResult 对象,用来 service 层返回带翻页信息的类,不直接使用 PageInfo 作为返回值是因为,里面有我们用不到的属性,减少无用数据的传递,还有就是可以以后我们需要扩展时方便我们扩展。直接使用 PageInfo 的话我们就没办法直接控制了。

 1 public class PageResult<T> {
 2     private List<T> list;
 3     private Integer pageNum;
 4     private Integer pageSize;
 5     private Long total;
 6     private Integer pages;
 7 
 8     public PageResult(PageInfo<T> pageInfo) {
 9         this.list = pageInfo.getList();
10         this.pageNum = pageInfo.getPageNum();
11         this.pageSize = pageInfo.getPageSize();
12         this.total = pageInfo.getTotal();
13         this.pages = pageInfo.getPages();
14     }
15      //get,set略
16 }

 

  在 UserServiceImpl 中,修改 query 如下。

 

1 @Override
2     public PageResult<User> query(QueryUser vo, PageVo pageVo) {
3         PageHelper.startPage(pageVo);
4         List<User> users = userMapper.select(vo);
5         PageInfo<User> pageInfo = new PageInfo<User>(users);
6         return new PageResult<>(pageInfo);
7     }

 

  然后,我们对返回的结果进行改造,初期还是使用 map 来做,不过创建一个 BaseController 用来处理所有的通用内容,以后获取登陆信息也在这里处理。 

 1 public class BaseController {
 2 
 3     private static final String CODE_SUCCESS = "0";
 4     private static final String CODE_ERROR = "1001";
 5     private static final String CODE_AUTHER = "5001";
 6 
 7     public Map<String, Object> getResultMessage(PageResult result) {
 8         return getResultMessage(true, result.getList(), result.getPageInfo(), CODE_SUCCESS, "");
 9     }
10 
11     public Map<String, Object> getResultMessage(Object data) {
12         return getResultMessage(true, data, CODE_SUCCESS, "");
13     }
14 
15 
16     public Map<String, Object> getResultMessage(Boolean success, Object data, String code, String message) {
17         Map<String, Object> map = new HashMap<>();
18         map.put("success", success);
19         map.put("data", data);
20         map.put("message", message);
21         map.put("code", code);
22         return map;
23     }
24 
25     public Map<String, Object> getResultMessage(Boolean success, Object data, Object pageInfo, String code, String message) {
26         Map<String, Object> map = new HashMap<>();
27         map.put("success", success);
28         map.put("data", data);
29         map.put("page", pageInfo);
30         map.put("message", message);
31         map.put("code", code);
32         return map;
33     }
34 }
View Code

 

  中间还对 PageResult 进行改造,可以将分页信息单独获取出来 

1 public Map<String, Object> getPageInfo() {
2         Map<String, Object> map = new HashMap<>();
3         map.put("pageNum", pageNum);
4         map.put("pageSize", pageSize);
5         map.put("total", total);
6         map.put("pages", pages);
7         return map;
8     }

 

  这是返回 json 的格式。到目前为止后端处理完成

{
    "code": "0",
    "data": [{
        "id": 1,
        "username": "admin",
        "password": "",
        "salt": "",
        "realname": "admin",
        "sex": "1",
        "mail": "a@a.a",
        "phone": "1234567",
        "avatar": "",
        "remarks": "",
        "status": "0",
        "createTime": "2018-12-16 20:00:00",
        "editTime": "2018-12-16 20:00:00",
        "editor": 1,
        "editorName": "admin",
        "lastLoginTime": null,
        "lastLoginIp": null
    }],
    "success": true,
    "page": {
        "total": 1,
        "pages": 1,
        "pageSize": 10,
        "pageNum": 1
    },
    "message": ""
}
json 结果

 

  我们再添加一条记录,id 为 2 的,再刷新界面我们看到了 user 排到 admin 前面了,看控制台的输出也能看到分页和排序了。

 

  查看一下控制台,也能看到查询的 sql 上带有分页和排序信息了

 

  接下来我们在前台加分页了。

  打开 user.vue,在 table 下面添加分页控件的引用

     <el-row style="text-align: right">
            <el-pagination class="pagination"
                           background
                           @size-change="handleSizeChange"
                           @current-change="handleCurrentChange"
                           :current-page="pagination.currentPage"
                           :page-sizes="pagination.pageSizes"
                           :page-size="pagination.pageSize"
                           layout="total, sizes, prev, pager, next, jumper"
                           :total="pagination.total">
            </el-pagination>
        </el-row>

 

  在 data 里,添加相关参数的引用。

 

    data() {
            return {
                loading: true,
                tableData: [],
                pagination: {
                    pageSizes: [1, 10, 20, 50],
                    currentPage: 1,
                    total: 0,
                    pageSize: 10,
                },
            }
        },

 

  添加两个事件

//改变时
            handleSizeChange(val) {
                this.pagination.pageSize = val;
                this.queryList();
            },
            //条目改变时
            handleCurrentChange(val) {
                this.pagination.currentPage = val;
                this.queryList();
            },        

 

  并在查询结果时,对参数进行赋值。我们刚才在返回结果写了 success 及 message,所以我们调整一下返回结果的处理。

            Vue.axios.post(queryUrl, para)
                    .then(function (res) {
                        let result = res.data;
                        if (result.success) {
                            _this.tableData = result.data;
                            _this.pagination.total = result.page.total;
                        } else {
                            this.$message({
                                message: result.message,
                                type: "error",
                            });
                        }
                        _this.loading = false;
                    })
                    .catch(function (error) {
                        this.$message({
                            message: error,
                            type: "error",
                        })
                    });

 

  

  我们再加上一个查询按钮,用来测试一下每次查询后显示到第一页的内容。

 

  完活,不算样式的话。这个查询终于做完了。

  下面是完整的 user.vue 代码

  1 <template>
  2     <div>
  3         <el-row>
  4             <el-button type="primary" size="small" id="search" @click="search">查询</el-button>
  5         </el-row>
  6         <el-table :data="tableData" v-loading="loading" stripe style="width: 100%">
  7             <el-table-column prop="username" label="用户名" width="180"/>
  8             <el-table-column prop="realname" label="姓名名" width="180"/>
  9             <el-table-column prop="sex" label="性别" width="100"/>
 10             <el-table-column prop="mail" label="邮箱" width="180"/>
 11             <el-table-column prop="phone" label="电话" width="180"/>
 12             <el-table-column prop="remark" label="备注" width="180"/>
 13             <el-table-column prop="status" label="状态" width="180"/>
 14             <el-table-column prop="editorName" label="修改人" width="180"/>
 15             <el-table-column prop="editTime" label="修改时间" width="180"/>
 16         </el-table>
 17         <el-row style="text-align: right">
 18             <el-pagination class="pagination"
 19                            background
 20                            @size-change="handleSizeChange"
 21                            @current-change="handleCurrentChange"
 22                            :current-page="pagination.currentPage"
 23                            :page-sizes="pagination.pageSizes"
 24                            :page-size="pagination.pageSize"
 25                            layout="total, sizes, prev, pager, next, jumper"
 26                            :total="pagination.total">
 27             </el-pagination>
 28         </el-row>
 29     </div>
 30 </template>
 31 
 32 <script>
 33     import Vue from ''vue'';
 34 
 35     export default {
 36         name: "userManage",
 37         data() {
 38             return {
 39                 loading: true,
 40                 tableData: [],
 41                 pagination: {
 42                     pageSizes: [1, 10, 20, 50],
 43                     currentPage: 1,
 44                     total: 0,
 45                     pageSize: 10,
 46                 },
 47             }
 48         },
 49         mounted: function () {
 50             this.queryList();
 51         },
 52         methods: {
 53             queryList: function () {
 54 
 55                 var _this = this;
 56                 var queryUrl = "/api/user/query";
 57                 let para = {
 58                     pageNum: this.pagination.currentPage,
 59                     pageSize: this.pagination.pageSize,
 60                 };
 61                 this.loading = true;
 62                 Vue.axios.post(queryUrl, para)
 63                     .then(function (res) {
 64                         let result = res.data;
 65                         if (result.success) {
 66                             _this.tableData = result.data;
 67                             _this.pagination.total = result.page.total;
 68                         } else {
 69                             this.$message({
 70                                 message: result.message,
 71                                 type: "error",
 72                             });
 73                         }
 74                         _this.loading = false;
 75                     })
 76                     .catch(function (error) {
 77                         this.$message({
 78                             message: error,
 79                             type: "error",
 80                         })
 81                     });
 82 
 83             },
 84             //改变时
 85             handleSizeChange(val) {
 86                 this.pagination.pageSize = val;
 87                 this.queryList();
 88             },
 89             //条目改变时
 90             handleCurrentChange(val) {
 91                 this.pagination.currentPage = val;
 92                 this.queryList();
 93             },
 94             search() {
 95                 this.pagination.currentPage = 1;
 96                 this.queryList();
 97             }
 98         }
 99     }
100 </script>
101 
102 <style scoped>
103 
104 </style>
user.vue

 

Asp.NET MVC 中登录验证(BaseController自定义控制器)

Asp.NET MVC 中登录验证(BaseController自定义控制器)

可以声明一个自定义控制器BaseController继承Controller重写Controller中的OnActionExecuting虚方法,然后其他控制器继承BaseController就可以,避免了给每个控制器打个过滤标签去验证

public class BaseController : Controller
    {
        
        public UserInfo LoginUser { get; set; }
        /// <summary>
        /// 执行控制器中的方法之前先执行该方法。
        /// </summary>
        /// <param name="filterContext"></param>
        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
            //if (Session["userInfo"] == null)
            bool isSucess = false;
            if(Request.Cookies["sessionId"]!=null)
            {
                string sessionId = Request.Cookies["sessionId"].Value;
                //根据该值查Memcache.
                object obj=Common.MemcacheHelper.Get(sessionId);
                if(obj!=null)
                {
                    UserInfo userInfo = Common.SerializeHelper.DeserializeToObject<UserInfo>(obj.ToString());
                   LoginUser = userInfo;
                   isSucess = true;
                   Common.MemcacheHelper.Set(sessionId, obj, DateTime.Now.AddMinutes(20));//模拟出滑动过期时间.
                    //留一个后门,测试方便。发布的时候一定要删除该代码。
                   if (LoginUser.UName == "itcast")
                   {
                       return;
                   }
                    //完成权限校验。
                    //获取用户请求的URL地址.
                   string url = Request.Url.AbsolutePath.ToLower();
                    //获取请求的方式.
                   string httpMehotd = Request.HttpMethod;
                    //根据获取的URL地址与请求的方式查询权限表。
                   IApplicationContext ctx = ContextRegistry.GetContext();
                   IBLL.IActionInfoService ActionInfoService = (IBLL.IActionInfoService)ctx.GetObject("ActionInfoService");
                  var actionInfo= ActionInfoService.LoadEntities(a=>a.Url==url&&a.HttpMethod==httpMehotd).FirstOrDefault();
                  if (actionInfo != null)
                  {
                      filterContext.Result = Redirect("/Error.html");
                      return;
                  }

                    //判断用户是否具有所访问的地址对应的权限
                   IUserInfoService UserInfoService = (IUserInfoService)ctx.GetObject("UserInfoService");
                   var loginUserInfo = UserInfoService.LoadEntities(u=>u.ID==LoginUser.ID).FirstOrDefault();
                    //1:可以先按照用户权限这条线进行过滤。
                   var isExt =(from a in loginUserInfo.R_UserInfo_ActionInfo
                               where a.ActionInfoID == actionInfo.ID
                               select a).FirstOrDefault();
                   if (isExt != null)
                   {
                       if (isExt.IsPass)
                       {
                           return;
                       }
                       else
                       {
                           filterContext.Result = Redirect("/Error.html");
                           return;
                       }

                   }
                    //2:按照用户角色权限这条线进行过滤。
                   var loginUserRole = loginUserInfo.RoleInfo;
                   var count = (from r in loginUserRole
                               from a in r.ActionInfo
                               where a.ID == actionInfo.ID
                               select a).Count();
                   if (count < 1)
                   {
                       filterContext.Result = Redirect("/Error.html");
                       return;
                   }
                    

                }
               
               

              //  filterContext.HttpContext.Response.Redirect("/Login/Index");
               
            }
            if (!isSucess)
            {
                filterContext.Result = Redirect("/Login/Index");//注意.
            }
        }
    }
其他继承BaseController
 //统一检查权限问题
    public class ActionInfoController : BaseController
    {
        //
        // GET: /ActionInfo/
        IBLL.IActionInfoService ActionInfoService { get; set; }
        public ActionResult Index()
        {
            return View();
        }
        #region 获取权限信息
        public ActionResult GetActionInfoList()
        {

            int pageIndex = Request["page"] != null ? int.Parse(Request["page"]) : 1;
            int pageSize = Request["rows"] != null ? int.Parse(Request["rows"]) : 5;
            int totalCount;
            short delFlag = (short)DeleteEnumType.Normarl;
            var actionInfoList = ActionInfoService.LoadPageEntities<int>(pageIndex, pageSize, out totalCount, r => r.DelFlag == delFlag, r => r.ID, true);
            var temp = from r in actionInfoList
                       select new { ID = r.ID, ActionInfoName = r.ActionInfoName, Sort = r.Sort, SubTime = r.SubTime, Remark = r.Remark, Url = r.Url, ActionTypeEnum = r.ActionTypeEnum, HttpMethod = r.HttpMethod };
            return Json(new { rows = temp, total = totalCount }, JsonRequestBehavior.AllowGet);
        }
        #endregion

        #region 获取上传的文件.
        public ActionResult GetFileUp()
        {
            HttpPostedFileBase file=Request.Files["fileUp"];
            string fileName = Path.GetFileName(file.FileName);
            string fileExt = Path.GetExtension(fileName);
            if (fileExt == ".jpg")
            {
                string dir = "/ImageIcon/" + DateTime.Now.Year + "/" + DateTime.Now.Month + "/" + DateTime.Now.Day + "/";
                Directory.CreateDirectory(Path.GetDirectoryName(Request.MapPath(dir)));
                string newfileName = Guid.NewGuid().ToString();
                string fullDir = dir + newfileName + fileExt;
                file.SaveAs(Request.MapPath(fullDir));
                //自己加上图片的缩略图
                return Content("ok:" + fullDir);
            }
            else
            {
                return Content("no:文件类型错误!!");
            }
        }
        
        #endregion

        #region 完成权限添加
        public ActionResult AddActionInfo(ActionInfo actionInfo)
        {
            actionInfo.DelFlag = 0;
            actionInfo.ModifiedOn = DateTime.Now.ToString();
            actionInfo.SubTime = DateTime.Now;
            actionInfo.Url = actionInfo.Url.ToLower();
            ActionInfoService.AddEntity(actionInfo);
            return Content("ok");
        }
        #endregion

    }


BaseController

BaseController

package com.lkx.base;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ModelAttribute;

import com.lkx.domain.UserBean;

/**
 * ClassName:BaseController 
 * Function: TODO ADD FUNCTION.
 * Reason: TODO ADD REASON.
 * Date:     2016年12月5日 下午5:55:26
 * @author   likaixuan
 * @version  V1.0
 * @since    JDK 1.7
 * @see
 */
@Component
public class BaseController {
    
    @ModelAttribute("user")
    public UserBean getUserInfo(HttpServletRequest request){
        HttpSession session = request.getSession();
        UserBean user  = (UserBean) session.getAttribute("user");
        return user;
    }

}

其他的 Controller 类 extends BaseController 即可使用

BaseController renderJson 问题

BaseController renderJson 问题

@本人纯属虚构 你好,想跟你请教个问题:现在我直接访问index 要获取到数据,getall 方法,不过现在返回的是renderjson 页面用 jstl 获取不到,在index 对应的controller 调用方法放到getattr 也不能放~void 返回值。应该怎么解决?

c# – ASP.Net MVC 4使用Attribute还是BaseController?

c# – ASP.Net MVC 4使用Attribute还是BaseController?

我有一个控制器有几个动作.如果服务上的IsCat字段为false,则应重定向Action:

所以这样的事情:

public ActionResult MyCatAction()
    {
        if (MyService.IsCat==false)
            return RedirectToAnotherControllerAction();
     ...

这可以在属性中完成并应用于整个Controller的一组操作吗?

解决方法

在这种情况下,Action filter是可行的方法:

Action filter,which wraps the action method execution. This filter
can perform additional processing,such as providing extra data to the
action method,inspecting the return value,or canceling execution of
the action method.

这是一个很好的MSDN如何:How to: Create a Custom Action Filter

在你的情况下,你会有这样的事情:

public class RedirectFilterattribute : ActionFilterattribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (MyService.IsCat==false)
            return RedirectToAnotherControllerAction();
    }
}

然后,您将在控制器级别应用此过滤器(适用于所有控制器操作)

[RedirectFilterattribute]
public class MyController : Controller
{
   // Will apply the filter to all actions inside this controller.

    public ActionResult MyCatAction()
    {

    }    
}

或按行动:

[RedirectFilterattribute]
public ActionResult MyCatAction()
{
     // Action logic
     ...
}

今天关于第十一章 分页及 BaseController分页实现原理的讲解已经结束,谢谢您的阅读,如果想了解更多关于Asp.NET MVC 中登录验证(BaseController自定义控制器)、BaseController、BaseController renderJson 问题、c# – ASP.Net MVC 4使用Attribute还是BaseController?的相关知识,请在本站搜索。

本文标签: