网上购物网站建设公司兼职做设计的网站

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

网上购物网站建设公司,兼职做设计的网站,网店代运营公司哪家好,有偿做设计的网站微服务架构 微服务是一种架构风格#xff0c;开发构建应用的时候把应用的业务构建成一个个的小服务#xff08;这就类似于把我们的应用程序构建成了一个个小小的盒子#xff0c;它们在一个大的容器中运行#xff0c;这种一个个的小盒子我们把它叫做服务#xff09;#…微服务架构 微服务是一种架构风格开发构建应用的时候把应用的业务构建成一个个的小服务这就类似于把我们的应用程序构建成了一个个小小的盒子它们在一个大的容器中运行这种一个个的小盒子我们把它叫做服务通过服务的组合来完成具体的业务。服务之间相互独立互不影响 第一个springboot程序 环境 springboot2.7.4 maven3.6.2 初始化项目 通过idea集成工具初始化springboot 1.new一个新的项目选择spring初始化选择官方地址这里我们也可以使用下面的custom填入alibaba的地址来初始化点击next 2.填写组名和项目名选择jdk版本为8删除多余的包路径避免包路径过于复杂点击next 3.初始化导入依赖这里导入两个也可以什么都不用导入后期我们手动导入web和devtools热部署工具每次修改不同重新启动服务器。左上角直接搜索devtools即可点击next 4.最后一步点击finish至此项目初始化完毕 ResponseBody的使用返回json字符串 ResponseBody是在标注了Controller的类中使用的它本身标注在类的方法上代表该类的这个方法只返回json字符串不经过视图解析进行视图跳转。和RestController不同的是它可以使用在控制视图跳转的类标注了Controller的类中只标注一个方法不进入视图解析器。 import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;Controller public class HelloController {RequestMapping(/hello)ResponseBodypublic String hello() {return hello,world!;} }修改默认端口号 在application.properties文件中或者application.yml文件中

修改项目的端口号

server.port8081修改启动默认logo 因为springboot的默认配置。默认配置中存在一个路径resource/banner.txt如果该路径下的banner.txt文件存在则启动logo显示为该文件内容。如果不存在则显示默认logo。所以我们只需要新建一个文件banner.txt就可以替换logo springboot自动装配原理 springboot项目都是基于自动配置 springboot的版本管理 在springboot项目中我们导入的依赖不需要版本号这是因为所有的版本都在springboot项目中的父依赖管理了springboot的父依赖规划好了所有我们可能会用到的jar包的版本。选择了springboot的版本也就是选择了之后所有用到jar包的版本。springboot核心依赖都在父工程中 springboot启动器 所有带有starter的依赖都是springboot的启动器。启动器其实就是springboot把我们实际会用到的的项目的一些场景给抽象出来了。比如web启动器就是给web环境准备的它会把web需要用到的jar打包进入一个依赖这里依赖就是启动器我们只需要导入这个springboot打包好的依赖就可以直接进行相关场景的开发。 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter/artifactId /dependencyspringboot主程序 就像一个普通的java程序一样springboot也就一个主程序入口。这个入口用来启动我们整个springboot项目 //标注一个springboot应用程序 SpringBootApplication public class Springboot01HelloworldApplication {public static void main(String[] args) {SpringApplication.run(Springboot01HelloworldApplication.class, args);}}SpringBootApplication内部原理 这个注解的内部其实也有一个个的其他注解组成。 SpringBootConfiguration springboot配置类Configuration spring配置类Component 组件 EnableAutoConfiguration 启用自动配置AutoConfigurationPackage 自动配置包Import({AutoConfigurationImportSelector.class}) 自动配置包注册Import({AutoConfigurationImportSelector.class}) 导入选择器[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9FIxWVsv-1677311559169)(C:\Users\zhongzheng\Desktop\笔记\JavaWeb\springboot\image-20221015110633289.png)] yaml格式的配置文件 application.yaml非配置的写法

1.可以写kv键值对

name: zhong# 2.对象 student:name: zhongage: 3# 3.对象的行内写法 student2: {name: zhong, age: 4}# 4.数组 pets:- dog- cat- pig# 5.数组的行内写法 pets2: [cat, dog, pig]yaml给实体类赋值ConfigurationProperties 首先在application.yaml中准备好数据 person:name: zhongage: 3happy: falsebirth: 2000/1/1maps: {k1: va, k2: v2}list:- code- music- girldog:name: 旺财age: 3在实体类中加上注解ConfigurationProperties(prefix “person”)括号内的是指定需要给实体类绑定yaml文件中的哪个数据。加上注解之后会爆红提示我们配置但是这个配置可有可无它并不影响程序的正常运行如需解决爆红在pom.xml文件中加入依赖 JSR303校验 Validated在类上标注意思是开启数据校验。然后通过在属性上添加注解来实现校验。 多环境配置和配置文件的位置 配置文件可以在四个位置被检测到 优先级项目/config 项目 resource/config resource 首先第二套环境配置文件名为application-dev.yaml

springboot 的多环境配置可以选择激化哪一个环境

spring:profiles:active: devyaml存在多文档格式 server:port: 8081 spring:profiles:active: test#多文档模式使用 — 分隔开 —server:port: 8082

给第二套环境命名此方式已经弃用

spring:profiles: test

在2.4之后的版本中推荐使用

spring:config:activate:on-profile: dev自动配置原理理解 AutoConfiguration注解去装载一个XXXproperties.java文件这个文件又去通过注解加载了yml文件中我们自定义的一些配置。那么如果我们yml中的配置存在XXXproperties文件生效。自动装配去找到这个文件并且把它加载进来实现加载我们的自定义配置。如果不存在自定义配置那么XXXproperties就会失效AutoConfiguration只会加载它自己已经定义好的一些默认值配置 总结 springboot启动会加载大量的配置类 看我们需要的功能在springboot默认写好的配置类中是否存在 配置类中存在哪些组件只要我们要用的组件存在我们就不需要手动配置 给容器中自动配置类添加组件的时候会从xxproperties类中获取某些属性我们需要在配置文件中指定这些属性的值就好 springboot的web开发 导入静态资源 可以使用maven的方式导入前端的一些包以webjar的方式 dependencygroupIdorg.webjars/groupIdartifactIdjquery/artifactIdversion3.4.1/version /dependencyresource下的这些目录的内容都可以被直接访问 优先级 resource static public 制作首页 springboot有自己的一个首页的配置类它指定了一个在resource目录下的index首页文件会被进入项目于时加载如果我们没有指定他就会加载配置好的一个默认的首页。 我们在resource目录的static目录下新建index.html文件。启动项目即可直接加载该文件 在templates目录下的所有资源只能够通过controller跳转或访问。类似于jsp开发中是WEB-INF目录。如果是需要跳转到templates目录下的页面需要模板引擎的支持 图标定制 link relicon th:href{/public/favicon.ico} typeimage/x-icon/模板引擎Thymeleaf 导入依赖 dependencygroupIdorg.thymeleaf/groupIdartifactIdthymeleaf-spring5/artifactId /dependency dependencygroupIdorg.thymeleaf.extras/groupIdartifactIdthymeleaf-extras-java8time/artifactId /dependency模板写在templates目录下 !DOCTYPE html html xmlns:thhttp://www.thymeleaf.org headmeta charsetUTF-8titleTitle/title /head body !–:th:test表示thymeleaf接管此标签并且绑定标签中的某个属性– div th:text\({msg}/div/body /htmlhtml文件需要使用模板引擎要导入约束 html langen xmlns::thhttp://www.thymeleaf.orgthymeleaf语法 !--utext表示接收的值不会被转义也就是不会被全部识别成字符串-- div th:text\){msg}/div !–正常模式下的text绑定会被识别成字符串的形式例如h1标签也会被页面当成普通字符处理– div th:text\({msg}/div !--遍历后端传递过来的list挨个取出里面的值-- div th:eachuser:\){userList} th:text\({user}/div !--行内写法通过两个中括号中间加入\){}来取值– div th:eachuser:\({userList}[[\){user}]]/div装配扩展springMVC 自定义配置首先新建目录config再新建配置类MyMvcConfig package com.zhong.config;import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;//这个类用来扩展mvc Configuration //EnableWebMvc 如果需要全面自定义mvc配置不想用自动配置的需要加上这个注解 public class MyMvcConfig implements WebMvcConfigurer {/重写视图跳转/Overridepublic void addViewControllers(ViewControllerRegistry registry) {/注册一个视图控制器请求/zhong路径的请求将会返回一个名字为test的视图//这可能是controller注解的mvc底层实现/registry.addViewController(/zhong).setViewName(tset);} } 根目录下的请求都推荐使用这种sprimvc的视图跳转方式配置 package com.zhong.config;import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;//这个类用来扩展mvc Configuration public class MyMvcConfig implements WebMvcConfigurer {Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController(/).setViewName(index);registry.addViewController(/index).setViewName(index);registry.addViewController(/index.html).setViewName(index);} }thymeleaf的路径写法使用{/} 这里/代表项目根路径下面的静态资源目录不用写直接使用它们内部的目录静态资源都使用thymeleaf接管 配置项目根路径 server:servlet:context-path: /zhong国际化 在资源目录下新建目录i18n国际化英文单词的缩写。新建两个文件login.propertieslogin_zh__CN.properties新建完成后ide会自动合并两个文件将它们放在同一个目录下。后面需要加入其他的语言包可以直接在这个ide生成的目录右键add 在idea主界面下方有个选项Resource Bundle可以进行可视化配置配置好我们的语言包之后需要在springboot配置文件中配置

配置文件的真实位置

spring:messages:basename: i18n.login然后在html需要使用到语言包的位置上使用#{}取值 扩展本地解析器来做语言包之间的切换我们可以通过请求中的lang属性来指定返回的语言。在{}路径中使用来传递参数 a classbtn btn-sm th:href{/index(lzh_CH)}中文/a a classbtn btn-sm th:href{/index(lenUS)}English/a在html切换语言按钮中请求连接在config下新建MyLocaleResolver package com.zhong.config;import org.springframework.web.servlet.LocaleResolver; import org.thymeleaf.util.StringUtils;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Locale;public class MyLocaleResolver implements LocaleResolver {//解析请求Overridepublic Locale resolveLocale(HttpServletRequest request) {//获取请求中的语言参数String language request.getParameter(l);Locale locale Locale.getDefault();//取得默认的if (!StringUtils.isEmpty(language)) {String[] split language.split();locale new Locale(split[0], split[1]);}return locale;}Overridepublic void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {} }把它配置到springmvc中让spring接管 Bean public LocaleResolver localeResolver() {return new MyLocaleResolver(); }项目实战 登陆功能实现 LoginController package com.zhong.controller;import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.thymeleaf.util.StringUtils;Controller public class LoginController {RequestMapping(/user/login)public String login(RequestParam(username) String username, RequestParam(password) String password, Model model) {//登陆业务if (!StringUtils.isEmpty(username) 123456.equals(password)) {return redirect:/main;}else {model.addAttribute(loginError, 用户名或密码错误);return index;}}}MyMvcConfig package com.zhong.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;//这个类用来扩展mvc Configuration public class MyMvcConfig implements WebMvcConfigurer {Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController(/).setViewName(index);registry.addViewController(/index).setViewName(index);registry.addViewController(/index.html).setViewName(index);registry.addViewController(/main.html).setViewName(dashboard);registry.addViewController(/main).setViewName(dashboard);}Beanpublic LocaleResolver localeResolver() {return new MyLocaleResolver();} }拦截器 新建类实现拦截器接口LoginHandlerInterceptor package com.zhong.config;import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;public class LoginHandlerInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {Object loginUser request.getSession().getAttribute(loginUser);if (loginUsernull) { // System.out.println(2121212);request.setAttribute(loginError, 请先登录);request.getRequestDispatcher(/index).forward(request, response);return false;}else {return true;}}}LoginController package com.zhong.controller;import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.thymeleaf.util.StringUtils;import javax.servlet.http.HttpSession;Controller public class LoginController {RequestMapping(/user/login)public String login(RequestParam(username) String username,RequestParam(password) String password,Model model,HttpSession session) {//登陆业务if (!StringUtils.isEmpty(username) 123456.equals(password)) {session.setAttribute(loginUser, username);return redirect:/main;}else {model.addAttribute(loginError, 用户名或密码错误);return index;}}}MyMvcConfig package com.zhong.config;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;//这个类用来扩展mvc Configuration public class MyMvcConfig implements WebMvcConfigurer {Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController(/).setViewName(index);registry.addViewController(/index).setViewName(index);registry.addViewController(/index.html).setViewName(index);registry.addViewController(/main.html).setViewName(dashboard);registry.addViewController(/main).setViewName(dashboard);}Overridepublic void addInterceptors(InterceptorRegistry registry) {/配置拦截器/registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns(/).excludePathPatterns(/index.html,/index,/,/user/login,/asserts/css/*,/asserts/js/,/asserts/img/);} }thymeleaf抽取公共页面 使用th:fragment名字可以抽取出这部分的代码作为一个类似插件的部分 在需要插入的地方写上 !–th:insert的意思是将抽取出来的部分插入到div里面作为子元素– div th:insert{dashboard::topbar}/div需要使用{抽取出插件的页面名字::插件名字}同时这种写法也可使用传递参数传递参数就相当于以前的jsp?传递参数 在动态设置导航栏激活状态的时候可以使用表达式加上三元运算符来判断激活状态 !– 接收参数并且判断– a th:class\({activemain.html?nav-link active:nav-link} th:href{/main}/a !--传递参数-- div th:insert~{commons/commons::sidebar(activelist.html)}/div页面操作 theadtrthid/ththlastName/ththemail/ththsex/ththdepartment/ththbirth/thth操作/th/tr /thead tbodytr th:eachemp:\){emps}td th:text\({emp.getId()}/tdtd[[ \){emp.getLastName()} ]]/tdtd th:text\({emp.getEmail()}/tdtd th:text\){emp.getSex()0?女:男}/tdtd th:text\({emp.getDepartment().getDepartmentName()}/tdtd th:text\){#dates.format(emp.getBirth(),yyyy-MM-dd HH:mm:ss)}/tdtdbutton classbtn btn-sm btn-primary编辑/buttonbutton classbtn btn-sm btn-danger删除/button/td/tr /tbody404页面定制 springboot帮助我们配置好的存放错误页面的目录和导向错误页面的路由。我们只需要在templates目录下新建error目录在该目录下新建名字为404或者500的页面即可 spring Data整合JDBC 导入依赖 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-jdbc/artifactId /dependency dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdscoperuntime/scope /dependency配置数据源这里可能需要设置时区但是在my.ini里配置过就不需要设置 spring:datasource:username: rootpassword: 123456url: jdbc:mysql://localhost:3306/mybatis?useUnicodetruecharacterEncodingutf-8useSSLfalsedriver-class-name: com.mysql.jdbc.Driver原始的就是在需要使用JDBC是类中自动装配DataSource就可以使用但是一般我们不这样用我们会用springboot帮我们写好的bean Autowired DataSource dataSource;Test void contextLoads() throws SQLException {//默认数据源System.out.println(dataSource.getClass());Connection connection dataSource.getConnection();System.out.println(connection);connection.close(); }这里介绍一种springboot写好的bean模板叫做 XXXtemplate例如springboot写好的jdbc的bean就叫做jdbc template使用它可以直接连接数据库。并且这个被springboot封装过的jdbc做好了事务它会帮我们自动提交事务。 package com.zhong.controller;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource; import java.util.List; import java.util.Map;RestController public class JDBCController {Autowiredprivate JdbcTemplate jdbcTemplate;GetMapping(/userList)public ListMapString, Object userList() {String sql select * from mybatis.user;ListMapString, Object maps jdbcTemplate.queryForList(sql);return maps;}GetMapping(/addUser)public String addUser() {String sql insert into mybatis.user(id, name, pwd) values(5, xxx, 123456);int update jdbcTemplate.update(sql);return addUserok;}GetMapping(/updateUser/{id})public String updateUser(PathVariable int id) {String sql update mybatis.user set name ?,pwd ? where id ?;;Object[] objects new Object[3];objects[0] aaa;objects[1] 123;objects[2] 5;int update jdbcTemplate.update(sql, objects);return updateUserok;}GetMapping(/deleteUser/{id})public String deleteUser(PathVariable int id) {String sql delete from mybatis.user where id ?;int update jdbcTemplate.update(sql, id);return deleteUserok;} }整合Druid数据源 导入依赖 dependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion1.2.14/version /dependency通过type指定springboot的数据源 spring:datasource:username: rootpassword: 123456url: jdbc:mysql://localhost:3306/mybatis?useUnicodetruecharacterEncodingutf-8useSSLfalsedriver-class-name: com.mysql.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSource#durid数据源专有配置initialSize: 5minIdle: 5maxActive: 20maxWait: 60000timeBetweenEvictionRunsMillis: 60000minEvictableIdleTimeMillis: 300000validationQuery: select 1 from dualtestWileIdle: truetestOnBorrow: falsetestOnReturn: falsepoolPreparedStatements: true#配置监控统计的拦截的filterstat监控统计、log4j日志记录、wall防御sql注入#如果运行时报错 类找不到异常log4j#就导入log4j依赖filters: stat,wall,log4jmaxPoolPreparedStatementPerConnectionSize: 20userGlobalDataSourceStat: trueconnectionProperties: druid.stat.mergeSqltrue;druid.stat.slowSqlMillis500新建目录config新建类DruidConfig package com.zhong.config;import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.support.http.StatViewServlet; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;import javax.sql.DataSource; import java.util.HashMap;//标注这个类是一个配置类 Configuration public class DruidConfig {//将yml文件中配置的属性绑定进来ConfigurationProperties(prefix spring.datasource)Bean //将这个new出来的对象托管给springpublic DataSource druidDataSource() {return new DruidDataSource();}//后台监控//ServletRegistrationBean意思是帮助我们把一些druid的插件注册成beanBean //需要注册为beanpublic ServletRegistrationBean statViewServlet() {//new一个bean的注册参数传递一些插件同时指定路径进入该路径的时候会进入该插件的图形界面ServletRegistrationBeanStatViewServlet bean new ServletRegistrationBean(new StatViewServlet(), /druid/*);//监控后台需要登陆HashMapString, String initParameters new HashMap();//增加配置initParameters.put(loginUsername,admin);//loginUsername固定写法initParameters.put(loginPassword,123456);//固定写法//允许访问initParameters.put(allow, );//如果该属性为空则代表所有人可以访问//禁止访问 // initParameters.put(kuangsheng, 这里写ip地址);//只要这样配置之后这个ip地址就会被禁止访问监控后台bean.setInitParameters(initParameters);//设置初始化参数return bean;}//注册filterBeanpublic FilterRegistrationBean webStatFilter() {FilterRegistrationBean bean new FilterRegistrationBean();bean.setFilter(new WebStatFilter());HashMapString, String initParameters new HashMap();//对请求这些资源或者路劲的请求不统计initParameters.put(exclusions, .js,.css,/druid/);bean.setInitParameters(initParameters);return bean;} }整合mybatis框架 导入依赖 dependencies!–非官方写的启动器会以框架名字开头–dependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactIdversion2.2.2/version/dependency!–官方启动器则会以spring-boot开头–dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-jdbc/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!–老版驱动dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdscoperuntime/scope/dependency–!–新版驱动–dependencygroupIdcom.mysql/groupIdartifactIdmysql-connector-j/artifactIdscoperuntime/scope/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency /dependencies配置数据源 spring:datasource:url: jdbc:mysql://localhost:3306/mybatis?useUnicodetruecharacterEncodingutf-8useSSLfalseusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver# springboot整合mybatis就是接管了mybatis的核心配置文件 mybatis:# 我们需要在这里配置好mybatis的别名映射type-aliases-package: com.zhong.pojo# 配置接口实现xml文件的位置mapper-locations: classpath:mybatis/mapper/.xml 编写实体类 package com.zhong.pojo;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString;Data AllArgsConstructor ToString NoArgsConstructor public class User {private int id;private String name;private String pwd; }编写Mapper接口 package com.zhong.mapper;import com.zhong.pojo.User; import org.apache.ibatis.annotations.Mapper; import org.mybatis.spring.annotation.MapperScan; import org.springframework.stereotype.Repository;import java.util.List;Mapper//表示这个类是一个mybaits的一个mapper //MapperScan(com.zhong.mapper)或者在主启动类上添加mapper包扫描 Repository//在spring中表示这是一个dao层对象 public interface UserMapper {ListUser queryUserList();User queryUserById(int id);int addUser(User user);int updateUser(User user);int deleteUserById(int id); }在resource下编写mapper的实现 ?xml version1.0 encodingUTF-8 ? !DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttps://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.zhong.mapper.UserMapperselect idqueryUserList resultTypeuserselect * from user;/selectselect idqueryUserById resultTypeuser parameterType_intselect * from user where id #{id};/selectinsert idaddUser parameterTypeuserinsert into user(id,name,pwd) values(#{id},#{name},#{pwd});/insertupdate idupdateUser parameterTypeuserupdate user set name #{name}, pwd #{pwd} where id #{id};/updatedelete iddeleteUserById parameterType_intdelete from user where id #{id};/delete /mapper编写controller测试一下 package com.zhong.controller;import com.zhong.mapper.UserMapper; import com.zhong.pojo.User; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource; import java.util.List;RestController public class UserController {Resourceprivate UserMapper userMapper;GetMapping(/queryUserList)public String queryUserList() {ListUser userList userMapper.queryUserList();return userList.toString();}}SpringSecurity安全 这是一个权限认证框架如果不使用它我们用过滤器拦截器一样能够完成权限认证的功能。 导入依赖 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId /dependency编写配置类 方式一web安全适配器已启用 package com.zhong.config;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter {//该方法是链式编程Overrideprotected void configure(HttpSecurity http) throws Exception {//实现首页所有人可以访问功能页只有对应的人可以访问//认证请求http.authorizeRequests().antMatchers(/).permitAll() //对某个路径下的所有请求都允许访问.antMatchers(/level1/).hasRole(vip1) //对该路径下的只有设定好的角色才可以访问.antMatchers(/level2/).hasRole(vip2).antMatchers(/level3/).hasRole(vip3);//配置如果访问没有权限默认跳转到登录页http.formLogin();}Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {//从内存拿到数据来进行验证//这里需要配置一个密码加密方式否则会跑不起来auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())//配置认证的用户用户角色可以配置多个.withUser(zhong).password(new BCryptPasswordEncoder().encode(123456)).roles(vip2,vip3)//可以通过and配置多个认证用户.and().withUser(root).password(new BCryptPasswordEncoder().encode(123456)).roles(vip1,vip2,vip3).and().withUser(guest).password(new BCryptPasswordEncoder().encode(123456)).roles(vip1);} }方式二 新方式不需要继承WebSecurityConfigurerAdapter而是注入一个过滤链的Bean通过这个过滤链去处理用户登录的请求 package com.zhong.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain;Configuration public class SecurityConfig {Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests((authz) - authz.antMatchers(/).permitAll().antMatchers(/level1/).hasRole(vip1).antMatchers(/level2/).hasRole(vip2).antMatchers(/level3/**).hasRole(vip3)).formLogin();return http.build();}Beanpublic InMemoryUserDetailsManager userDetailsService() {PasswordEncoder encoder new BCryptPasswordEncoder();UserDetails user User.withDefaultPasswordEncoder().username(root).password(123456).roles(vip1).build();//该设置密码加密的方式已经弃用只用来写代码示例UserDetails user2 User.withDefaultPasswordEncoder().username(zhong).password(123456).roles(vip1).build();return new InMemoryUserDetailsManager(user,user2);}}注销功能实现 //开启注销功能并清除cookie清除session.但实际上一般不会这么干 // http.logout().deleteCookies(remove).invalidateHttpSession(true); //开启注销功能并让它注销成功之后跳转到我们指定的路径 http.logout().logoutSuccessUrl(/);权限显示控制 导入依赖 dependencygroupIdorg.thymeleaf.extras/groupIdartifactIdthymeleaf-extras-springsecurity5/artifactIdversion3.0.4.RELEASE/version /dependency导入命名空间 在html文件中需要导入命名空间方便使用代码提示。不导入程序一样能够跑起来。 html langen xmlns:thhttp://www.thymeleaf.orgxmlns:sechttp://www.thymeleaf.org/extras/spring-security动态显示内容 !–登录注销– div classright menu!–未登录–div sec:authorize!isAuthenticated()a classitem th:href{/toLogin}i classaddress card icon/i 登录/a/divdiv sec:authorizeisAuthenticated()a classitem!–获取用户名–用户名 span sec:authenticationname/span!–获取用户角色–角色 span sec:authenticationauthorities/span/a/div!–已登陆显示用户名注销–div sec:authorizeisAuthenticated()!–注销–a classitem th:href{/logout}i classsign-out icon/i 注销/a/div!–动态菜单– div classcolumn sec:authorizehasRole(vip1)跨域配置 //关闭默认开启的网站防御攻击以此支持跨域请求 http.csrf().disable();记住我和首页定制 开启记住我功能会保存用户的登陆状态通过向用户电脑存放一个cookie来实现保存登陆状态cookie有效期为两周 http.rememberMe();定制登录页 //定制登录页并且指定处理登陆请求的控制器。这里表单提交必须要是post .formLogin().loginPage(/toLogin).loginProcessingUrl(/login);定制登录页的前提是前端传递的参数必须是username和password如果它们的name是其他的名称框架识别不到就会登陆失败。当然这种参数名字也可以定制通过以下两种方法为参数指定一个新的接收前端参数的名字。 .formLogin().loginPage(/toLogin).usernameParameter(user).passwordParameter(pwd).loginProcessingUrl(/login);同样的记住我功能也可以定制参数 http.rememberMe().rememberMeParameter(remember);Shiro 导入依赖 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentartifactIdspringboot-08-shiro/artifactIdgroupIdcom.zhong/groupIdversion1.0-SNAPSHOT/version/parentmodelVersion4.0.0/modelVersionartifactIdhello-shiro/artifactIddependenciesdependencygroupIdorg.apache.shiro/groupIdartifactIdshiro-core/artifactIdversion1.10.0/version/dependency!– configure logging –dependencygroupIdorg.slf4j/groupIdartifactIdjcl-over-slf4j/artifactIdversion2.0.3/version/dependencydependencygroupIdorg.apache.logging.log4j/groupIdartifactIdlog4j-slf4j-impl/artifactIdversion2.0/version/dependencydependencygroupIdorg.slf4j/groupIdartifactIdslf4j-api/artifactIdversion1.8.0-beta4/version/dependencydependencygroupIdorg.slf4j/groupIdartifactIdslf4j-log4j12/artifactIdversion1.8.0-beta4/version/dependencydependencygroupIdlog4j/groupIdartifactIdlog4j/artifactIdversion1.2.17/version/dependency/dependencies/project日志配置 log4j.rootLoggerINFo,stdoutlog4j.appender.stdoutorg.apache.log4j.ConsoleAppender log4j.appender.stdout.layoutorg.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern%d %p 【%c 】 - ‰m %n#General Apache libraries log4j.logger.org.apacheWARN#Spring log4j.logger.org.springframeworkWARN#Default Shiro Logging log4j.logger.org.apache.shiroINFO#Disable verbose Logging log4j.logger.org.apache.shiro.util.ThreadContextWARN log4j.logger.org.apache.shiro.cache.ehcache.EhCacheWARNshiro配置 [users]

user root with password secret and the admin role

root secret, admin

user guest with the password guest and the guest role

guest guest, guest

user presidentskroob with password 12345 (Thats the same combination on

my luggage!!! ;)), and role president

presidentskroob 12345, president

user darkhelmet with password ludicrousspeed and roles darklord and schwartz

darkhelmet ludicrousspeed, darklord, schwartz

user lonestarr with password vespa and roles goodguy and schwartz

lonestarr vespa, goodguy, schwartz# —————————————————————————–

Roles with assigned permissions

Each line conforms to the format defined in the

org.apache.shiro.realm.text.TextConfigurationRealm#setRoleDefinitions JavaDoc

—————————————————————————–

[roles]

admin role has all permissions, indicated by the wildcard *

admin *

The schwartz role can do anything (*) with any lightsaber:

schwartz lightsaber:*

The goodguy role is allowed to drive (action) the winnebago (type) with

license plate eagle5 (instance specific id)

goodguy winnebago:drive:eagle5快速启动 /** Licensed to the Apache Software Foundation (ASF) under one* or more contributor license agreements. See the NOTICE file* distributed with this work for additional information* regarding copyright ownership. The ASF licenses this file* to you under the Apache License, Version 2.0 (the* License); you may not use this file except in compliance* with the License. You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing,* software distributed under the License is distributed on an* AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY* KIND, either express or implied. See the License for the* specific language governing permissions and limitations* under the License./import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.; import org.apache.shiro.mgt.DefaultSecurityManager; import org.apache.shiro.realm.text.IniRealm; import org.apache.shiro.session.Session; import org.apache.shiro.subject.Subject; import org.slf4j.Logger; import org.slf4j.LoggerFactory;/*** Simple Quickstart application showing how to use Shiros API.** since 0.9 RC2*/ public class Quickstart {private static final transient Logger log LoggerFactory.getLogger(Quickstart.class);public static void main(String[] args) {// The easiest way to create a Shiro SecurityManager with configured// realms, users, roles and permissions is to use the simple INI config.// Well do that by using a factory that can ingest a .ini file and// return a SecurityManager instance:// Use the shiro.ini file at the root of the classpath// (file: and url: prefixes load from files and urls respectively):DefaultSecurityManager defaultSecurityManagernew DefaultSecurityManager();IniRealm iniRealmnew IniRealm(classpath:shiro.ini);defaultSecurityManager.setRealm(iniRealm);// for this simple example quickstart, make the SecurityManager// accessible as a JVM singleton. Most applications wouldnt do this// and instead rely on their container configuration or web.xml for// webapps. That is outside the scope of this simple quickstart, so// well just do the bare minimum so you can continue to get a feel// for things.SecurityUtils.setSecurityManager(defaultSecurityManager);// Now that a simple Shiro environment is set up, lets see what you can do:// get the currently executing user:Subject currentUser SecurityUtils.getSubject();// Do some stuff with a Session (no need for a web or EJB container!!!)Session session currentUser.getSession();session.setAttribute(someKey, aValue);String value (String) session.getAttribute(someKey);if (value.equals(aValue)) {log.info(Retrieved the correct value! [ value ]);}// lets login the current user so we can check against roles and permissions:if (!currentUser.isAuthenticated()) {UsernamePasswordToken token new UsernamePasswordToken(lonestarr, vespa);token.setRememberMe(true);try {currentUser.login(token);} catch (UnknownAccountException uae) {log.info(There is no user with username of token.getPrincipal());} catch (IncorrectCredentialsException ice) {log.info(Password for account token.getPrincipal() was incorrect!);} catch (LockedAccountException lae) {log.info(The account for username token.getPrincipal() is locked. Please contact your administrator to unlock it.);}// … catch more exceptions here (maybe custom ones specific to your application?catch (AuthenticationException ae) {//unexpected condition? error?}}//say who they are://print their identifying principal (in this case, a username):log.info(User [ currentUser.getPrincipal() ] logged in successfully.);//test a role:if (currentUser.hasRole(schwartz)) {log.info(May the Schwartz be with you!);} else {log.info(Hello, mere mortal.);}//test a typed permission (not instance-level)if (currentUser.isPermitted(lightsaber:wield)) {log.info(You may use a lightsaber ring. Use it wisely.);} else {log.info(Sorry, lightsaber rings are for schwartz masters only.);}//a (very powerful) Instance Level permission:if (currentUser.isPermitted(winnebago:drive:eagle5)) {log.info(You are permitted to drive the winnebago with license plate (id) eagle5. Here are the keys - have fun!);} else {log.info(Sorry, you arent allowed to drive the eagle5 winnebago!);}//all done - log out!currentUser.logout();System.exit(0);} }springboot集成shiro 导入依赖 dependencygroupIdorg.apache.shiro/groupIdartifactIdshiro-spring/artifactIdversion1.4.1/version /dependency编写配置类 package com.zhong.config;import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection;public class UserRealm extends AuthorizingRealm {//授权Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {System.out.println(执行了授权);return null;}//认证Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {System.out.println(执行了认证);return null;} }package com.zhong.config;import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;Configuration public class ShiroConfig {//shiroFilterFactoryBeanBeanpublic ShiroFilterFactoryBean getShiroFilterFactorBean(Qualifier(securityManager) DefaultWebSecurityManager defaultWebSecurityManager) {ShiroFilterFactoryBean bean new ShiroFilterFactoryBean();//设置安全管理bean.setSecurityManager(defaultWebSecurityManager);return bean;}//defaultWebSecurityManagerBean(name securityManager)public DefaultWebSecurityManager getDefaultWebSecurityManager(Qualifier(userRealm) UserRealm userRealm) {DefaultWebSecurityManager securityManager new DefaultWebSecurityManager();//管理userRealmsecurityManager.setRealm(userRealm);return securityManager;}//创建realm对象Beanpublic UserRealm userRealm() {return new UserRealm();}}shiro实现登陆认证 Bean public ShiroFilterFactoryBean getShiroFilterFactorBean(Qualifier(securityManager) DefaultWebSecurityManager defaultWebSecurityManager) {ShiroFilterFactoryBean bean new ShiroFilterFactoryBean();//设置安全管理bean.setSecurityManager(defaultWebSecurityManager);//添加shiro的内置过滤器实现登陆认证/anno: 不用认证直接访问authc 认证之后才能访问user 开启记住我功能才能访问perms 拥有某个资源的权限才能访问role 拥有某个角色权限才能访问/LinkedHashMapString, String filterMap new LinkedHashMap();//设置登陆拦截filterMap.put(/user/add, authc);filterMap.put(/user/update, authc);bean.setFilterChainDefinitionMap(filterMap);//设置登陆请求bean.setLoginUrl(/toLogin);return bean; }shiro实现用户认证 userRealm //认证 Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {System.out.println(执行了认证);String username root;String password 123456;UsernamePasswordToken userToken (UsernamePasswordToken) authenticationToken;if (!userToken.getUsername().equals(username)) {return null;//返回空shiro会帮助我们抛出一个不明账户异常UnknownAccountException我们就可以在调用类中捕获来处理这种情况}//shiro不需要我们手动认证密码。它的实现类会自动帮我们验证密码。我们只需要新建一个实现类将用户密码传递进去即可return new SimpleAuthenticationInfo(,password,); }控制器 RequestMapping(/login) public String login(String username, String password, Model model) {//获取当前用户Subject subject SecurityUtils.getSubject();//将前端提交的表单数据封装成令牌UsernamePasswordToken token new UsernamePasswordToken(username, password);try {//使用令牌登陆subject.login(token);//执行登陆方法shrio帮助我们认证用户//shiro会在这里帮助我们调用realm的认证方法。从而使用到userrealm类return index;} catch (UnknownAccountException e) {//异常捕获我们用来处理一些错误情况给前端返回一些错误信息//用户不存在model.addAttribute(msg, 用户名错误);return login;} catch (IncorrectCredentialsException e) {//密码错误model.addAttribute(msg, 密码错误);return login;} }shiro整合mybatis 导入依赖 dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.24/version /dependency dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactId /dependency dependencygroupIdlog4j/groupIdartifactIdlog4j/artifactIdversion1.2.17/version /dependency dependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactIdversion1.2.14/version /dependency dependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactIdversion2.2.2/version /dependency配置数据源 spring:datasource:driver-class-name: com.mysql.cj.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSourceurl: jdbc:mysql://localhost:3306/myabtis?useUnicodetruecharacterEncodingutf-8useSSLfalseusername: rootpassword: 123456#durid数据源专有配置initialSize: 5minIdle: 5maxActive: 20maxWait: 60000timeBetweenEvictionRunsMillis: 60000minEvictableIdleTimeMillis: 300000validationQuery: select 1 from dualtestWileIdle: truetestOnBorrow: falsetestOnReturn: falsepoolPreparedStatements: true#配置监控统计的拦截的filterstat监控统计、log4j日志记录、wall防御sql注入#如果运行时报错 类找不到异常log4j#就导入log4j依赖filters: stat,wall,log4jmaxPoolPreparedStatementPerConnectionSize: 20userGlobalDataSourceStat: trueconnectionProperties: druid.stat.mergeSqltrue;druid.stat.slowSqlMillis500#mybatis配置 mybatis:type-aliases-package: com.zhong.pojomapper-locations: classpath:mybatis/mapper/.xmluserRealm package com.zhong.config;import com.zhong.pojo.User; import com.zhong.service.UserServiceImpl; import org.apache.shiro.authc.; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection;import javax.annotation.Resource;public class UserRealm extends AuthorizingRealm {//整合mybatis连接到数据库ResourceUserServiceImpl userService;//授权Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {System.out.println(执行了授权);return null;}//认证Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {System.out.println(执行了认证);UsernamePasswordToken userToken (UsernamePasswordToken) authenticationToken;//连接数据库User user userService.queryUserByName(userToken.getUsername());if (user null) {return null;//返回空shiro会帮助我们抛出一个不明账户异常UnknownAccountException我们就可以在调用类中捕获来处理这种情况}//shiro不需要我们手动认证密码。它的实现类会自动帮我们验证密码。我们只需要新建一个实现类将数据库的用户密码丢给它让他去验证用户输入的密码即可return new SimpleAuthenticationInfo(,user.getPwd(),);} }shrio请求授权实现 我们需要在shiro的配置文件中配置授权信息 package com.zhong.config;import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;import java.util.LinkedHashMap;Configuration public class ShiroConfig {//shiroFilterFactoryBeanBeanpublic ShiroFilterFactoryBean getShiroFilterFactorBean(Qualifier(securityManager) DefaultWebSecurityManager defaultWebSecurityManager) {ShiroFilterFactoryBean bean new ShiroFilterFactoryBean();//设置安全管理bean.setSecurityManager(defaultWebSecurityManager);//添加shiro的内置过滤器实现登陆认证/anno: 不用认证直接访问authc 认证之后才能访问user 开启记住我功能才能访问perms 拥有某个资源的权限才能访问role 拥有某个角色权限才能访问///授权组用来存放资源被授权给哪些权限LinkedHashMapString, String filterMap new LinkedHashMap();//将该路劲下的资源文件授权给拥有useradd权限的用户。其他用户访问会报401filterMap.put(/user/add,perms[user:add]);filterMap.put(/user/update,perms[user:update]);//设置user路径下的所有请求需要先认证才能放行filterMap.put(/user/, authc);//将权限组放进shiro责任链实例对象beanbean.setFilterChainDefinitionMap(filterMap);//设置登陆请求bean.setLoginUrl(/toLogin);//设置未授权请求bean.setUnauthorizedUrl(/noauth);return bean;}}控制器配置未授权请求跳转 RequestMapping(/noauth) ResponseBody public String unauthorized() {return 未经授权无法访问; }配置认证 package com.zhong.config;import com.zhong.pojo.User; import com.zhong.service.UserServiceImpl; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.subject.Subject;import javax.annotation.Resource;public class UserRealm extends AuthorizingRealm {//授权Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {System.out.println(执行了授权);//设置授权SimpleAuthorizationInfo info new SimpleAuthorizationInfo();//设置授权名称 // info.addStringPermission(user:add);//拿到当前登陆的对象Subject subject SecurityUtils.getSubject();User currentUser (User) subject.getPrincipal();//取出认证方法中存入的用户//设置当前用户权限info.addStringPermission(currentUser.getPerms());return info;}} 用户注销 filterMap.put(/logout, logout);//shiro注销实现在配置文件的内置过滤器控制器只需要做跳转即可 RequestMapping(/logout) public String logout() {return redirect:/toLogin; }shrio整合thymeleaf 动态菜单 导入依赖 dependencygroupIdcom.github.theborakompanioni/groupIdartifactIdthymeleaf-extras-shiro/artifactIdversion2.1.0/version /dependency配置shrio配置文件创建一个整合实例对象托管给spring //整合shrioDialect用来整合thymeleaf Bean public ShiroDialect getShiroDialect() {return new ShiroDialect(); }命名空间导入 xmlns:shirohttp://www.pollix.at/thymeleaf/shiro通过判断认证的身份来动态显示子元素 !–shiro:guest验证是是否为未登录用户是就显示子元素– a th:href{/toLogin} shiro:guest登陆/a!–hasAnyPermissions拥有指定的任何一个权限即可显示子元素– div shiro:hasAnyPermissionsuser:add,user:update/div!–指定拥有特定权限的用户才会显示子元素– div shiro:hasPermissionuser:adda th:href{/user/add}add/a br /div div shiro:hasPermissionuser:uodatea th:href{/user/update}update/a /divSwagger Restful Api 文档在线自动生成工具Api文档和Api定义同步更新直接运行可以在线测试 在项目中使用swagger需要springfox swagger2swaggerUI 在springboot中集成swagger 在springboot2.7以上的版本可能会和swagger存在不兼容的问题原因是springboot改变了swagger需要的一个源码的路径为了兼容swagger3我们需要做一些配置。 新建一个项目依赖中含有web启动器 导入swagger依赖 !– https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui – dependencygroupIdio.springfox/groupIdartifactIdspringfox-swagger-ui/artifactIdversion3.0.0/version /dependency !– https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 – dependencygroupIdio.springfox/groupIdartifactIdspringfox-swagger2/artifactIdversion3.0.0/version /dependency dependencygroupIdio.springfox/groupIdartifactIdspringfox-boot-starter/artifactIdversion3.0.0/version /dependency配置application.yml spring:mvc:pathmatch:matching-strategy: ant_path_matcher在启动类上加上注解EnableOpenApi package com.zhong.swagger;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import springfox.documentation.oas.annotations.EnableOpenApi;SpringBootApplication EnableOpenApi public class SwaggerDemoApplication {public static void main(String[] args) {SpringApplication.run(SwaggerDemoApplication.class, args);}}创建swagger的配置类config/SwaggerConfig.java package com.zhong.swagger.config;import org.springframework.context.annotation.Configuration; import springfox.documentation.swagger2.annotations.EnableSwagger2;Configuration //让springboot帮助我们把swagger加载到配置中 EnableSwagger2 //开启swagger配置 public class SwaggerConfig { }创建测试的类 package com.zhong.swagger.controller;import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;RestController public class HelloController {RequestMapping(/hello)public String hello() {return hello;} }运行项目并访问http://localhost:8080/swagger-ui/index.html成功会显示如下内容
swagger配置 public class SwaggerConfig {//配置swagger的docket的bean实例Beanpublic Docket docket() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());}//配置swagger文档基本信息private ApiInfo apiInfo() {//作者信息Contact contact new Contact(钟, , 2132121qq.com);return new ApiInfo(swagger文档,这里填写文档信息,v1.0,urn:tos,contact,Apache 2.0,http://www.apache.org/licenses/LICENSE-2.0,new ArrayList());} }swagger配置扫描接口 //配置swagger的docket的bean实例 Bean public Docket docket() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())//配置接口扫描.select()//RequestHandlerSelectors配置接口扫描的方式//.basePackage()基于包名扫描//.any()扫描全部//.none()全部不扫描//.withClassAnnotation()扫描类上的注解需要一个注解的反射对象//.withMethodAnnotation()扫描方法上的注解需要一个注解的反射对象.apis(RequestHandlerSelectors.withMethodAnnotation())//过滤器可以让swagger不扫描哪些路径//PathSelectors.ant()参数传递com包下的路径.paths(PathSelectors.ant())//建造者模式.build(); }配置是否启动swagge //配置swagger的docket的bean实例 Bean public Docket docket() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())//配置swagger是否开启.enable(false).select().apis(RequestHandlerSelectors.basePackage(com.zhong.swagger.controller)).build(); }根据配置文件配置的环境决定是否开启swagger #激活环境 spring:profiles:active: promvc:pathmatch:matching-strategy: ant_path_matcher

#多文档模式使用 — 分隔开

在2.4之后的版本中推荐使用on-profile命名环境

spring:config:activate:on-profile: dev

spring:config:activate:on-profile: propublic class SwaggerConfig {Beanpublic Docket docket(Environment environment) {//配置需要开启swagger的环境Profiles profiles Profiles.of(dev,test);//接收一个环境名字判断是否处于该环境中boolean flag environment.acceptsProfiles(profiles);return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).enable(flag)}}配置API文档分组 .groupName(zhong)配置多个文档分组也就是创建多个Docket类并且注册到bean并且使用不同的groupname swagger中的model 只要被swagger扫描的接口中存在有接口的返回值是一个实体类那么这个实体类就会被swagger扫描并且配置到swagger文档中实体类中必须存在属性的get方法该属性才会被swagger扫描到文档中。可以用过注解ApiModel和ApiModelProperty来给文档中的model层加上一些注释 ApiModel(用户实体类) public class User {ApiModelProperty(用户名)private String username;ApiModelProperty(密码)private String password; }ApiOperation()给接口加上swagger注释ApiParam()给接口中的参数加上注释 任务 异步任务 在需要开启多线程处理的业务中加上注解Async表示这是一个异步任务 Service public class AsyncService {//告诉spring这是一个异步任务Asyncpublic void hello() {try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(数据处理完成);} }在启动类上需要加上EnableAsync之后在控制器中正常调用就好spring会帮我们自动开启多线程处理 EnableAsync//开启异步注解扫描 SpringBootApplication public class Springboot09TestApplication {public static void main(String[] args) {SpringApplication.run(Springboot09TestApplication.class, args);} }定时任务 在启动类上加上注解开启定时任务EnableScheduling //cron是指在linux上是时间服务器 //这里使用cron表达式来定时秒 分 时 日 月 星期 //定时任务本身就是一个异步任务到了指定的时间自动执行 Scheduled(cron 40 46 19 * * ?)//在周一到周天中任何时间内的第0秒执行这个程序 public void hello() {System.out.println(hello被执行); }邮件发送 springboot中配置邮件任务需要一个邮件启动器的依赖不过根据springboot的版本不同可能会存在mail启动器没有这个版本下的依赖这个时候需要手动设置mail启动器的版本 springboot版本为2.7.9 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-mail/artifactIdversion2.7.8/version /dependency简单邮件发送 配置 spring:mail:username: 99268317qq.compassword: oqfmuurtzrhost: smtp.qq.com# qq邮箱需要配置SSL加密properties.mail.smtl.ssl.enable: true邮件发送 Resource private JavaMailSender javaMailSender;Test void contextLoads() {// 简单邮件发送SimpleMailMessage simpleMailMessage new SimpleMailMessage();//封装一个邮件对象simpleMailMessage.setSubject(springboot邮件发送测试);//设置邮件标题simpleMailMessage.setText(刘先生收到请回复收到请回复over);//设置邮件正文simpleMailMessage.setTo(1426717qq.com);//设置收件人simpleMailMessage.setFrom(992616qq.com);//设置发件人javaMailSender.send(simpleMailMessage);//调用发送}复杂邮件发送 Test void contextLoads2() throws MessagingException {//复杂邮件发送MimeMessage mimeMessage javaMailSender.createMimeMessage();//创建一个复杂邮件对象//对复杂邮件对象进行封装MimeMessageHelper mimeMessageHelper new MimeMessageHelper(mimeMessage, true);//必须设置一个邮件标题和正文mimeMessageHelper.setSubject(springboot附件邮件测试);mimeMessageHelper.setText(p stylecolor:red带有附件的复杂邮件类型/p, true);//附件mimeMessageHelper.addAttachment(1.jpg, new File(D:\sourceCode\JAVA\springboot-09-test\target\classes\static\1.jpg));//封装源和目标mimeMessageHelper.setTo(1420917qq.com);mimeMessageHelper.setFrom(992616qq.com);javaMailSender.send(mimeMessage);//调用发送 }