目录

1.springboot整合Web

2.springboot整合oss上传文件

3.spring整合视频点播

3.1整合

3.1.1 pom

3.1.2 application.properties

3.1.3 获取凭证

3.1.4 获取url

3.2上传视频

4.spring boot 整合登录jwt token

4.1 依赖pom

4.1.1导入依赖

4.2 工具类

4.2.1JwtUtils .java

4.2.2登录密码  只加密不揭密MD5.java

4.2.3 登录获取token

5.cookie和session和token

5.1session和cookie的区别

5.2 后端接收保存

5.2.1 session和cookie


1.springboot整合Web

 <!--springboot整合Web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>

1.1.2

//templates.list下
@Controller
public class index{@RequestMapping("/index")public String index() {return "list/index";}
}

2.springboot整合oss上传文件

        <!-- 阿里云oss依赖 --><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId></dependency><!-- 日期工具栏依赖 --><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId></dependency>

2.2.2前端设计上传

<form th:action="@{/fileupload}" method="post" enctype="multipart/form-data"><table><tr><td><input type="file" name="file" multiple="multiple" /></td></tr><tr><td><input type="submit" value="提交"/></td></tr><hr></table>
</form>

2.2.3后端设计

    @RequestMapping("fileupload")public String upload(@Param("files") MultipartFile file){//-----------------------上传阿里ossString url = ossService.upload(file);//-----------------------上传本地String fileName = file.getOriginalFilename();//1.获取原文件名System.out.println("fileName"+fileName);int index = fileName.indexOf(".");System.out.println("index"+index);//2.获取后缀String substring = fileName.substring(index, fileName.length());System.out.println("substring"+substring);//3. 获取新的文件名SimpleDateFormat ymd = new SimpleDateFormat("yyyyMMdd");String date = ymd .format(new Date());String newFileName =  date + UUID.randomUUID() + substring;//4将要保存的全路径File file1 = new File("D:/image/"+newFileName);//.提交//查看文件夹是否存在,不存在则创建if(!file1.getParentFile().exists()) {file1.getParentFile().mkdirs();}try {//使用此方法保存必须要绝对路径且文件夹必须已存在,否则报错file.transferTo(file1);System.out.println("成功");} catch (IllegalStateException | IOException e) {e.printStackTrace();}return "0";}
@Service
public class OssServiceImpl implements OssService {@Overridepublic String upload(MultipartFile file) {String endPoint = ConstantPropertiesUtils.END_POINT;String accessKeyId = ConstantPropertiesUtils.ACCESS_KEY_ID;String accessKeySecret = ConstantPropertiesUtils.ACCESS_KEY_SECRET;String bucketName = ConstantPropertiesUtils.BUCKET_NAME;try {
// 创建OSSClient实例。OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, accessKeySecret);// 上传文件流。InputStream inputStream = file.getInputStream();//获取文件名称String fileOriginalFilename = file.getOriginalFilename();//使用uuid在文件名称里面添加唯一值String uuid = UUID.randomUUID().toString().replace("-", "");fileOriginalFilename = uuid + fileOriginalFilename;String datePach = new DateTime().toString("yyyy/MM/dd");fileOriginalFilename = datePach + "/" + fileOriginalFilename;//调用oss进行上传//第一个参数BucketName,第二个参数上传到oss文件的路径和名称,第三个文件输入流ossClient.putObject(bucketName, fileOriginalFilename, inputStream);// 关闭OSSClient。ossClient.shutdown();String url = "http://" + bucketName + "." + endPoint + "/" + fileOriginalFilename;return url;} catch (Exception e) {e.printStackTrace();return null;}}
}
package com.atguigu.oss.utils;import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;//项目启动,spring接口,加载之后,执行接口的方法
@Component
public class ConstantPropertiesUtils implements InitializingBean {//读取配置文件@Value("${aliyun.oss.file.endpoint}")private String endpoint;@Value("${aliyun.oss.file.keyid}")private String keyid;@Value("${aliyun.oss.file.keysecret}")private String keysecret;@Value("${aliyun.oss.file.bucketname}")private String bucketname;public static String END_POINT;public static String ACCESS_KEY_ID;public static String ACCESS_KEY_SECRET;public static String BUCKET_NAME;//定义公共的静态常量@Overridepublic void afterPropertiesSet() throws Exception {END_POINT = endpoint;ACCESS_KEY_ID = keyid;ACCESS_KEY_SECRET = keysecret;BUCKET_NAME = bucketname;}
}
application.properties文件
#阿里云oss
#yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
aliyun.oss.file.endpoint=oss-cn-beijing.aliyuncs.com
# 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
aliyun.oss.file.keyid=LTAI5tG378r3
aliyun.oss.file.keysecret=uf0OWKm6WWcOq9NrzYC
aliyun.oss.file.bucketname=edu-yu10

3.spring整合视频点播

3.1整合

3.1.1 pom

         <dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-core</artifactId><version>4.3.3</version></dependency><dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-vod</artifactId><version>2.15.2</version></dependency><dependency><groupId>com.aliyun</groupId><artifactId>aliyun-sdk-vod-upload</artifactId><version>1.4.14</version></dependency><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.1.0</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.28</version></dependency>

3.1.2 application.properties

查看RAM 访问控制 (aliyun.com)获取用户的id和secret

文档创建角色并进行STS临时授权 (aliyun.com)

aliyun.vod.file.keyid=LTAI5tBE2MLWLiiMRYny1c
aliyun.vod.file.keysecret=6msloN87DayD5rC8soeygWvGn# 最大上传单个文件大小:默认1M
spring.servlet.multipart.max-file-size=1024MB
# 最大置总上传的数据大小 :默认10M
spring.servlet.multipart.max-request-size=1024MB

3.1.3 获取凭证

        //根据视频id获得视频凭证 63e345254a33459d806b437d7fec4be3@GetMapping("getPlayAuth/{id}")public R getPlayAuth(@PathVariable String id) {System.out.println("id"+id);try {//创建初始化对象DefaultAcsClient client = AliyunVodSDKUtils.initVodClient(ConstantVodUtils.ACCESS_KEY_ID, ConstantVodUtils.ACCESS_KEY_SECRET);System.out.println("client"+client);//创建获取凭证的request和response对象GetVideoPlayAuthRequest request = new GetVideoPlayAuthRequest();System.out.println("request"+request);//向request对象中设置视频idrequest.setVideoId(id);System.out.println("request"+request);//调用方法获得凭证GetVideoPlayAuthResponse response = client.getAcsResponse(request);System.out.println("response"+response);String playAuth = response.getPlayAuth();System.out.println("playAuth"+playAuth);return R.ok().data("playAuth", playAuth);} catch (ClientException | com.aliyuncs.exceptions.ClientException e) {e.printStackTrace();throw new yuException(20001,"视频playAuth获取失败");}}
                 AliyunVodSDKUtils.java
public class AliyunVodSDKUtils {public static DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) throws ClientException {String regionId = "cn-shanghai";  // 点播服务接入区域  在视频管理可以看到DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);DefaultAcsClient client = new DefaultAcsClient(profile);return client;}
}

ConstantVodUtils.java

@Component
public class ConstantVodUtils implements InitializingBean {@Value("${aliyun.vod.file.keyid}")private String keyid;@Value("${aliyun.vod.file.keysecret}")private String keysecret;public static String ACCESS_KEY_SECRET;public static String ACCESS_KEY_ID;@Overridepublic void afterPropertiesSet() throws Exception {ACCESS_KEY_ID = keyid;ACCESS_KEY_SECRET = keysecret;}
}

3.1.4 获取url

public static void getPlayUrl() throws ClientException {//创建初始化对象DefaultAcsClient client = AliyunVodSDKUtils.initVodClient("aliyun.vod.file.keyid", "aliyun.vod.file.keysecret");//创建获取视频地址request和responseGetPlayInfoRequest request = new GetPlayInfoRequest();GetPlayInfoResponse response = new GetPlayInfoResponse();//向request对象里面设置视频idrequest.setVideoId("9cc6a580681647029033baabed85dab0");//调用初始化对象里面的方法,传递request,获取数据response = client.getAcsResponse(request);List<GetPlayInfoResponse.PlayInfo> playInfoList = response.getPlayInfoList();//播放地址for (GetPlayInfoResponse.PlayInfo playInfo : playInfoList) {System.out.println("PlayInfo.PlayURL =" + playInfo.getPlayURL() + "\n");}//Base信息System.out.println("VideoBase.Title =" + response.getVideoBase().getTitle() + "\n");}

3.2上传视频

    @PostMapping("uploadAlyiVideo")public R uploadAlyiVideo(MultipartFile file) {System.out.println("VideoId");String VideoId = vodService.uploadVIdeo(file);System.out.println("VideoId"+VideoId);return R.ok().data("VideoId", VideoId);}
@Service
public class VodServiceImpl implements VodService {  @Overridepublic String uploadVIdeo(MultipartFile file) {try {//accessKeyId, accessKeySecret//fileName:上传文件原始名称// 01.03.09.mp4String fileName = file.getOriginalFilename();//title:上传之后显示名称String title = fileName.substring(0, fileName.lastIndexOf("."));//inputStream:上传文件输入流InputStream inputStream = file.getInputStream();UploadStreamRequest request = new UploadStreamRequest(ConstantVodUtils.ACCESS_KEY_ID, ConstantVodUtils.ACCESS_KEY_SECRET, title, fileName, inputStream);UploadVideoImpl uploader = new UploadVideoImpl();UploadStreamResponse response = uploader.uploadStream(request);String videoId = null;if (response.isSuccess()) {videoId = response.getVideoId();} else { //如果设置回调URL无效,不影响视频上传,可以返回VideoId同时会返回错误码。其他情况上传失败时,VideoId为空,此时需要根据返回错误码分析具体错误原因videoId = response.getVideoId();}return videoId;} catch (Exception e) {e.printStackTrace();return null;}}@Overridepublic void removeVideo(String videoId) {try {//初始化对象DefaultAcsClient client = AliyunVodSDKUtils.initVodClient(ConstantVodUtils.ACCESS_KEY_ID,ConstantVodUtils.ACCESS_KEY_SECRET);//创建删除视频的request对象DeleteVideoRequest request = new DeleteVideoRequest();//向request中设置videoIdrequest.setVideoIds(videoId);//调用删除方法DeleteVideoResponse response = client.getAcsResponse(request);System.out.print("RequestId = " + response.getRequestId() + "\n");} catch (ClientException e) {throw new yuException(20001, "视频删除失败");}}
}

4.spring boot 整合登录jwt token

4.1 依赖pom

4.1.1导入依赖

        <!-- JWT--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId></dependency>

4.2 工具类

4.2.1JwtUtils .java

package com.yu.commonutils;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.StringUtils;import javax.servlet.http.HttpServletRequest;
import java.util.Date;/*** @author yu* @since 2012/8/16* 生成字符串,包含用户信息,* jwt生成包含三部分:1头2.有效荷载3.签名哈希 防伪标志*/
public class JwtUtils {public static final long EXPIRE = 1000 * 60 * 60 * 24;//token过期时间public static final String APP_SECRET = "ukc8BDbRigUDaY6pZFfWus2jZWLPHO";//密钥public static String getJwtToken(String id, String nickname){String JwtToken = Jwts.builder()//第一步分.setHeaderParam("typ", "JWT").setHeaderParam("alg", "HS256")//第二部分.setSubject("yu-user").setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() + EXPIRE))//第三部分  token主体.claim("id", id).claim("nickname", nickname).signWith(SignatureAlgorithm.HS256, APP_SECRET).compact();return JwtToken;}/*** 判断token是否存在与有效* @param jwtToken* @return*/public static boolean checkToken(String jwtToken) {if(StringUtils.isEmpty(jwtToken)) return false;try {Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);} catch (Exception e) {e.printStackTrace();return false;}return true;}/*** 判断token是否存在与有效* @param request* @return*/public static boolean checkToken(HttpServletRequest request) {try {String jwtToken = request.getHeader("token");System.out.println("jwtToken"+jwtToken);if(StringUtils.isEmpty(jwtToken)) return false;Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);} catch (Exception e) {e.printStackTrace();return false;}return true;}/*** 根据token获取会员id* @param request* @return*/public static String getMemberIdByJwtToken(HttpServletRequest request) {String jwtToken = request.getHeader("token");if(StringUtils.isEmpty(jwtToken))return "";Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);Claims claims = claimsJws.getBody();System.out.println("claims:"+claims);return (String)claims.get("id");}
}

4.2.2登录密码  只加密不揭密MD5.java

package com.yu.commonutils;import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;public final class MD5 {public static String encrypt(String strSrc) {try {char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8','9', 'a', 'b', 'c', 'd', 'e', 'f' };byte[] bytes = strSrc.getBytes();MessageDigest md = MessageDigest.getInstance("MD5");md.update(bytes);bytes = md.digest();System.out.println("bytes"+bytes);int j = bytes.length;System.out.println("j"+j);char[] chars = new char[j * 2];int k = 0;for (int i = 0; i < bytes.length; i++) {byte b = bytes[i];System.out.println(" bytes[i]"+ bytes[i]);//转化hexCharschars[k++] = hexChars[b >>> 4 & 0xf];chars[k++] = hexChars[b & 0xf];}return new String(chars);} catch (NoSuchAlgorithmException e) {e.printStackTrace();throw new RuntimeException("MD5加密出错!!+" + e);}}public static void main(String[] args) {System.out.println(MD5.encrypt("123456"));}}

4.2.3 登录获取token

package com.yu.educenter.controller;import com.yu.commonutils.JwtUtils;
import com.yu.commonutils.R;
import com.yu.commonutils.user.UcenterMemberOrder;
import com.yu.educenter.entity.UcenterMember;
import com.yu.educenter.entity.vo.RegisterVo;
import com.yu.educenter.service.UcenterMemberService;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletRequest;/*** <p>* 会员表 前端控制器* </p>** @author atguigu* @since 2020-08-11*/
@RestController
@RequestMapping("/educenter/member")
@CrossOrigin
public class UcenterMemberController {@Autowiredprivate UcenterMemberService ucenterMemberService;//电话和密码登录  返回token@PostMapping("login")public R login(@RequestBody UcenterMember ucenterMember){System.out.println("ucenterMember"+ucenterMember);String token =ucenterMemberService.login(ucenterMember);return R.ok().data("token",token);}}
package com.yu.educenter.service.impl;import com.yu.commonutils.JwtUtils;
import com.yu.commonutils.MD5;
import com.yu.commonutils.exceptionhandler.GuliException;
import com.yu.educenter.entity.UcenterMember;
import com.yu.educenter.entity.vo.RegisterVo;
import com.yu.educenter.mapper.UcenterMemberMapper;
import com.yu.educenter.service.UcenterMemberService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;/*** <p>* 会员表 服务实现类* </p>** @author yu* @since 2022-08-11*/
@Service
public class UcenterMemberServiceImpl extends ServiceImpl<UcenterMemberMapper, UcenterMember> implements UcenterMemberService {//用来验证,redis验证码是否匹配@Autowiredprivate RedisTemplate<String,String> redisTemplate;//登录的方法@Overridepublic String login(UcenterMember ucenterMember) {//手机号和密码做登录//1、获取手机号和密码String mobile = ucenterMember.getMobile();String password = ucenterMember.getPassword();//2、如过手机号和密码,直接返回登录失败if (StringUtils.isEmpty(mobile)||StringUtils.isEmpty(password)){throw new YuException(20001,"手机号和密码为空");}//判断手机号是否正确QueryWrapper<UcenterMember> queryWrapper = new QueryWrapper<>();queryWrapper.eq("mobile",mobile);UcenterMember mobileMember = baseMapper.selectOne(queryWrapper);if (mobileMember == null){throw new YuException(20001,"手机号不存在");}//判断密码是否相等//数据库密码进行加密,不能直接对比//MD5对密码进行加密,再与数据库进行比较String password1 = mobileMember.getPassword();if (!MD5.encrypt(password).equals(password1)){throw new YuException(20001,"密码错误");}//判断用户是否被禁用if(mobileMember.getIsDisabled()){throw new YuException(20001,"用户被禁用登录失败");}//登录成功//按照jwt生产token返回String token = JwtUtils.getJwtToken(mobileMember.getId(), mobileMember.getNickname());return token;}}
package com.yu.commonutils.exceptionhandler;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** 自定义异常类*/
@Data
@AllArgsConstructor  //有参数构造器
@NoArgsConstructor   //生成无参数构造
public class YuException extends RuntimeException {private Integer code;//状态码private String msg;//输出消息
}

5.cookie和session和token

cookie原理

token原理

5.1session和cookie的区别

  • cookie数据存放在客户端的浏览器上,session数据 放在服务器上。

  • 单个cookie保存的数据不能超过4K,浏览器都限制一个站点最多保存20个cookie。session没有这种限制

  • cookie比session更不安全,别人可以分析存放在本地的cookie并进行cookie欺骗。(可考虑对cookie加密)

  • session会在一定时间内保存在服务器上。当访问增多时,会比较占用服务器的内容,考虑到减轻服务器负担,可以考虑使用cookie

  • session存放图片验证码session.setAttribute(CAPTCHA_KEY, verifyCode.toLowerCase());

cookie和token的区别

  • token存在哪儿都行,客户端可存放在localstorage或者cookie,而服务器端则会存放于数据库(服务器端的session是直接放在内存中的)

  • cookie 举例:门卫大爷看你的学生证,给你一个编号,以后进行任何操作,都出示编号后服务员去看查你是谁。
     token  举例:直接给门卫大爷看自己学生证

  • 对于token而言,服务器不需要去查看你是谁,是无状态的,而cookie则是相对有状态的。

  • token的可拓展性更强。

  • token可抵御csrf,因为cookie容易伪造,但是token是不容易伪造的。

5.2 后端接收保存

5.2.1 session和cookie

    @RequestMapping("tes")public String tes(HttpServletRequest req,HttpServletResponse response, HttpSession session) {//1.cookieCookie cookie = new Cookie("mobile", "yu");cookie.setMaxAge(Integer.MAX_VALUE);//设置根目录cookie.setPath("/");//Cookie中 maxAge设置为负值 和0的区别//如果设置为负值,则为浏览器进程Cookie(内存中保存),关闭浏览器就失效;//如果设置为0,则立即删除该Cookie。//设置Cookie的最大生命周期,否则浏览器关闭后Cookie即失效//设置cookie过期值时间是7天,7*24*60*60单位是秒Cookie cookie1 = new Cookie("mobile1", "10s");cookie1.setMaxAge(10);//将Cookie加到response中response.addCookie(cookie);response.addCookie(cookie1);//2.session//设置session,浏览器关闭后session即失效session.setAttribute("mobile_session","yu1");/* setMaxInactiveInterval(int   i)   i的单位是秒。*如果设置的值为零或负数,则表示会话将永远不会超时。常用于设置当前会话时间。* 不设置关闭浏览器 放弃值*/session.setMaxInactiveInterval(10);final String id = session.getId();System.out.println("sessionid:"+id);return "file/index";}
    @RequestMapping("getse")public String getse(HttpServletRequest req,HttpServletResponse response, HttpSession session) {//获取session值   浏览器关了就没有了   在cookie中看不到String sesionCode = (String) req.getSession().getAttribute("mobile_session");log.info("sesionCode->{}",sesionCode);final Object mobile = session.getAttribute("mobile_session");log.info("mobile ->{}",mobile );//获取Cookie值Cookie[] cookie1 = req.getCookies();for (int i = 0; i < cookie1.length; i++) {Cookie cook = cookie1[i];System.out.println("cook:"+cook);System.out.println("cook.getName():"+cook.getName()); //KSystem.out.println("cook:"+cook.getValue().toString());//Vif(cook.getName().equalsIgnoreCase("mobile")){ //获取键System.out.println("mobile:"+cook.getValue().toString());    //获取值}}return "file/index";}

6.vue创建命令

vue create vue-vod  创建一个简单的vue项目

cd vue-vod
 $ npm run serve

springboot整合相关推荐

  1. SpringBoot第九篇: springboot整合Redis

    这篇文章主要介绍springboot整合redis,至于没有接触过redis的同学可以看下这篇文章:5分钟带你入门Redis. 引入依赖: 在pom文件中添加redis依赖: <dependen ...

  2. es springboot 不设置id_原创 | 一篇解决Springboot 整合 Elasticsearch

    ElasticSearch 结合业务的场景,在目前的商品体系需要构建搜索服务,主要是为了提供用户更丰富的检索场景以及高速,实时及性能稳定的搜索服务. ElasticSearch是一个基于Lucene的 ...

  3. springboot整合shiro使用shiro-spring-boot-web-starter

    此文章仅仅说明在springboot整合shiro时的一些坑,并不是教程 增加依赖 <!-- 集成shiro依赖 --> <dependency><groupId> ...

  4. db2 springboot 整合_springboot的yml配置文件通过db2的方式整合mysql的教程

    springboot整合MySQL很简单,多数据源就master,slave就行了,但是在整合DB2就需要另起一行,以下是同一个yml文件 先配置MySQL,代码如下 spring: datasour ...

  5. 九、springboot整合rabbitMQ

    springboot整合rabbitMQ 简介 rabbitMQ是部署最广泛的开源消息代理. rabbitMQ轻量级,易于在内部和云中部署. 它支持多种消息传递协议. RabbitMQ可以部署在分布式 ...

  6. 八、springboot整合Spring Security

    springboot整合Spring Security 简介 Spring Security是一个功能强大且可高度自定义的身份验证和访问控制框架.它是保护基于Spring的应用程序的事实标准. Spr ...

  7. 六、springboot整合swagger

    六.springboot整合swagger 简介 swagger 提供最强大,最易用的工具,以充分利用OpenAPI规范. 官网 : https://swagger.io/ 准备工作 pom.xml ...

  8. SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例(转)...

    SpringBoot整合mybatis.shiro.redis实现基于数据库的细粒度动态权限管理系统实例 shiro 目录(?)[+] 前言 表结构 maven配置 配置Druid 配置mybatis ...

  9. SpringBoot整合RabbitMQ-整合演示

    本系列是学习SpringBoot整合RabbitMQ的练手,包含服务安装,RabbitMQ整合SpringBoot2.x,消息可靠性投递实现等三篇博客. 学习路径:https://www.imooc. ...

  10. 【模板引擎】Springboot整合ThymeleafThymeleaf基本语法

    Thymeleaf介绍 thymeleaf是一个XML/XHTML/HTML5模板引擎,可用于Web与非Web环境中的应用开发.它是一个开源的Java库,基于Apache License 2.0许可, ...

最新文章

  1. babylonjs 分部加载模型_使用 Babylon.js 在 HTML 页面加载 3D 对象
  2. weblogic mime-type
  3. Deployer 的使用
  4. 只读域控制器在Server Core中的部署
  5. 计算机老师任课教师寄语,任课老师寄语大全
  6. SpringBoot 2.x (3):文件上传
  7. 《Perl语言入门》学习笔记
  8. 《数字图像处理 第三版》(冈萨雷斯)——第十章 图像分割
  9. 匈牙利命名法为何被淘汰_体育午报:15年魔咒破除!国足淘汰赛终迎一胜
  10. 海外短视频月活1.5亿,欢聚时代拿稳全球短视频入场券?
  11. GPK游戏包安装方法
  12. robotframework框架ui自动化测试上传附件问题
  13. 【Python爬虫案例学习4】Python 爬取meizitu
  14. TSL 传输层安全性协议
  15. 信息安全初学者容易犯的三个毛病
  16. 多线程堆排序算法C语言实现
  17. html需要编译执行吗,Javascript代码需要编译以后才能执行。
  18. 不管你学的是什么专业,你都应该多少懂些管理学的东西之【鳄鱼法则】【鲇鱼效应】...
  19. 4.CRH寄存器和CRL寄存器
  20. 华为快服务助手测试报错No data found

热门文章

  1. 人脸识别最全知识图谱
  2. 分支定界-附Python代码
  3. 运用软件配置管理加强风险管理
  4. 聚类算法——KMeans(K-均值)
  5. html转换为pdf c#,HTML转PDF(C# itextsharp)
  6. ubuntu 安装matlab+matconvnet
  7. 利用canvas的getImageData()方法制作《在线取色器》
  8. QT-700多种实用好看的图标,直接拿来用
  9. 校园一卡通管理信息系统的设计与实现(asp.net)
  10. 计算机连校园网没有弹出页面,校园网连接之后CMCC登录界面不能弹出怎么解决?...