当前位置: 首页 > news >正文

华仁建设网站谷歌google官网入口

华仁建设网站,谷歌google官网入口,服务好的镇江网站优化,东莞 网站建设收费环境搭建 后端部分需要准备#xff1a; sql数据库 创建SpringBoot工程#xff0c;引入对应的依赖(web\mybatis\mysql驱动) 配置文件application.yml中引入mybatis的配置信息 创建包结构#xff0c;并准备实体类 完成今日开发后项目部分内容如下图示 用户注册于登录部分…环境搭建 后端部分需要准备 sql数据库 创建SpringBoot工程引入对应的依赖(web\mybatis\mysql驱动) 配置文件application.yml中引入mybatis的配置信息 创建包结构并准备实体类 完成今日开发后项目部分内容如下图示 用户注册于登录部分相关内容 注册 谈到注册首先就要看看数据库中用户表的构成 然后对应的完成User实体类的开发 Data //lombok 在编译阶段,为实体类自动生成setter getter toString // pom文件中引入依赖 在实体类上添加注解 public class User {private Integer id;//主键IDprivate String username;//用户名private String password;//密码private String nickname;//昵称private String email;//邮箱private String userPic;//用户头像地址private LocalDateTime createTime;//创建时间private LocalDateTime updateTime;//更新时间 }此处用到了lombok技术该技术可以在java文件编译时自动为变量生成getter、setter方法和tostring方法,后期实体类的开发也均会用到该技术。 dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependency 接下来就是要完成Mapper - Service - Controller这三层的对应开发。 在开发之前我们要明确开发需求即用户的注册。 而在用户注册时会出现两种情况注册成功与注册失败。此时我们粗略地将这两种情况对应为 数据库中没有该用户名对应行 - 该用户还尚不存在 -允许注册 -注册 数据库中存在该用户名对应行 - 该用户已经存在 - 不允许注册 -返回注册失败原因 理清逻辑后我们从Mapper层开始开发 首先我们要注意到在用户注册时我们会首先对数据库中是否已经存在该用户进行检测如果没有再在数据库中录入新用户信息 这就涉及到了sql中的两种操作select与insert,所以我们在Mapper层的接口中就要提供这两个操作 Mapper public interface UserMapper {Select(select * from user where username #{username})User getByUserName(String username);Insert(insert into user(username,password,create_time,update_time)values (#{username},#{password},now(),now()))void add(String username, String password); }不要忘记使用Mapper注册该类  再来看Service层 service层开发较为简单只需要将dao层的对应方法调用 service接口 public interface UserService {//用户名查询用户User getByUserName(String username);//新用户注册void register(String username, String password); }而impl文件中在实现这些方法之余我们在service层会对用户输入的密码进行加密这里使用到了MD5加密 Service public class SuerServiceImpl implements UserService {AutowiredUserMapper userMapper;Overridepublic User getByUserName(String username) {User u userMapper.getByUserName(username);return u;}Overridepublic void register(String username, String password) {//密码加密String p Md5Util.getMD5String(password);userMapper.add(username,p);} } 记得检查传入mapper层的密码一定要是加密后的  MD5: public class Md5Util {/*** 默认的密码字符串组合用来将字节转换成 16 进制表示的字符,apache校验下载的文件的正确性用的就是默认的这个组合*/protected static char hexDigits[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f};protected static MessageDigest messagedigest null;static {try {messagedigest MessageDigest.getInstance(MD5);} catch (NoSuchAlgorithmException nsaex) {System.err.println(Md5Util.class.getName() 初始化失败MessageDigest不支持MD5Util。);nsaex.printStackTrace();}}/*** 生成字符串的md5校验值** param s* return*/public static String getMD5String(String s) {return getMD5String(s.getBytes());}/*** 判断字符串的md5校验码是否与一个已知的md5码相匹配** param password 要校验的字符串* param md5PwdStr 已知的md5校验码* return*/public static boolean checkPassword(String password, String md5PwdStr) {String s getMD5String(password);return s.equals(md5PwdStr);}public static String getMD5String(byte[] bytes) {messagedigest.update(bytes);return bufferToHex(messagedigest.digest());}private static String bufferToHex(byte bytes[]) {return bufferToHex(bytes, 0, bytes.length);}private static String bufferToHex(byte bytes[], int m, int n) {StringBuffer stringbuffer new StringBuffer(2 * n);int k m n;for (int l m; l k; l) {appendHexPair(bytes[l], stringbuffer);}return stringbuffer.toString();}private static void appendHexPair(byte bt, StringBuffer stringbuffer) {char c0 hexDigits[(bt 0xf0) 4];// 取字节中高 4 位的数字转换, // 为逻辑右移将符号位一起右移,此处未发现两种符号有何不同char c1 hexDigits[bt 0xf];// 取字节中低 4 位的数字转换stringbuffer.append(c0);stringbuffer.append(c1);}}最后一步我们进行Controller层的开发  在controller层中我们需要进行相应的逻辑判断来验证该用户名是否已经被占用具体操作如下 RestController RequestMapping(/user) public class UserController {AutowiredUserService userService;PostMapping(/register)public Result register(String username,String password){//查询该用户名是否已经存在User u userService.getByUserName(username);if (unull){//用户名没有被占用,注册userService.register(username,password);return Result.success();} else {return Result.error(用户名被占用);}} }Result实体类如下 NoArgsConstructor AllArgsConstructor Data public class ResultT {private Integer code;//业务状态码 0-成功 1-失败private String message;//提示信息private T data;//响应数据//快速返回操作成功响应结果(带响应数据)public static E ResultE success(E data) {return new Result(0, 操作成功, data);}//快速返回操作成功响应结果public static Result success() {return new Result(0, 操作成功, null);}public static Result error(String message) {return new Result(1, message, null);} } 最后的最后我们使用测试软件对注册部分进行测试 先看新用户注册正常注册成功情况 数据库存储情况 可以看到密码的加密工作也顺利完成 再来看看注册失败的情况这里我们直接使用刚才的账密注册 注册失败至此我们的注册功能已完成最基本的开发与测试。  当然我们在日常生活中会发现账户与密码会有一个基本的校验即a-b位的非空字符显然我们还需要对账密进行进行长度检验。 账户密码长度参数校验 这里我预设的账户长度为4-16位 密码长度位11-16位 校验我们在controller层完成 RestController RequestMapping(/user) public class UserController {AutowiredUserService userService;PostMapping(/register)public Result register(String username,String password){if(username ! null username.length()4 username.length() 16 password ! null password.length() 11 password.length() 16){//查询该用户名是否已经存在User u userService.getByUserName(username);if (unull){//用户名没有被占用,注册userService.register(username,password);return Result.success();} else {return Result.error(用户名被占用);}}else{return Result.error(用户名或密码输入不合法);}} } 当然我们会发现仅仅校验账户与密码这两个参数就会导致我们的逻辑判断代码如此繁琐Spring当然也为我们提供了简化方法——Spring Validation框架  Spring Validation框架 Spring提供的一个参数校验框架使用预定义的注解完成参数校验  Spring Validation框架使用流程 第一步、引入Spring Validation框架起步依赖 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-validation/artifactId/dependency 第二步、在参数前面添加Pattren注解 public Result register(Pattern(regexp ^\\S{4,16}$) String username, Pattern(regexp ^\\S{11,16}$)String password){ 第三步、在Controller类上添加Validated注解 RestController RequestMapping(/user) Validated public class UserController {AutowiredUserService userService;PostMapping(/register)public Result register(Pattern(regexp ^\\S{4,16}$) String username, Pattern(regexp ^\\S{11,16}$)String password){//查询该用户名是否已经存在User u userService.getByUserName(username);if (unull){//用户名没有被占用,注册userService.register(username,password);return Result.success();} else {return Result.error(用户名被占用);}} } 当我们输入不合法的账密时我们会发现这里的报错不如我们之前手动返回的所以我们要对其进行参数校验失败异常处理 RestControllerAdvice public class GlobalExceptionHandler {ExceptionHandler(Exception.class)public Result handleExxception(Exception e){e.printStackTrace();return Result.error(StringUtils.hasLength(e.getMessage())?e.getMessage():操作失败);} } 再次使用非法账密测试 可以看到异常处理功能正常运行  登录 在开发之前我们要明确开发需求即用户的登录成功登录后需求返回一个 jwt token 令牌。 而在用户登录时会出现三种情况账密正确成功登录、账号错误登陆失败与密码错误登陆失败。此时我们粗略地将这三种情况对应为 数据库中没有该用户名对应行 - 该用户还尚不存在 -登陆失败 -返回登陆失败原因 数据库中存在该用户名对应行但密码不对应 - 密码输入错误 - 登陆失败 - 返回登录失败原因 数据库中存在该用户名对应行且密码对应 - 账户密码输入正确 - 登陆成功 分析完需求我们会发现我们在书写登录模块时需要对用户的帐户密码进行相应的逻辑判断用到的sql语句为select与insert这两个方法我们在注册模块已经完成了书写所以我们直接在Controller层编写登录模块即可 Controller层技术开发 PostMapping(/login)public ResultString login(Pattern(regexp ^\\S{4,16}$) String username, Pattern(regexp ^\\S{11,16}$)String password){//查询用户是否存在User lUser userService.getByUserName(username);if(lUser null){return Result.error(用户不存在);}//查询密码是否正确(密码需要加密后再与数据库中密码比较)if (Md5Util.getMD5String(password).equals(lUser.getPassword())){return Result.success(jwt token 令牌);}return Result.error(密码错误!);} 可以看到对于账密合法性判断我们采取了与注册时一样的操作 逻辑判断部分也是简单的匹配下面我们来对其进行测试 这是一组正确的账户密码测试可以看到此时我们暂时还没有编写jwt令牌的返回暂时使用一个字符串代替 下面再进行一组错误账户名的测试 可以看到错误信息如期。 最后在进行一组错误密码的测试 测试完毕我们编辑的最最基础的登录部份功能正常运行 登录认证 当我们需要将某些界面设置为登陆后可见时我们就需要对其加入登录认证的功能接下来就进行该功能的开发 我们先建立一个chesscontroller供下例使用 RestController RequestMapping(/article) public class ChessController {PostMapping(/chess)public ResultString chess(){return Result.success(读取所有的棋子数据!);} }登陆验证需要一个令牌该令牌就是一段字符串需要满足下列要求 承载业务数据减少后续请求查询数据库次数 防篡改保证信息的合法性和有效性 在web开发中最常用的令牌便是JWT令牌 JWT 全称JSON Web Token 定义了一种简洁的、自包含的格式用于通信双方以json数据格式安全的传输信息 组成 第一部分Header(头)记录令牌类型、签名算法等。例如{alg:HS256,type:JWT} 第二部分PayLoad(有效载荷)携带一些自定义信息、默认信息等。例如{id:1,us1} 第三部分:Signature(签名)防止Token被篡改、切薄安全性。将header、payload加入指定密钥通过指定签名算法计算而来 JWT-生成 首先导入对应依赖坐标 dependencygroupIdcom.auth0/groupIdartifactIdjava-jwt/artifactIdversion4.4.0/version/dependency 接下来编写对应的程序 public class JwtTest {Testpublic void testGen(){MapString, Object claims new HashMap();claims.put(id,1);claims.put(username,zmx);//生成jwt代码String token JWT.create().withClaim(user,claims)//添加载荷.withExpiresAt(new Date(System.currentTimeMillis()1000*60*12))//添加过期时间.sign(Algorithm.HMAC256(cacb));//指定算法配置密钥System.out.println(token);} }如上我输入了一组简单的数据来测试 运行结果 JWT-验证 Testpublic void testParse(){//定义字符串模拟用户传递的tokenString token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoxLCJ1c2VybmFtZSI6InpteCJ9LCJleHAiOjE3MDY5NTUzNTN9.pZ0fYD5rRMPHXzAq_sLC6RKprPGwIiIHoimAuChTzdk;JWTVerifier jwtVerifier JWT.require(Algorithm.HMAC256(cacb)).build();DecodedJWT decodedJWT jwtVerifier.verify(token);//验证token生成一个解析后的JWT对象MapString, Claim claims decodedJWT.getClaims();System.out.println(claims.get(user));} 使用上例生成的JWT进行验证 结果如下 JWT校验时使用的签名密钥必须和生成JWT令牌时使用的密钥是配套的 如果JWT令牌解析校验时报错则说明JWT令牌被篡改或失效了令牌非法 登录认证书写 由于JWT生成与验证的代码过于繁琐所以我们选择使用一个工具类来承载JWT生成与验证的方法 public class JwtUtil {private static final String KEY cacb;//接收业务数据,生成token并返回public static String genToken(MapString, Object claims) {return JWT.create().withClaim(claims, claims).withExpiresAt(new Date(System.currentTimeMillis() 1000 * 60 * 60 * 12)).sign(Algorithm.HMAC256(KEY));}//接收token,验证token,并返回业务数据public static MapString, Object parseToken(String token) {return JWT.require(Algorithm.HMAC256(KEY)).build().verify(token).getClaim(claims).asMap();}} 第一步、在登录界时生成token PostMapping(/login)public ResultString login(Pattern(regexp ^\\S{4,16}$) String username, Pattern(regexp ^\\S{11,16}$)String password){//查询用户是否存在User lUser userService.getByUserName(username);if(lUser null){return Result.error(用户不存在);}//查询密码是否正确(密码需要加密后再与数据库中密码比较)if (Md5Util.getMD5String(password).equals(lUser.getPassword())){MapString,Object claims new HashMap();claims.put(id,lUser.getId());claims.put(usernname,lUser.getUsername());String token JwtUtil.genToken(claims);return Result.success(token);}return Result.error(密码错误!);} 第二步、在需要验证token界面对应的接口验证token(复杂)  还是以list为例(token从请求头中的Authorization读取) GetMapping(/list)public ResultString chess(RequestHeader(name Authorization)String token , HttpServletResponse response){//验证tokentry {MapString,Object claims JwtUtil.parseToken(token);return Result.success(读取所有的棋子数据!);} catch (Exception e){//设置HTTP响应状态码为401response.setStatus(401);return Result.error(请登录!);}} 测试结果如下 验证token高效方法、使用拦截器统一验证token令牌 第一步、将验证token转移到拦截器中 Component public class LoginInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//令牌验证String token request.getHeader(Authorization);//验证tokentry {MapString,Object claims JwtUtil.parseToken(token);//放行return true;} catch (Exception e){//设置HTTP响应状态码为401response.setStatus(401);//不放行return false;}} } 第二步、书写配置类注册拦截器 Configuration public class WebConfig implements WebMvcConfigurer {Autowiredprivate LoginInterceptor loginInterceptor;Overridepublic void addInterceptors(InterceptorRegistry registry) {//注册拦截器,登录接口和注册接口不拦截registry.addInterceptor(loginInterceptor).excludePathPatterns(/user/login,/user/register);} }注意如例中的login与register接口不需要拦截可以直接放行 第三步、修改简化被拦截的接口内容 GetMapping(/list)public ResultString chess(RequestHeader(name Authorization) String token, HttpServletResponse response) {return Result.success(读取所有的棋子数据!);} 测试结果如下
http://www.dnsts.com.cn/news/135692.html

相关文章:

  • 工信部如何查网站备案中英文网站用一个域名还是两个域名利于优化
  • 网站建设开票北京百度推广代理公司
  • 比较好的网站公司潍坊网站建设中公
  • 泰安外贸网站建设公司中企动力网站icp备案通知
  • 佛山新网站制作市场摄影师网站
  • 做网站公司哪家公司网站开发最快框架
  • 株洲网站建设优化企业西安免费网站搭建制作
  • 网站怎么制作做wordpress无法访问首页
  • 微博上如何做网站推广wordpress支付可见下载
  • seo关键词排名优化报价搜索引擎优化排名案例
  • 三拼域名做网站wordpress 网站收录
  • 南部建设局网站网站源码客户
  • 网站建设专员一定要会网站建设吗做住宿网站挣钱吗
  • 旅游网站开发的流程手机app软件
  • 网站 服务器 域名亚马逊雨林火灾
  • 专注合肥网站推广如皋网站建设公司
  • 贸易公司网站设计建设部网站下载
  • h5企业网站定制排名重庆品牌设计公司排行
  • 公司做宣传网站做网站用Linux还是win
  • 网站内容框架app模板图片
  • 互联网网站建设水平个人网页设计dw
  • 域名绑定网站需要多久上海专业网站建设渠道
  • 做古风人物小图的网站或软件上海缘魁网站建设
  • 网站建设小工具一级消防工程师考试大纲
  • 3 建设营销型网站流程我的世界自己做披风网站
  • 网站专题效果图怎么做昌吉网站建设公司
  • 永嘉县住房和城乡建设局网站深圳市房产交易中心官网
  • 织梦网站密码北京制作网站报价
  • 域名和网站名要一样吗母婴网站建设 社区
  • 上海网站推广价格原单手表网站