Boss项目:部门新增+部门编辑+部门删除+登录拦截(鉴权)(2.4)

一、部门新增:

①DepartmentController:

	@PostMapping("/saveOrUpdate")
    @ResponseBody   
    public Result saveOrUpdate(@RequestBody Department department){
        try {
            if(StringUtils.isEmpty(department.getId())){
                departmentService.save(department);
            }else {
                //departmentService.update(department);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail(e.getMessage());
        }

        return Result.success();
    }

定义新增或编辑方法,传入department对象,如果对象id为空则为新增;否则就为编辑。

②DepartmentService:

​ ↓

DepartmentServiceImpl:

@Override
    public void save(Department department) {

        int m = departmentMapper.insert(department);
        if(m<=0){
            throw new RuntimeException("保存部门失败");
        }
    }

departmentMapper对象调用新增方法,返回受影响行数m,若m<0,则抛出异常。

③DepartmentMapper:

@Insert("insert into department (name,sn) values (#{name},#{sn})")
    @Options(useGeneratedKeys = true,keyColumn = "id",keyProperty = "id")
    int insert(Department department);

useGeneratedKeys = true:开启使用数据库自动生成的主键功能

keyProperty = "id":Java 端的主键映射,将数据库生成的自增主键值,赋值给Java 实体类中的哪个属性

keyColumn = "id":数据库端的主键映射,数据库表中自增主键的列名

二、部门编辑:

 <!-- 使用data-*绑定自定义数据-->
 <a href="#"
    class="btn btn-info btn-xs btn-input"
    data-json='${(department.json)!}' >
    <span class="glyphicon glyphicon-pencil"></span> 编辑
 </a>

data-json='${(department.json)!}' :department中应该有一个json的属性,而.指这个属性的get方法。我们应该把id,name,sn都传到json里。因为数据库中没有叫json的字段,json根本就不存在,json是一个动态字段,也叫逻辑字段。

①pom.xml:

加入依赖:

 <!-- fastjson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
        </dependency>

②Department:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Department {

    private Long id;
    private String name;
    private String sn;



    public String getJson() {//json 逻辑数据

        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        map.put("name", name);
        map.put("sn", sn);

        String jsonString = JSON.toJSONString(map);//Map转JSON类型,需引入依赖

        return jsonString;
    }
}

③DepartmentController:

	@PostMapping("/saveOrUpdate")
    @ResponseBody
    public Result saveOrUpdate(@RequestBody Department department){
        try {
            if(StringUtils.isEmpty(department.getId())){
                departmentService.save(department);
            }else {
                departmentService.update(department);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail(e.getMessage());
        }

        return Result.success();
    }

④DepartmentService:

​ ↓

DepartmentServiceImpl:

   @Override
    public void update(Department department) {
        int m = departmentMapper.update(department);
        if(m<=0){
            throw new RuntimeException("部门修改失败");
        }
    }

⑤DepartmentMapper:

 @Update("update department set name=#{name},sn=#{sn} where id=#{id}")
    int update(Department department);

三、部门删除:

			//删除按钮
            $(".btn-delete").click(function () {
                //获取当前点击的部门id
                let id = $(this).data('id');
                //提示确认框
                $.messager.confirm("警告","是否确认删除?",function () {
                    //发送ajax请求
                    //$.get('/department/delete.do',{id:id},handlerMessage)
                    let data={
                        id:id
                    }
                    axios.get("/department/delete",{  //指定url地址  传递承诺书
                        params: data
                    }) .then(handlerMessage)

                })

            })

①DepartmentController:

@GetMapping("/delete")
    @ResponseBody
    public Result delete(Long id){
        try {
            departmentService.delete(id);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail(e.getMessage());
        }
        return Result.success();
    }

②DepartmentService:

DepartmentServiceImpl:

  @Override
    public void delete(Long id) {
        int m = departmentMapper.delete(id);
        if(m<=0){
            throw new RuntimeException("部门删除失败");
        }

    }

③DepartmentMapper:

 @Delete("delete from department where id=#{id}")
 int delete(Long id);

四、登录拦截(鉴权):

image-20260204190022912

①application.yml(配置文件):

server:
  port: 8000


spring:
    application:
        name: Boos

    datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/crm?serverTimezone=GMT%2B8&characterEncoding=utf8&useUnicode=true&useSSL=false
        username: root
        password: 1234

    freemarker:
      expose-session-attributes: true
      suffix: .ftl
    main:
      allow-circular-references: true //允许循环引用

②annotation.RequireLogin(注解):

@Target({ElementType.METHOD}) // 限定注解只能贴在方法上
@Retention(RetentionPolicy.RUNTIME) // 运行期保留,反射才能获取
@Documented // 生成文档时保留注解信息
public @interface RequireLogin {
    boolean required() default true;
}

标记型注解,本身不执行任何逻辑,仅用来告诉拦截器:这个方法需要做登录校验

③interceptor.WebHandlerInterceptor(拦截器):

public class WebHandlerInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 1. 非Controller的动态方法(如静态资源、跨域预检请求)直接放行
        if(!(handler instanceof HandlerMethod)){
            return true;
        }

        // 2. 处理Controller中的动态方法,强转为处理器方法对象
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        // 通过反射获取目标方法上的@RequireLogin注解:如果方法没贴注解,返回null
        RequireLogin requireLogin = handlerMethod.getMethodAnnotation(RequireLogin.class);

        // 3. 方法无登录注解 或 注解指定无需登录,直接放行
        if(StringUtils.isEmpty(requireLogin) || !requireLogin.required()){
            return true;
        }

        // 4. 方法需要登录,从session中获取当前登录用户
        Employee user = (Employee) request.getSession().getAttribute("user");
        // 5. 未获取到用户(未登录),返回json格式的登录提示,拦截请求
        if(StringUtils.isEmpty(user)){
            // 设置响应内容类型和编码,防止中文乱码
            response.setContentType("text/html;charset=utf-8");
            // 构造失败响应结果
            Result result = Result.fail("请先登录");
            // 将结果转为json字符串写入响应流
            response.getWriter().write(JSON.toJSONString(result));
            response.getWriter().flush();
            response.getWriter().close();
            // 拦截请求,不继续执行后续业务
            return false;
        }

        // 6. 已登录,放行请求执行Controller方法
        return true;
    }
}

登录校验的执行者,实现了 SpringMVC 的HandlerInterceptor接口,重写preHandle方法,完成请求到达Controller层前的前置校验。

preHandle方法:true--->放行 false--->拦截

④config.WebConfiguration(配置类):

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    // 注入拦截器Bean:从Spring容器中获取WebHandlerInterceptor的实例
    @Autowired
    private WebHandlerInterceptor webHandlerInterceptor;

    /**
     * 注册拦截器Bean到Spring容器
     */
    @Bean
    public WebHandlerInterceptor webHandlerInterceptor(){
        return new WebHandlerInterceptor();
    }

    /**
     * 配置拦截器的拦截/放行规则
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(webHandlerInterceptor)
                .addPathPatterns("/**") // 拦截所有请求
                //.excludePathPatterns("/loginUser","logout",...); // 放行无需登录的接口(如登录、退出)
        ;
    }
}

⑤贴注解:

DepartmentController下的:

listGet+listPost+saveOrUpdate+delete 方法上加@RequireLogin

posted on 2026-02-04 19:45  冬冬咚  阅读(0)  评论(0)    收藏  举报