JAVA后端开发注意事项13

JAVA后端开发注意事项

JAVA后端开发注意事项

一.
>登录功能

@Slf4j
@RestController
public class LoginController {

@Autowired
private EmpService empService;

@PostMapping("/login")
public Result login(@RequestBody Emp emp){
    log.info("登录功能{}",emp);

    Emp e = empService.login(emp);
    return e!=null ?Result.success():Result.error("用户名或密码错误");
}

}

Emp login(Emp emp);

@Override
public Emp login(Emp emp) {
return empMapper.getByUsernameAndPassword(emp);
}

@Select("select * from emp where username = #{username} and password=#{password} ")
Emp getByUsernameAndPassword(Emp emp);

二.登录校验
没有登录校验会导致没有验证直接操作页面,不安全。
统一拦截技术 过滤器Filter 拦截器Interceptor
登录标记,每次成功登录都能获取此标记。

会话技术,浏览器与服务器的连接,几个浏览器就有几个会话,一个会话有多个操作
会话跟踪:一种维护浏览器状态的方法,服务器识别多次请求是否是同一浏览器,所以在同一次会话中多次请求的时候共享数据。
客户端会话跟踪技术 cookie
优点:HTTP支持的技术,name自动请求Cookie,自动响应set-Cookie
缺点:移动端无法使用,不安全,用户可以禁用,cookie不能跨域。跨域区分13个维度:协议,IP/域名,端口
服务器会话跟踪技术 session
优点:存储在服务端,安全
缺点:服务器集群环境下无法直接使用Session(负载均衡情况下)
cookie的缺点。

负载均衡:负载均衡服务器根据子服务器情况发送操作指令。

package com.itheima.controller;

import com.itheima.pojo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

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

/**

  • HttpSession演示
    */
    @Slf4j
    @RestController
    public class SessionController {

    //设置Cookie
    @GetMapping(“/c1”)
    public Result cookie1(HttpServletResponse response){
    response.addCookie(new Cookie(“login_username”,“itheima”)); //设置Cookie/响应Cookie
    return Result.success();
    }

    //获取Cookie
    @GetMapping(“/c2”)
    public Result cookie2(HttpServletRequest request){
    Cookie[] cookies = request.getCookies();
    for (Cookie cookie : cookies) {
    if(cookie.getName().equals(“login_username”)){
    System.out.println("login_username: "+cookie.getValue()); //输出name为login_username的cookie
    }
    }
    return Result.success();
    }

    @GetMapping(“/s1”)
    public Result session1(HttpSession session){
    log.info(“HttpSession-s1: {}”, session.hashCode());

     session.setAttribute("loginUser", "tom"); //往session中存储数据
     return Result.success();
    

    }

    @GetMapping(“/s2”)
    public Result session2(HttpServletRequest request){
    HttpSession session = request.getSession();
    log.info(“HttpSession-s2: {}”, session.hashCode());

     Object loginUser = session.getAttribute("loginUser"); //从session中获取数据
     log.info("loginUser: {}", loginUser);
     return Result.success(loginUser);
    

    }
    }

令牌技术
优点:支持PC端,移动端
解决集群环境下的认证问题
减轻服务器端存储压力。
缺点:需要自己实现

JWT令牌
JSON Web Token(https://jwt.io/)
定义了一种简洁的,自包含的格式,用于在通信双方以json数据格式安全的传输信息。由于数字签名的存在,这些信息是可靠的。
组成部分3:
第一部分:Header(头),记录令牌类型,签名算法,{“alg”:“HS356”,“type”:“JWT”} “alg”算法,"type"令牌类型
第二部分:Payload(有效载荷),携带一些自定义信息,默认信息等。例如{“id”:1,“username”:“Tom”}
第三部分:Signature(签名),防止Token被篡改,确保安全性。将header,payload,加入指定密钥,指定的签名算法计算得到。

第1,2部分通过Base64编码得到JWT令牌中的格式,
Base64:是一种基于64个可打印字符(A-Z a-z 0-9 +/)表示二进制数据的编码方式。

登录自动生成令牌并且下发到网页端
public Result login(@RequestBody Emp emp){
log.info(“登录功能{}”,emp);

    Emp e = empService.login(emp);
    //生成令牌,并且下发到网页端
    if(e!=null){
        Map<String, Object> claim = new HashMap<>();
        claim.put("id",e.getId());
        claim.put("username",e.getUsername());
        claim.put("password",e.getPassword());
        String JwtLogin = JwtUtils.generateJwt(claim);
        return Result.success(JwtLogin);
    }


    return Result.error("用户名或密码错误");
}

过滤器(Filter)
概念:Filter过滤器,是JavaWeb三大组件(Servlet,Filter,Listener)之一
过滤器将对资源的请求拦截下,以此实现登录校验,统一编码处理,敏感字符处理等

Filter快速入门
1.定义Filter: 定义一个类,实现Filter接口,并重写其所有方法
2.配置Filter: Filter类上加@WebFilter注解,配置拦截资源的路径。引导类上加
@ServletComponentScan开启Servlet组件支持

过滤器链
介绍:一个web应用中,配置多个过滤器,多个过滤器形成过滤器链。
顺序:注解配置的Filter,优先级按照过滤器类名(字符串)的自然排序。

登录校验

@Slf4j
@WebFilter
public class LoginCheckFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req=(HttpServletRequest) servletRequest;
HttpServletResponse rep = (HttpServletResponse) servletResponse;
//1 获取请求url
String url =req.getRequestURI().toString();
log.info(“获取请求url”,url);
//2.判断是否登录,url中有没有login
if(url.contains(“login”)){
log.info(“登录操作,放行”);
filterChain.doFilter(servletRequest,servletResponse);
return;
}

    //3.从请求req中获取请求头tooken
    String jj =req.getHeader("token");
    //4.判断JWT令牌是否存在
    if(!StringUtils.hasLength(jj)){
        log.info("令牌不存在");
        //返回错误提示信息
         Result error= Result.error("NOT_LOGIN");
        //返回JSON格式
        String s_json= JSON.toJSONString(error);
        rep.getWriter().write(s_json);
        return;


    }
    //5.令牌校验

        try {
            JwtUtils.parseJWT(jj);
        }catch (Exception e){
            e.printStackTrace();
            log.info("令牌解析失败");
            Result error= Result.error("NOT_LOGIN");
            //返回JSON格式
            String s_json= JSON.toJSONString(error);
            rep.getWriter().write(s_json);
            return;
        }

    //6.放行
    log.info("令牌合法,放行");
    filterChain.doFilter(servletRequest,servletResponse);

}

}

拦截器Interceptor
概念,一种动态拦截方法调用的机制,Spring框架中提供的,用来动态拦截控制器方法的执行
作用:拦截请求,指定方法调用前后,根据业务执行预先设定的代码。

根据需求配置不同的拦截路径
/* 一级路径
/** 任意级路径
/depts/* /depts下一级路径
/depts/** /depts下任意级路径

拦截器的执行流程
浏览器的请求-》《-Filter过滤器-》《-DispatcherServiet服务器-》《-Interceptor拦截器-》《-controller控制器

过滤器和拦截器
接口规范不同:过滤器需要实现Filter接口,而拦截器需要实现HandlerInterceptor接口
拦截范围不同:过滤器Filter会拦截所有资源,Interceptor只会拦截Spring环境中的资源。

拦截器新建Interceptor类

@Slf4j
@Component
public class InterCheckInterceptor implements HandlerInterceptor {
@Override
//目标方法放行前运行,true放行,false不放行
public boolean preHandle(HttpServletRequest req, HttpServletResponse rep, Object handler) throws Exception {
//登录校验工作,在操作前

    //1 获取请求url
    String url =req.getRequestURI().toString();
    log.info("获取请求url",url);
    //2.判断是否登录,url中有没有login
    if(url.contains("login")){
        log.info("登录操作,放行");
        return true;
    }

    //3.从请求req中获取请求头tooken
    String jj =req.getHeader("token");
    //4.判断JWT令牌是否存在
    if(!StringUtils.hasLength(jj)){
        log.info("令牌不存在");
        //返回错误提示信息
        Result error= Result.error("NOT_LOGIN");
        //返回JSON格式
        String s_json= JSON.toJSONString(error);
        rep.getWriter().write(s_json);
        return false;
    }
    //5.令牌校验

    try {
        JwtUtils.parseJWT(jj);
    }catch (Exception e){
        e.printStackTrace();
        log.info("令牌解析失败");
        Result error= Result.error("NOT_LOGIN");
        //返回JSON格式
        String s_json= JSON.toJSONString(error);
        rep.getWriter().write(s_json);
        return false;
    }

    //6.放行
    log.info("令牌合法,放行");
    System.out.println("preHandle----");
    return true;
}

@Override   //目标方法运行后放行
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    System.out.println("postHandle-----------");
}

@Override   //视图渲染后放行,最后运行
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    System.out.println("afterCompletion -----------");
}

}

新建WebConfig类
@Configuration
public class WebConfig implements WebMvcConfigurer {

@Autowired
private InterCheckInterceptor interCheckInterceptor;
@Override

// public void addInter
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(interCheckInterceptor).addPathPatterns(“/**”).excludePathPatterns(“/login”);
}
}

三.异常处理

出现异常处理方法
1.在Controller的方法中进行try…catch处理,代码臃肿
2.全局异常处理器,推荐
//全局异常处理器

@RestControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(Exception.class)   //捕获所有异常
public Result ex(Exception ex){
    ex.printStackTrace();
    return Result.error("对不起,操作异常,请联系管理员");
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值