嘘~ 正在从服务器偷取页面 . . .

BaseController 通用操作


BaseController

1、复用基础常见操作

BaseController 使用并不算普遍,有些项目会使用,有些不会,因为有些小功能也完全可以使用工具类实现。

package com.xiaocai.mybatistk.common.base;


import com.xiaocai.mybatistk.common.message.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.HashMap;

/**如果有一些比较通用的操作可以放这里,
 * 当然 BaseController 的并不多,因为这些小功能也完全可以使用工具类实现。
 * 这些方法随便一搜都能找到,这里列举一部分
 * @author xiaocai.zhang
 */
@Slf4j
public class BaseController {


    /**
     * 从请求头中获取token
     *
     * @return
     */
    public String getTokenFromHeader() {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return requestAttributes.getRequest().getHeader("token");
    }

    /**
     * 获取请求的ip地址
     *
     * @return
     */
    protected final String getIpAddr() {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String ip = request.getHeader("x-forwarded-for");
        if (!StringUtils.hasLength(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }

        if (!StringUtils.hasLength(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }

        if (!StringUtils.hasLength(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }

        return ip;
    }

    /**
     * 从thread local获取网络上下文
     */
    public HttpServletRequest getServletRequest() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes servletRequestAttributes;
        if (requestAttributes instanceof ServletRequestAttributes) {
            servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
            return servletRequestAttributes.getRequest();
        }
        return null;
    }

    /**
     * 获取当前客户端session对象
     * @return
     */
    public HttpSession getSession() {
        return getServletRequest().getSession();
    }

    public HttpServletRequest getRequest() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }

    public HttpServletResponse getResponse() {
        return  ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
    }
    /**
     * 设置 cookie
     *
     * @param cookieName
     * @param value
     * @param age
     */
    protected void setCookie(String cookieName, String value, int age) {
        Cookie cookie = new Cookie(cookieName, value);
        cookie.setMaxAge(age);
        // cookie.setHttpOnly(true);
        getResponse().addCookie(cookie);
    }

    /**
     * 保存信息到request中
     *
     * @param key
     * @param value
     */
    public void setRequestAttribute(String key, Object value) {
        this.getRequest().setAttribute(key, value);
    }

    protected String getCookie(String cookieName) {
        Cookie[] cookies = getRequest().getCookies();
        for (Cookie cookie : cookies) {
            if (cookieName.equals(cookie.getName())) {
                return cookie.getValue();
            }
        }

        return null;
    }

    /**
     * 请求方式判断
     *
     * @param request
     * @return
     */
    public boolean isAjaxRequest(HttpServletRequest request) {
        if (!(request.getHeader("accept").indexOf("application/json") > -1
                || (request.getHeader("X-Requested-With") != null
                && request.getHeader("X-Requested-With").indexOf("XMLHttpRequest") > -1)
                || "XMLHttpRequest".equalsIgnoreCase(request.getParameter("X_REQUESTED_WITH")))) {
            return false;
        }
        return true;
    }
}

2、钩子方法使用

有时候,有一些通用的数据校验、权限验证、安全验证,分页信息,可以使用通用controller来实现,当然可以使用拦截器或者过滤器来实现。

但有时候对某些业务需要进行特殊处理,比如前置处理,特殊业务特殊验证等,这时候来个baseController是最开心的时候了。

我们可以在 BaseController 中开心的定义执行模板,和钩子方法,有没有发现,这不就是设计模式里的模板模式吗? 自己曾经玩过,竟然后知后觉…

好吧,面试的时候再也不能说自己没有用过设计模式了…

比如:


package com.xiaocai.mybatistk.common.base;


import com.xiaocai.mybatistk.common.message.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.HashMap;

/**如果有一些比较通用的操作可以放这里,
 * 当然 BaseController 的并不多,因为这些小功能也完全可以使用工具类实现。
 * @author xiaocai.Zhang
 */
@Slf4j
public class BaseController {

    protected void before(HashMap<String,Object> params){
        log.info("这里进行一些通用业务的前置处理--common--before");
    }

    protected void after(HashMap<String,Object> params){
        log.info("这里进行一些通用业务的后置处理--common--after");
    }

    /**
     *  需要进行前置后置处理的方法
     * @param params
     */
    protected CommonResult doSomeBusiness(HashMap<String,Object> params){
        before(params);
        doBusiness(params);
        after(params);
        return CommonResult.ok("事情搞定了");
    }

    protected void doBusiness(HashMap<String,Object> params) {
        log.info("这里进行一些通用业务的处理--common--doBusiness--start");
        String ip = getIpAddr(); // 方法就不重复贴出来了
        log.info("ip--{}", ip);
        String tokenFromHeader = getTokenFromHeader(); // 方法就不重复贴出来了
        log.info("token--{}", tokenFromHeader);
        log.info("这里进行一些通用业务的处理--common--doBusiness--end");
    }

}

通用的定义好了,那怎么使用呢?

使用,定义一个自己的业务类,我就用之前的UserContrller了:

package com.xiaocai.mybatistk.controller;

import com.xiaocai.mybatistk.common.base.BaseController;
import com.xiaocai.mybatistk.common.message.CommonResult;
import com.xiaocai.mybatistk.model.User;
import com.xiaocai.mybatistk.service.base.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;

/**
 * @author Xiaocai.Zhang
 */
@Slf4j
@RestController
public class UserController  extends BaseController {

    @Autowired
    private UserService userService;


    /**
     * http://localhost:8804/userList
     * @param user
     * @return
     */
    @RequestMapping("/userList")
    public CommonResult getUserList(User user) {
        user.setName("J");
        user.setEmail("test");
        List<User> result = userService.getList(user);
        return CommonResult.ok(result);
    }

    /**
     * http://localhost:8804/user?userId=1
     * @param userId
     * @return
     */
    @RequestMapping("/user")
    public CommonResult getUserList(@RequestParam Integer userId) {
        User result = userService.getUserById(userId);
        return CommonResult.ok(result);
    }


    @Override
    protected void before(HashMap<String, Object> params) {
        super.before(params);
        log.info("这里进行一些自己业务的前置处理--user--before");
    }

    @Override
    protected void after(HashMap<String, Object> params) {
        super.after(params);
        log.info("这里进行一些自己的业务处理--user--after");
    }
    /**
     *  http://localhost:8804/dothing
     * @param params
     * @return
     */
    @Override
    @RequestMapping("/dothing")
    public CommonResult doSomeBusiness(HashMap<String, Object> params) {
        super.doSomeBusiness(params);
        return CommonResult.ok("事情搞定了");
    }

    @Override
    protected void doBusiness(HashMap<String, Object> params) {
        super.doBusiness(params);
        log.info("这里进行一些自己的业务处理--user--搞自己的事情");
    }
}

为了方便查看,我把结果搞短一点,通用的调用结果:

INFO 20328 --- [nio-8804-exec-1] c.x.m.common.base.BaseController         : 这里进行一些通用业务的前置处理--common--before
INFO 20328 --- [nio-8804-exec-1] c.x.mybatistk.controller.UserController  : 这里进行一些自己业务的前置处理--user--before
INFO 20328 --- [nio-8804-exec-1] c.x.m.common.base.BaseController         : 这里进行一些通用业务的处理--common--doBusiness--start
INFO 20328 --- [nio-8804-exec-1] c.x.m.common.base.BaseController         : ip--0:0:0:0:0:0:0:1
INFO 20328 --- [nio-8804-exec-1] c.x.m.common.base.BaseController         : token--null
INFO 20328 --- [nio-8804-exec-1] c.x.m.common.base.BaseController         : 这里进行一些通用业务的处理--common--doBusiness--end
INFO 20328 --- [nio-8804-exec-1] c.x.mybatistk.controller.UserController  : 这里进行一些自己的业务处理--user--搞自己的事情
INFO 20328 --- [nio-8804-exec-1] c.x.m.common.base.BaseController         : 这里进行一些通用业务的后置处理--common--after
INFO 20328 --- [nio-8804-exec-1] c.x.mybatistk.controller.UserController  : 这里进行一些自己的业务处理--user--after

效果处理了吧?

有人就要说了,既然是特殊业务可不可以不要调用通用处理,只做自己业务的前置和后置处理?

当然可以!!!

把三个super的调用注释掉就可以。 注意,千万不要把模板方法的supper 干掉了,如果你干掉了super.doBusiness(params); 的模板方法就变成了普通请求,不能调用 before()after() 了。

package com.xiaocai.mybatistk.controller;

import com.xiaocai.mybatistk.common.base.BaseController;
import com.xiaocai.mybatistk.common.message.CommonResult;
import com.xiaocai.mybatistk.model.User;
import com.xiaocai.mybatistk.service.base.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;

/**
 * @author Xiaocai.Zhang
 */
@Slf4j
@RestController
public class UserController  extends BaseController {

    @Autowired
    private UserService userService;


    /**
     * http://localhost:8804/userList
     * @param user
     * @return
     */
    @RequestMapping("/userList")
    public CommonResult getUserList(User user) {
        user.setName("J");
        user.setEmail("test");
        List<User> result = userService.getList(user);
        return CommonResult.ok(result);
    }

    /**
     * http://localhost:8804/user?userId=1
     * @param userId
     * @return
     */
    @RequestMapping("/user")
    public CommonResult getUserList(@RequestParam Integer userId) {
        User result = userService.getUserById(userId);
        return CommonResult.ok(result);
    }


    @Override
    protected void before(HashMap<String, Object> params) {
        //super.before(params);
        log.info("这里进行一些自己业务的前置处理--user--before");
    }

    @Override
    protected void after(HashMap<String, Object> params) {
        //super.after(params);
        log.info("这里进行一些自己的业务处理--user--after");
    }

    /**
     *  http://localhost:8804/dothing
     * @param params
     * @return
     */
    @Override
    @RequestMapping("/dothing")
    public CommonResult doSomeBusiness(HashMap<String, Object> params) {
        super.doSomeBusiness(params);
        return CommonResult.ok("事情搞定了");
    }

    @Override
    protected void doBusiness(HashMap<String, Object> params) {
        //super.doBusiness(params);
        log.info("这里进行一些自己的业务处理--user--搞自己的事情");
    }
}

执行结果:

2020-12-01 17:44:34.074  INFO 1540 --- [nio-8804-exec-1] c.x.mybatistk.controller.UserController  : 这里进行一些自己业务的前置处理--user--before
2020-12-01 17:44:34.074  INFO 1540 --- [nio-8804-exec-1] c.x.mybatistk.controller.UserController  : 这里进行一些自己的业务处理--user--搞自己的事情
2020-12-01 17:44:34.074  INFO 1540 --- [nio-8804-exec-1] c.x.mybatistk.controller.UserController  : 这里进行一些自己的业务处理--user--after

完美!

3、通用的CURD 操作

要做通用的CURD操作,这个应该用的更少了,基本上会和通用的BaseService、 通用的BaseMapper一起玩。

参考链接:通用的BaseController

不过这位哥们的博客只给了个BaseControllerBaseService,也很不错了,就借鉴用一下:

BaseService 就直接用这位哥们的,BaseController 我自己改了一下:


package com.xiaocai.base.demo.common.base;

import com.github.pagehelper.PageInfo;
import com.xiaocai.base.demo.common.message.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 *  通用 BaseController
 * @author Xiaocai.Zhang
 * @param <T>
 */
@Slf4j
public  abstract class BaseController<T> {



    protected void beforeHandle(Map map){
        log.info("前置处理--before");
    }

    protected  void afterHandle(Map map){
        log.info("后置处理--after");
    }

    /**
     *  由子类的实现提供真实的service
     * @return
     */
    public abstract BaseService<T> getBaseService();

    @RequestMapping("/add")
    public Object add(@RequestBody Map map){
        beforeHandle(map);
        T newinstance = getBaseService().newinstance(map);
        T t = getBaseService().add(newinstance);
        afterHandle(map);
        return CommonResult.ok("操作成功");
    }

    @RequestMapping("delete")
    public Object delete(@RequestBody Map map){
        T newinstance = getBaseService().newinstance(map);
        getBaseService().delete(newinstance);
        return CommonResult.ok("操作成功");
    }

    /**
     * 通过主键id批量删除 参数必须为数组,名为ids
     * @param ids
     * @return
     */
    @RequestMapping("deletes")
    public Object batchDelete(@RequestParam("ids[]") Integer ids[]){
        int i = getBaseService().deleteByIds(Arrays.asList(ids));
        if(i>0) {
            return CommonResult.ok("操作成功");
        }else {
            return CommonResult.fail("操作失败");
        }
    }



    @RequestMapping("update")
    public Object update(@RequestBody Map map){
        T t = getBaseService().newinstance(map);
        int rs = getBaseService().update(t);
        if(rs>0) {
            return CommonResult.ok("更新成功");
        }else {
            return CommonResult.fail("更新失败");
        }

    }
    @RequestMapping("/getById")
    public Object getById(@RequestParam(defaultValue = "1") Integer id){
        T t = getBaseService().queryByPrimaryKey(id);
        if(null==t)
            return  CommonResult.fail("查询失败");;
        return CommonResult.ok(t);
    }

    @RequestMapping(value = "/getOne")
    public Object getOne(@RequestBody Map map){
        T t = getBaseService().newinstance(map);
        t = getBaseService().queryOne(t);
        if(null==t)
            return  CommonResult.fail("查询失败");;
        return CommonResult.ok(t);
    }

    @RequestMapping("/getList")
    public Object getList(@RequestBody Map map){
        T t = getBaseService().newinstance(map);
        List<T> list = getBaseService().queryList(t);
        return CommonResult.ok(list);
    }

    /**
     * 附带检索条件的分页查询
     * @param map
     * @param pageNo
     * @param pageSize
     * @return
     */
    @RequestMapping("/getPageQuery")
    public Object getListByPage(@RequestBody Map map, @RequestParam("pageNo") int pageNo, @RequestParam("pageSize") int pageSize){
        T t = getBaseService().newinstance(map);
        PageInfo<T> pageInfo = getBaseService().queryListByPage(t,pageNo,pageSize);
        return CommonResult.ok(pageInfo);
    }

    /**
     * 无检索条件的分页查询 --测试过
     * @param pageNo
     * @param pageSize
     * @return
     */
    @RequestMapping("/getPage")
    public Object getListByPage( @RequestParam("pageNo") int pageNo, @RequestParam("pageSize") int pageSize){
        //T t = getBaseService().newinstance(null);
        T t=null;
        PageInfo<T> pageInfo = getBaseService().queryListByPage(t,pageNo,pageSize);
        return CommonResult.ok(pageInfo);
    }

}

使用:

package com.xiaocai.base.demo.controller;


import com.xiaocai.base.demo.common.base.BaseController;
import com.xiaocai.base.demo.common.base.BaseService;
import com.xiaocai.base.demo.common.message.CommonResult;
import com.xiaocai.base.demo.service.base.UserBsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author Xiaocai.Zhang
 */
@Slf4j
@RestController
@RequestMapping(value = "/user")
public class UserController extends BaseController {

    @Autowired
    private UserBsService userBsService;

    @Override
    public BaseService getBaseService() {
        return userBsService;
    }


    /**
     * http://localhost:8805/user/doUser
     * @return
     */
    @RequestMapping("/doUser")
    public CommonResult doUser(){
       return userBsService.querySpecialAgeOver20();
    }
}

测试访问通用的查询:http://localhost:8805/user/getById
测试访问自定义的查询:http://localhost:8805/user/doUser

完整的Demo在这里:



版权声明: 本博客所有文章除特別声明外,均采用 CC BY-SA 4.0 许可协议。转载请注明来源 Small-Rose / 张小菜 !
评论
  目录