在线生成地址
// 在springboot项目 resources 目录下新建 banner.txt 文件
// 将结果拷贝
# # # # # # # # #
## ### ## ######## ## ## ## ########### ##
## ## ## ## ## ## ## ## ## ## ####
## ## # ## ## ## ## ## ########## ####
# ######## ## # # ## ## ## # ## ## ## ####
### ## # ## ####### ## ############### ########## ####
### # ## # ## ## ## # ## ## ## # ## # ####
# ## # ## ## ########## ## ## ## ## ## ##
## ##### ## ## ## ## ## ## ## ## ### ##
## ##### # ## ## ## #### ## ## ## #### # #### ##
## ## ## ## ### ## #### ## ###### ## ## ## ##
## ## ## ## ### ## ## ## # # ## ## ##
### ## # ## ## ## # ## ## ## ####
## ## ## ## # ## # ## # ## ## ##
## #### # # ### # ############# # ##
# # # # # # #
// 修改启动类可操作显示/关闭banner
SpringApplicationBuilder builder = new SpringApplicationBuilder(D1Application.class);
builder.bannerMode(Banner.Mode.LOG).run(args); // 关闭/显示 banner
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<java.version>1.8java.version>
properties>
# yaml 配置
#解决返回乱码问题
server:
servlet:
encoding:
charset: UTF-8
force: true
enabled: true
// jdk 安装目录 /bin 打开cmd
-alias 别名
-keypass 指定生成密钥的密码
-keyalg 指定密钥使用的加密算法(如 RSA)
-keysize 密钥大小
-validity 过期时间,单位天
-keystore 指定存储密钥的密钥库的生成路径、名称
-storepass 指定访问密钥库的密码
keytool -genkeypair -alias tomcat_https -keypass 123456 -keyalg RSA -keysize 1024 -validity 365 -keystore d:/tomcat_https.keystore -storepass 123456
// 生成的文件放在 resources 目录下
# 配置
#https默认端口:443,http默认端口:80
server:
port: 4439
http-port: 8082
#开启https,配置跟证书一一对应
ssl:
enabled: true
#指定证书
key-store: classpath:tomcat_https.keystore
key-store-type: JKS
#密码
key-store-password: 123456
可能有报错,maven执行clear再运行
// 配置http重指向https
@Configuration
public class SSLUtils {
@Bean
TomcatServletWebServerFactory tomcatServletWebServerFactory(){
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(){
@Override
protected void postProcessContext(Context context){
SecurityConstraint constraint = new SecurityConstraint();
constraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
constraint.addCollection(collection);
context.addConstraint(constraint);
}
};
factory.addAdditionalTomcatConnectors(createTomcatConnertor());
return factory;
}
private Connector createTomcatConnertor(){
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http0");
connector.setPort(8082);
connector.setSecure(false);
connector.setRedirectPort(4439);
return connector;
}
}
# application.yaml
spring:
profiles:
# 区分开发 / 生产
active: dev # prod
application:
# 应用名称
name: d1
#https默认端口:443,http默认端口:80
server:
# http/https 端口
port: 4439
http-port: 8082
#开启https,配置跟证书一一对应
ssl:
enabled: true
#指定证书
key-store: classpath:tomcat_https.keystore.old
key-store-type: JKS
#密码
key-store-password: 123456
servlet:
# utf-8 配置
encoding:
charset: UTF-8
force: true
enabled: true
book: # 自定义配置
name: 测试
author: 999
# application-dev.yaml
server:
servlet:
# 请求前缀
context-path: /dev-api
# application-prod.yaml
server:
servlet:
# 请求前缀
context-path: /prod-api
@Component
@ConfigurationProperties(prefix = "book")
public class BookConfig {
private String name;
private String author;
// get,set,tostring
}
// 使用
@Autowired
BookConfig bookConfig;
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
spring:
# thymeleaf 配置
thymeleaf:
# 是否开启缓存,开发时可设置为false,默认true
cache: true
# 检查模板是否存在,默认true
check-template: true
# 检查模板位置是否存在,默认true
check-template-location: true
# 模板文件编码
encoding: UTF-8
# 模板位置
prefix: classpath:/templates/
# Content-Type 配置
servlet:
content-type: text/html
# 模板文件后缀
suffix: .html
// 新建 User
public class User {
private Integer id;
private String username;
private String password;
// get,set
}
// Controller
@GetMapping("/users")
public ModelAndView users(){
List<User> users = new ArrayList<>();
User u = new User(1,"搜索","123455");
User u1 = new User(2,"刚刚","321123");
User u2 = new User(3,"哈哈","555551");
users.add(u);
users.add(u1);
users.add(u2);
ModelAndView mv = new ModelAndView();
mv.addObject("users",users);
mv.setViewName("users");
return mv;
}
DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div>
<div th:each="user:${users}">
<span th:text="${user.id}">span>
<span th:text="${user.username}">span>
<span th:text="${user.password}">span>
div>
div>
body>
html>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-freemarkerartifactId>
dependency>
spring:
freemarker:
# HttpServletRequest 的属性是否可以覆盖 controller 中的 model 的同明项
allow-request-override: false
# HttpSession 的属性是否可以覆盖 controller 中的 model 的同明项
allow-session-override: false
# 是否开启缓存,开发时可设置为false,默认true
cache: false
# 模板文件编码
charset: UTF-8
# 检查模板位置是否存在,默认true
check-template-location: true
# Content-Type 配置
content-type: text/html
# HttpServletRequest 的属性是否添加到 model
expose-request-attributes: false
# HttpSession 的属性是否添加到 model
expose-session-attributes: false
# 模板文件后缀
suffix: .ftl
# 模板位置
template-loader-path: classpath:/templates/
// Controller 同上
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div>
<#if users ??&& (users?size>0)>
<#list users as user>
<span>${user.id}span>
<span>${user.username}span>
<span>${user.password}span>
#list>
#if>
div>
body>
html>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
1.这个依赖默认加入了 json 处理器
在方法上加注解 @ResponseBody 或 在类上使用 @ResponseController
@ResponseController 等同于 @ResponseBody @Controller
2. 自定义json处理器
Gson
fastjson
spring:
mvc:
static-path-pattern: /static/**
resources:
static-locations: classpath:/static/
# yaml 配置
spring:
servlet:
multipart:
# 单文件上传最大
max-file-size: 10MB
# 多文件上传最大
max-request-size: 100MB
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>单文件上传title>
head>
<body>
<form action="/dev-api/upload" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFile" value="选择文件" />
<input type="submit" value="上传" />
form>
body>
html>
@RestController
public class FileUploadController {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");
private String uploadPath = "/target/classes/static/uploadFile/";
@PostMapping("/upload")
public String upload(MultipartFile uploadFile, HttpServletRequest req) {
String realPath = System.getProperty("user.dir")+uploadPath;
String format = sdf.format(new Date());
File folder = new File(realPath + format);
System.out.println(folder.isDirectory());
if (!folder.isDirectory()) {
folder.mkdirs();
}
String oldName = uploadFile.getOriginalFilename();
String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."), oldName.length());
try {
uploadFile.transferTo(new File(folder, newName));
String filePath = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + "/dev-api/static/uploadFile/" + format + newName;
return filePath;
} catch (IOException e) {
e.printStackTrace();
}
return "失败";
}
}
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>多文件上传title>
head>
<body>
<form action="/dev-api/uploads" method="post" enctype="multipart/form-data">
<input type="file" name="uploadFiles" value="选择文件" multiple/>
<input type="submit" value="上传" />
form>
body>
html>
@PostMapping("/uploads")
public List<String> uploads(MultipartFile[] uploadFiles, HttpServletRequest req) {
List<String> strings = new ArrayList<>();
for (MultipartFile uploadFile : uploadFiles) {
strings.add(this.upload(uploadFile, req)); // 调用单文件上传
}
return strings;
}
@ControllerAdvice
public class CustomExceptionHandler {
@ExceptionHandler(MaxUploadSizeExceededException.class)
public void upload(MaxUploadSizeExceededException e, HttpServletResponse resp) throws IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.write("上传文件大小限制");
out.flush();
out.close();
}
}
@ControllerAdvice
public class GlobalConfig {
@ModelAttribute(value = "info")
public Map<String,String> userInfo(){
HashMap<String,String> map = new HashMap<>();
map.put("id","0");
map.put("ids","01");
return map;
}
}
@GetMapping("/hello")
public String hello(Model model){
Map<String,Object> map = model.asMap();
Map<String,Object> maps = model.asMap();
Set<String> ket = map.keySet();
Iterator<String> its = ket.iterator();
Map s = null;
while (its.hasNext()){
String k = its.next();
Object v = map.get(k);
if (k.equals("info")){
s = (Map) v;
}
}
return (String) s.get("id");
}
/ccc?u.id=1&b.id=9
@GetMapping("/ccc")
public String ccc(@ModelAttribute("u") User user,@ModelAttribute("b") Bian bian){
return user.toString()+">>"+bian.toString();
}
@ControllerAdvice
public class GlobalConfig {
@InitBinder("u")
public void init(WebDataBinder webDataBinder){
webDataBinder.setFieldDefaultPrefix("u.");
}
@InitBinder("b")
public void init2(WebDataBinder webDataBinder){
webDataBinder.setFieldDefaultPrefix("b.");
}
}
1.在 resources/static 下新建error
2. 自定义 error数据
@Component
public class MyErrorAttribute extends DefaultErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
Map<String,Object> errorAttr = super.getErrorAttributes(webRequest,options);
errorAttr.put("zdy","错误了");
errorAttr.remove("error");
return errorAttr;
}
}
@Component
public class MyErrorViewResolver implements ErrorViewResolver {
@Override
public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
ModelAndView mv = new ModelAndView("errorPage");
mv.addObject("zdy","错误了");
mv.addAllObjects(model);
return mv;
}
}
DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>errortitle>
head>
<body>
<div>
自定义视图
<div>timestamp: <span th:text="${timestamp}">span>div>
<div>status: <span th:text="${status}">span>div>
<div>error: <span th:text="${error}">span>div>
<div>messages: <span th:text="${#messages}">span>div>
<div>path: <span th:text="${path}">span>div>
<div>zdy: <span th:text="${zdy}">span>div>
div>
body>
html>
@Controller
public class MyErrorController extends BasicErrorController {
@Autowired
public MyErrorController(ErrorAttributes errorAttributes, ServerProperties serverProperties,List<ErrorViewResolver> errorViewResolvers) {
super(errorAttributes, serverProperties.getError(),errorViewResolvers);
}
@Override
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
HttpStatus status = getStatus(request);
Map<String,Object> model = getErrorAttributes(request,isIncludeStackTrace(request, MediaType.TEXT_HTML));
model.put("zdy","错误了???????");
ModelAndView modelAndView = new ModelAndView("errorPage",model,status);
return modelAndView;
}
@Override
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
Map<String,Object> body = getErrorAttributes(request,isIncludeStackTrace(request,MediaType.ALL));
body.put("zdy","错误了?????123123??");
HttpStatus status = getStatus(request);
return new ResponseEntity<>(body,status);
}
}
Controller 类加注解 @CrossOrigin
public class Hello {
public String sayHellos(String name){
return "hellos "+name;
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="com.Hello" id="hello">bean>
beans>
@Autowired
Hello hello;
@GetMapping("/beans")
public String beans(){
return hello.sayHellos("啊啊啊啊啊");
}
public class MyInterceptor1 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyInterceptor1---preHandle");
return true; // true 才会往下执行
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("MyInterceptor1---postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("MyInterceptor1---afterCompletion");
}
}
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor1())
.addPathPatterns("/**") // 拦截的路径
.excludePathPatterns("/hello"); // 排除路径
}
}
@Component
@Order(1) // 执行顺序
public class MyCommandLineRunner2 implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("MyCommandLineRunner2---"+ Arrays.toString(args));
}
}
@Component
@Order(2) // 执行顺序
public class MyCommandLineRunner1 implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("MyCommandLineRunner1---"+ Arrays.toString(args));
}
}
@Component
@Order(1)
public class MyApplicationRunner2 implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
List<String> nonOptionArgs = args.getNonOptionArgs();
System.out.println("2-nonOptionArgs"+nonOptionArgs);
Set<String> optionsNames = args.getOptionNames();
for (String optionsName : optionsNames){
System.out.println("2-key:"+optionsName+";value:"+args.getOptionValues(optionsName));
}
}
}
@Component
@Order(2)
public class MyApplicationRunner1 implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
List<String> nonOptionArgs = args.getNonOptionArgs();
System.out.println("1-nonOptionArgs"+nonOptionArgs);
Set<String> optionsNames = args.getOptionNames();
for (String optionsName : optionsNames){
System.out.println("1-key:"+optionsName+";value:"+args.getOptionValues(optionsName));
}
}
}
// 启动类上加注解
@ServletComponentScan
@WebServlet("/my")
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("name>>>>>"+req.getParameter("name"));
}
}
@WebFilter("/*")
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("MyFilter>>init");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("MyFilter>>doFilter");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
System.out.println("MyFilter>>destroy");
}
}
@WebListener
public class MyListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("MyListener>>>>>requestDestroyed");
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("MyListener>>>>>requestInitialized");
}
}
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/sun").setViewName("999"); // 第一个:路径 第二个:模板
}
}
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
999999
body>
html>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-aopartifactId>
dependency>
// service
@Service
public class UserService {
public List<User> users(User user){
List<User> users = new ArrayList<>();
users.add(user);
return users;
}
}
@Component
@Aspect
public class LogAspect {
@Pointcut("execution(* com.example.d1.service.*.*(..))")
public void pcl(){}
@Before(value = "pcl()")
public void before(JoinPoint jp){
String name = jp.getSignature().getName();
System.out.println(name+"方法执行开始");
}
@After(value = "pcl()")
public void after(JoinPoint jp){
String name = jp.getSignature().getName();
System.out.println(name+"方法执行结束");
}
@AfterReturning(value = "pcl()",returning = "result")
public void afterReturning(JoinPoint jp,Object result){
String name = jp.getSignature().getName();
System.out.println(name+"方法返回值为:"+result);
}
@AfterThrowing(value = "pcl()",throwing = "e")
public void afterThrowing(JoinPoint jp,Exception e){
String name = jp.getSignature().getName();
System.out.println(name+"方法抛异常为:"+e.getMessage());
}
@Around("pcl()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
return pjp.proceed();
}
}
@CrossOrigin
@RestController
public class UserController {
@Autowired
UserService userService;
@GetMapping("/ceshilog")
public List<User> getUserService() {
return userService.users(new User(1,"ceshi","9999"));
}
}
在 resources/static/ 添加 favicon.ico
启动类上添加注解 @EnableAutoConfiguration(exclude = {某个类.class})
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jdbcartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>1.1.10version>
dependency>
# 数据库配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql:///ssm
username: root
password: 521314
public class Ccc {
private int id;
private String name;
private String author;
// get,set...
}
@Repository
public class CccDao {
@Autowired
JdbcTemplate jdbcTemplate;
public int addCcc(Ccc ccc){
return jdbcTemplate.update("INSERT INTO ccc(name,author) VALUES (?,?)",ccc.getName(),ccc.getAuthor());
}
public int updateCcc(Ccc ccc){
return jdbcTemplate.update("UPDATE ccc SET name =?,author=? WHERE id=?",ccc.getName(),ccc.getAuthor(),ccc.getId());
}
public int delCcc(int id){
return jdbcTemplate.update("DELETE FROM ccc WHERE id=?",id);
}
public Ccc getIdCcc(int id){
return jdbcTemplate.queryForObject("select * from ccc book where id=?",new BeanPropertyRowMapper<>(Ccc.class),id);
}
public List<Ccc> getCcc(int id){
return jdbcTemplate.query("select * from ccc",new BeanPropertyRowMapper<>(Ccc.class));
}
}
@Service
public class CccService {
@Autowired
CccDao cccDao;
public int addCcc(Ccc ccc){
return cccDao.addCcc(ccc);
}
public int updateCcc(Ccc ccc){
return cccDao.updateCcc(ccc);
}
public int delCcc(int id){
return cccDao.delCcc(id);
}
public Ccc getIdCcc(int id){
return cccDao.getIdCcc(id);
}
public List<Ccc> getCcc(){
return cccDao.getCcc();
}
}
@Autowired
CccService cccService;
@GetMapping("/ceshi")
public String indexs(){
System.out.println("添加:::"+cccService.addCcc(new Ccc("哈哈哈","发发撒顶起")));
System.out.println("修改:::"+cccService.updateCcc(new Ccc(1,"11111","gasfasfafa")));
System.out.println("删除:::"+cccService.delCcc(1));
System.out.println("id:::"+cccService.getIdCcc(2));
System.out.println("List:::"+cccService.getCcc());
return "999";
}
spring:
datasource:
one:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql:///ssm
username: root
password: 521314
two:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql:///bk
username: root
password: 521314
// 根据配置生成两个数据源
@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties("spring.datasource.one")
DataSource dsOne(){
return DruidDataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties("spring.datasource.two")
DataSource dsTwo(){
return DruidDataSourceBuilder.create().build();
}
}
// 配置jdbcTemplate
@Configuration
public class JdbcTemplateConfig {
@Bean
JdbcTemplate jdbcTemplateOne(@Qualifier("dsOne")DataSource dataSource){
return new JdbcTemplate(dataSource);
}
@Bean
JdbcTemplate jdbcTemplateTwo(@Qualifier("dsTwo")DataSource dataSource){
return new JdbcTemplate(dataSource);
}
}
// Dao 注入JdbcTemplate 时切换
@Resource(name = "jdbcTemplateTwo")
JdbcTemplate jdbcTemplate;
类/表与上面一样
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>2.1.4version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>1.1.10version>
dependency>
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql:///ssm
username: root
password: 521314
mybatis:
mapper-locations: classpath:mapper/*.xml
@Mapper
public interface CccMapper {
int addCcc (Ccc ccc);
int updateCcc (Ccc ccc);
int delCcc (int id);
Ccc getIdCcc (int id);
List<Ccc> ListCcc ();
}
@Service
public class CccService {
@Autowired
CccMapper cccMapper;
public int addCcc(Ccc ccc){
return cccMapper.addCcc(ccc);
}
public int updateCcc(Ccc ccc){
return cccMapper.updateCcc(ccc);
}
public int delCcc(int id){
return cccMapper.delCcc(id);
}
public Ccc getIdCcc(int id){
return cccMapper.getIdCcc(id);
}
public List<Ccc> getCcc(){
return cccMapper.ListCcc();
}
}
@CrossOrigin
@RestController
public class CccController {
@Autowired
CccService cccService;
@GetMapping("/ceshilog")
public String cehsi() {
System.out.println("添加:::"+cccService.addCcc(new Ccc("哈哈哈","发发撒顶起")));
System.out.println("修改:::"+cccService.updateCcc(new Ccc(6,"11111","gasfasfafa")));
System.out.println("删除:::"+cccService.delCcc(2));
System.out.println("id:::"+cccService.getIdCcc(6));
System.out.println("List:::"+cccService.getCcc());
return "999";
}
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.d2.mapper.CccMapper">
<insert id="addCcc" parameterType="com.example.d2.Ccc">
insert into ccc(name,author) values (#{name},#{author})
insert>
<update id="updateCcc" parameterType="com.example.d2.Ccc">
UPDATE ccc SET name =#{name},author=#{author} WHERE id=#{id}
update>
<delete id="delCcc" parameterType="int">
DELETE FROM ccc WHERE id=#{id}
delete>
<select id="getIdCcc" parameterType="int" resultType="com.example.d2.Ccc">
select * from ccc where id=#{id}
select>
<select id="ListCcc" resultType="com.example.d2.Ccc">
select * from ccc
select>
mapper>
spring:
datasource:
one:
type: com.alibaba.druid.pool.DruidDataSource
jdbc-url: jdbc:mysql:///ssm
username: root
password: 521314
two:
type: com.alibaba.druid.pool.DruidDataSource
jdbc-url: jdbc:mysql:///bk
username: root
password: 521314
@Configuration
@MapperScan(basePackages = "com.example.d2.mapper", sqlSessionFactoryRef = "OneSqlSessionFactory")//basePackages:接口文件的包路径
public class OneDataSourceConfig {
@Bean(name = "OneDataSource")
// 表示这个数据源是默认数据源
@Primary//这个一定要加,如果两个数据源都没有@Primary会报错
@ConfigurationProperties(prefix = "spring.datasource.one")//我们配置文件中的前缀
public DataSource getOneDateSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "OneSqlSessionFactory")
@Primary
public SqlSessionFactory OneSqlSessionFactory(@Qualifier("OneDataSource") DataSource datasource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(datasource);
bean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources("classpath*:xml/mapper/CccMapper.xml"));
return bean.getObject();// 设置mybatis的xml所在位置
}
@Bean("OneSqlSessionTemplate")
// 表示这个数据源是默认数据源
@Primary
public SqlSessionTemplate OneSqlSessionTemplate(
@Qualifier("OneSqlSessionFactory") SqlSessionFactory sessionfactory) {
return new SqlSessionTemplate(sessionfactory);
}
}
@Configuration
@MapperScan(basePackages = "com.example.d2.mapperTwo", sqlSessionFactoryRef = "TwoSqlSessionFactory")
public class TwoDataSourceConfig {
@Bean(name = "TwoDataSource")
@ConfigurationProperties(prefix = "spring.datasource.two")
public DataSource getTwoDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "TwoSqlSessionFactory")
public SqlSessionFactory TwoSqlSessionFactory(@Qualifier("TwoDataSource") DataSource datasource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(datasource);
bean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources("classpath*:xml/mapper/CccMapper2.xml"));
return bean.getObject();// 设置mybatis的xml所在位置
}
@Bean("TwoSqlSessionTemplate")
public SqlSessionTemplate TwoSqlSessionTemplate(
@Qualifier("TwoSqlSessionFactory") SqlSessionFactory sessionfactory) {
return new SqlSessionTemplate(sessionfactory);
}
}
@Mapper
public interface CccMapper {
int addCcc (Ccc ccc);
int updateCcc (Ccc ccc);
int delCcc (int id);
Ccc getIdCcc (int id);
List<Ccc> ListCcc ();
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.d2.mapper.CccMapper">
<insert id="addCcc" parameterType="com.example.d2.Ccc">
insert into ccc(name,author) values (#{name},#{author})
</insert>
<update id="updateCcc" parameterType="com.example.d2.Ccc">
UPDATE ccc SET name =#{name},author=#{author} WHERE id=#{id}
</update>
<delete id="delCcc" parameterType="int">
DELETE FROM ccc WHERE id=#{id}
</delete>
<select id="getIdCcc" parameterType="int" resultType="com.example.d2.Ccc">
select * from ccc where id=#{id}
</select>
<select id="ListCcc" resultType="com.example.d2.Ccc">
select * from ccc
</select>
</mapper>
@Mapper
public interface CccMapper2 {
int addCcc (Ccc ccc);
int updateCcc (Ccc ccc);
int delCcc (int id);
Ccc getIdCcc (int id);
List<Ccc> ListCcc ();
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.d2.mapperTwo.CccMapper2">
<insert id="addCcc" parameterType="com.example.d2.Ccc">
insert into ccc(name,author) values (#{name},#{author})
</insert>
<update id="updateCcc" parameterType="com.example.d2.Ccc">
UPDATE ccc SET name =#{name},author=#{author} WHERE id=#{id}
</update>
<delete id="delCcc" parameterType="int">
DELETE FROM ccc WHERE id=#{id}
</delete>
<select id="getIdCcc" parameterType="int" resultType="com.example.d2.Ccc">
select * from ccc where id=#{id}
</select>
<select id="ListCcc" resultType="com.example.d2.Ccc">
select * from ccc
</select>
</mapper>
@Service
public class CccService {
// @Autowired
// CccMapper cccMapper; // one 这个位置的切换
@Autowired
CccMapper2 cccMapper; // two 这个位置的切换
public int addCcc(Ccc ccc){
return cccMapper.addCcc(ccc);
}
public int updateCcc(Ccc ccc){
return cccMapper.updateCcc(ccc);
}
public int delCcc(int id){
return cccMapper.delCcc(id);
}
public Ccc getIdCcc(int id){
return cccMapper.getIdCcc(id);
}
public List<Ccc> getCcc(){
return cccMapper.ListCcc();
}
}
@CrossOrigin
@RestController
public class CccController {
@Autowired
CccService cccService;
@GetMapping("/ceshilog")
public String cehsi() {
System.out.println("添加:::"+cccService.addCcc(new Ccc("哈哈哈","发发撒顶起")));
System.out.println("List:::"+cccService.getCcc());
return "999";
}
}
新建数据库 demo
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.10version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jpaartifactId>
<exclusions>
<exclusion>
<groupId>com.zaxxergroupId>
<artifactId>HikariCPartifactId>
exclusion>
exclusions>
dependency>
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/demo?serverTimezone=Asia/Shanghai&characterEncoding=utf-8
username: root
password: 521314
type: com.alibaba.druid.pool.DruidDataSource
jpa:
show-sql: true
database: mysql
hibernate:
ddl-auto: update
server:
port: 9090
//Book
@Entity(name = "s_book")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "book_name",nullable = false)
private String name;
@Transient // 生成数据库表时,不生成该字段
private String ooo;
// ...set,get
}
//BookDao
public interface BookDao extends JpaRepository<Book,Integer> {
List<Book> getBooksByNameContaining(String name);
@Query(value = "select * from s_book where id=(select max(id) from s_book)",nativeQuery = true)
Book getMaxIdBook();
@Query(value = "select * from s_book where id>:id",nativeQuery = true)
List<Book> getBookById(@Param("id") Integer id);
}
//BookService
@Service
public class BookService {
@Autowired
BookDao bookDao;
public Book getMaxIdBook(){
return bookDao.getMaxIdBook();
}
public List<Book> getBookById(Integer id){
return bookDao.getBookById(id);
}
}
//BookController
@CrossOrigin
@RestController
public class BookController {
@Autowired
BookService bookService;
@GetMapping("/")
public String index(){
System.out.println("getMaxIdBook:::"+bookService.getMaxIdBook());
System.out.println("getBookById:::"+bookService.getBookById(1));
return "99";
}
}
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
primary:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/demo?serverTimezone=Asia/Shanghai&characterEncoding=utf-8
username: root
password: 521314
secondary:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/bk?serverTimezone=Asia/Shanghai&characterEncoding=utf-8
username: root
password: 521314
jpa:
show-sql: true
database: mysql
hibernate:
ddl-auto: update
server:
port: 9090
//DataSourceConfig
/**
* 数据库配置
*/
@Configuration
public class DataSourceConfig {
@Primary
@Bean(value = "primaryDataSource")
@ConfigurationProperties("spring.datasource.primary") //标红为yml文件中数据源路径:primary
public DataSource dataSourceOne(){
return DruidDataSourceBuilder.create().build();
}
@Bean(value = "secondDataSource")
@ConfigurationProperties("spring.datasource.secondary")//标红为yml文件中数据源路径:secondary
public DataSource dataSourceTwo(){
return DruidDataSourceBuilder.create().build();
}
}
//PrimaryJpaConfig
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryPrimary",
transactionManagerRef = "transactionManagerPrimary",
basePackages = {"com.example.d3.one"}) //设置Repository所在位置
public class PrimaryJpaConfig {
@Autowired
private JpaProperties jpaProperties;
@Autowired
private HibernateProperties hibernateProperties;
@Autowired
@Qualifier("primaryDataSource")
private DataSource primaryDataSource;
@Primary
@Bean(name = "entityManagerPrimary")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
}
@Primary
@Bean(name = "entityManagerFactoryPrimary")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {
return builder
.dataSource(primaryDataSource)// 设置数据源
.properties(jpaProperties.getProperties())// 设置jpa配置
.properties(getVendorProperties())// 设置hibernate配置
.packages("com.example.d3.etwo") //设置实体类所在位置
.persistenceUnit("primaryPersistenceUnit")// 设置持久化单元名,用于@PersistenceContext注解获取EntityManager时指定数据源
.build();
}
private Map getVendorProperties() {
return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
}
@Primary
@Bean(name = "transactionManagerPrimary")
public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
}
}
//SecondJpaConfig
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactorySecond",
transactionManagerRef = "transactionManagerSecond",
basePackages = {"com.example.d3.two"}) //设置Repository所在位置
public class SecondJpaConfig {
@Autowired
private JpaProperties jpaProperties;
@Autowired
private HibernateProperties hibernateProperties;
@Autowired
@Qualifier("secondDataSource")
private DataSource secondDataSource;
@Bean(name = "secondEntityManager")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactorySecond(builder).getObject().createEntityManager();
}
@Bean(name = "entityManagerFactorySecond")
public LocalContainerEntityManagerFactoryBean entityManagerFactorySecond(EntityManagerFactoryBuilder builder) {
return builder
.dataSource(secondDataSource)
.properties(jpaProperties.getProperties())// 设置jpa配置
.properties(getVendorProperties())
.packages("com.example.d3.etwo") //设置实体类所在位置
.persistenceUnit("secondPersistenceUnit")
.build();
}
private Map getVendorProperties() {
return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
}
@Bean(name = "transactionManagerSecond")
public PlatformTransactionManager transactionManagerSecond(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactorySecond(builder).getObject());
}
}
//BookService
@Service
public class BookService {
@Autowired
BookDao bookDao; // 这个位置切换数据源
public Book getMaxIdBook(){
return bookDao.getMaxIdBook();
}
public List<Book> getBookById(Integer id){
return bookDao.getBookById(id);
}
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
<exclusions>
<exclusion>
<groupId>io.lettucegroupId>
<artifactId>lettuce-coreartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>redis.clientsgroupId>
<artifactId>jedisartifactId>
dependency>
spring:
redis:
# redis 库编号 0-15
database: 0
# ip
host: 192.168.75.129
# 端口号
port: 6379
# 密码
password: 123456
jedis:
pool:
# 最大连接数
max-active: 8
# 最大空闲连接数
max-idle: 8
# 最大阻塞等待时间 -1 表示没有限制
max-wait: -1ms
# 最小空闲连接数
min-idle: 0
public class Book implements Serializable {
private Integer id;
private String name;
private String ooo;
// get / set
}
@Autowired
RedisTemplate redisTemplate;
@Autowired
StringRedisTemplate stringRedisTemplate;
@GetMapping("/redis")
public String Redis(){
ValueOperations<String,String> opsl = stringRedisTemplate.opsForValue();
opsl.set("id","1");
System.out.println(opsl.get("id"));
ValueOperations ops2 = redisTemplate.opsForValue();
Book b = new Book();
b.setId(1);
b.setName("测名称");
b.setOoo("sadasdasd");
ops2.set("book",b);
Book bd = (Book) ops2.get("book");
System.out.println(bd);
return "99";
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-mongodbartifactId>
dependency>
spring:
data:
mongodb:
authentication-database: admin
database: admin
host: 192.168.75.129
port: 27017
username: guoguo
password: 123456
public class Book implements Serializable {
private Integer id;
private String name;
private String ooo;
// get / set
}
public interface BookMongoDB extends MongoRepository<Book,Integer> {
List<Book> findByNameContains(String name);
Book findByNameEquals(String name);
}
@Autowired
BookMongoDB mongoDB;
@GetMapping("/mongodb")
public String mongodb(){
List<Book> books = new ArrayList<>();
Book b1 = new Book();
b1.setOoo("000");
b1.setName("名称1");
b1.setId(1);
Book b2 = new Book();
b2.setOoo("22222");
b2.setName("名称2");
b2.setId(2);
books.add(b1);
books.add(b2);
mongoDB.insert(books);
System.out.println(mongoDB.findByNameContains("1"));
System.out.println(mongoDB.findByNameEquals("名称2"));
return "99";
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
<exclusions>
<exclusion>
<groupId>io.lettucegroupId>
<artifactId>lettuce-coreartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>redis.clientsgroupId>
<artifactId>jedisartifactId>
dependency>
<dependency>
<groupId>org.springframework.sessiongroupId>
<artifactId>spring-session-data-redisartifactId>
dependency>
spring:
redis:
# redis 库编号 0-15
database: 0
# ip
host: 192.168.75.129
# 端口号
port: 6379
# 密码
password: 123456
jedis:
pool:
# 最大连接数
max-active: 8
# 最大空闲连接数
max-idle: 8
# 最大阻塞等待时间 -1 表示没有限制
max-wait: -1ms
# 最小空闲连接数
min-idle: 0
server:
port: 9091
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400 * 30)
public class SessionConfig {
}
/**
* session共享测试controller
* 启动两个服务,端口为9090的服务设置session,端口为9091的服务来获取session,测试是否能够获取,实现session共享
*/
@RestController
@RequestMapping("/session")
public class SessionController {
@Value("${server.port}")
private Integer port;
@GetMapping("/set")
public String set(HttpSession session) {
session.setAttribute("username", "test");
return String.valueOf(port);
}
@GetMapping("/get")
public String get(HttpSession session) {
String username = (String) session.getAttribute("username");
return username + ":" + port;
}
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jpaartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-restartifactId>
dependency>
spring:
data:
rest:
# 每页查询记录数
default-page-size: 20
# 分页查询页码参数名
page-param-name: page
# 分页查询记录数参数名
limit-param-name: size
# 分页查询排序参数名
sort-param-name: sort
# 所有请求加上前缀
base-path: /api
# 添加成功是否返回添加内容
return-body-on-create: true
# 修改成功是否返回修改内容
return-body-on-update: true
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/bk?serverTimezone=Asia/Shanghai&characterEncoding=utf-8
username: root
password: 521314
jpa:
show-sql: true
database: mysql
hibernate:
ddl-auto: update
server:
port: 9090
@Entity(name = "s_book")
public class Book implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "book_name",nullable = false)
private String name;
@Transient // 生成数据库表时,不生成该字段
private String ooo;
// get set
}
public interface BookRepository extends JpaRepository<Book,Integer> {
}
get http://localhost:9090/books 查询全部
page=1 size=3 sort=id,desc 第二页 三条记录 id倒叙
get http://localhost:9090/books/1 根据id查询
post http://localhost:9090/books 新增
put http://localhost:9090/books 修改
delete http://localhost:9090/books/1 根据id删除
@CrossOrigin // cors
// 自定义路径
@RepositoryRestResource(path = "bs",collectionResourceRel = "bs",itemResourceRel = "b")//exported = true 暴露出来,false不暴露
public interface BookRepository extends JpaRepository<Book,Integer> {
//自定义查询方法
// http://localhost:9090/bs/search/name?name=a
@RestResource(path = "name",rel = "name",exported = true) //exported = true 暴露出来,false不暴露
List<Book> findByNameContaining(@Param("name")String name);
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<optional>trueoptional>
dependency>
# Idea 需要配置
# devtools 默认不会监听静态文件
# 按 ctrl + shift + alt + /
spring:
devtools:
restart:
# 是否关闭自动重启
enabled: false
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-cacheartifactId>
dependency>
<dependency>
<groupId>net.sf.ehcachegroupId>
<artifactId>ehcacheartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
<exclusions>
<exclusion>
<groupId>org.junit.vintagegroupId>
<artifactId>junit-vintage-engineartifactId>
exclusion>
exclusions>
dependency>
// Book
public class Book implements Serializable {
private Integer id;
private String name;
private String ooo;
private String uuu;
// get/set/tostring
}
// BookDao
@Repository
@CacheConfig(cacheNames = "book_cache") // 缓存名称
public class BookDao {
@Cacheable
public Book getBookById(Integer id){
System.out.println("getBookById");
Book b = new Book();
b.setId(id);
b.setName("999as十大");
b.setOoo("1232");
return b;
}
@CachePut(key = "#book.id")
public Book updateBookById(Book book){
System.out.println("updateBookById");
book.setOoo("oooooooooo");
return book;
}
@CacheEvict(key = "#id")
public void delBookById(Integer id){
System.out.println("delBookById");
}
}
// 启动类上添加
@EnableCaching // 开启缓存
spring:
cache:
ehcache:
config: classpath:ehcache.xml # 重命名缓存配置文件位置
<ehcache>
<diskStore path="java.io.tmpdir/cache"/>
<defaultCache
eternal="false"
maxElementsInMemory="10000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"/>
<cache
name="book_cache"
eternal="true"
maxElementsInMemory="10000"
overflowToDisk="true"
diskPersistent="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="600"/>
ehcache>
@Autowired
BookDao bookDao;
@Test
void contextLoads() {
bookDao.getBookById(1);
bookDao.getBookById(1);
bookDao.delBookById(1);
Book b3 = bookDao.getBookById(1);
System.out.println("b3:"+b3);
Book b = new Book();
b.setOoo("5555");
b.setName("123");
b.setId(1);
bookDao.updateBookById(b);
Book b4 = bookDao.getBookById(1);
System.out.println("b4--"+b4);
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-cacheartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
<exclusions>
<exclusion>
<groupId>io.lettucegroupId>
<artifactId>lettuce-coreartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>redis.clientsgroupId>
<artifactId>jedisartifactId>
dependency>
spring:
cache:
cache-names: book_cache
redis:
time-to-live: 1800s
redis:
database: 0
host: 127.0.0.1
port: 6379
password:
jedis:
pool:
max-active: 8
max-idle: 8
max-wait: -1ms
min-idle: 0
启动类注解 @EnableCaching,Book,BookDao同上
@Autowired
BookDao bookDao;
@Test
void contextLoads() {
bookDao.getBookById(1);
bookDao.getBookById(1);
bookDao.delBookById(1);
Book b3 = bookDao.getBookById(1);
System.out.println("b3:" + b3);
Book b = new Book();
b.setOoo("5789");
b.setName("9999");
b.setId(1);
bookDao.updateBookById(b);
Book b4 = bookDao.getBookById(1);
System.out.println("b4--" + b4);
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-securityartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
spring:
security:
user:
name: admin
password: 123
roles: admin
@Test
void reg() {
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(10);
String encodePasswod = encoder.encode("123");
System.out.println(encodePasswod);
}
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
PasswordEncoder passwordEncoder(){
// return NoOpPasswordEncoder.getInstance(); // 明文
return new BCryptPasswordEncoder(10);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
auth.inMemoryAuthentication()
.withUser("root").password("$2a$10$13wlsj3mVvgRkyaM9iUvDu7hecAMPMQkuKD7kGiZ/g3sVp8T3l2MC").roles("ADMIN","DBA")
.and()
.withUser("admin").password("$2a$10$13wlsj3mVvgRkyaM9iUvDu7hecAMPMQkuKD7kGiZ/g3sVp8T3l2MC").roles("ADMIN","USER")
.and()
.withUser("sun").password("$2a$10$13wlsj3mVvgRkyaM9iUvDu7hecAMPMQkuKD7kGiZ/g3sVp8T3l2MC").roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**")
.hasRole("ADMIN")
.antMatchers("/user/**")
.access("hasAnyRole('ADMIN','USER')")
.antMatchers("/db/**")
.access("hasRole('ADMIN') and hasRole('DBA')")
.anyRequest()
.authenticated()
.and()
.logout()
.logoutUrl("logout")
.clearAuthentication(true)
.invalidateHttpSession(true)
.addLogoutHandler(new LogoutHandler() {
@Override
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
}
})
.logoutSuccessHandler(new LogoutSuccessHandler() {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
response.sendRedirect("/login_page");
}
})
.and()
.formLogin()
.loginPage("/login_page")
.loginProcessingUrl("/login")
.usernameParameter("name")
.passwordParameter("passwd")
.successHandler(new AuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
Object principal = authentication.getPrincipal();
response.setContentType("application/json;charset=utf-8");
PrintWriter out = response.getWriter();
response.setStatus(200);
Map<String,Object> map = new HashMap<>();
map.put("status",200);
map.put("msg",principal);
ObjectMapper om = new ObjectMapper();
out.write(om.writeValueAsString(map));
out.flush();
out.close();
}
})
.failureHandler(new AuthenticationFailureHandler(){
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
response.setContentType("application/json;charset=utf-8");
PrintWriter out = response.getWriter();
response.setStatus(401);
Map<String,Object> map = new HashMap<>();
map.put("status",401);
if(exception instanceof LockedException){
map.put("msg","账号被锁定,登录失败");
}else if(exception instanceof BadCredentialsException){
map.put("msg","账号名称或密码输入错误");
}else if(exception instanceof DisabledException){
map.put("msg","账号被禁用");
}else if(exception instanceof AccountExpiredException){
map.put("msg","账号已过期");
}else if(exception instanceof CredentialsExpiredException){
map.put("msg","密码已过期");
}else{
map.put("msg","登录失败");
}
ObjectMapper om = new ObjectMapper();
out.write(om.writeValueAsString(map));
out.flush();
out.close();
}
})
.permitAll()
.and()
.csrf()
.disable();
}
}
@RestController
@CrossOrigin
public class HelloController {
// @GetMapping("/admin")
// @Secured("ROLE_ADMIN")
// public String a(){
// return "admin角色注解99十大";
// }
// @GetMapping("/a1")
// @PreAuthorize("hasAnyRole('ADMIN','DBA','USER')")
// public String a1(){
// return "'ADMIN','DBA','USER'";
// }
// @GetMapping("/a2")
// @PreAuthorize("hasRole('ADMIN') and hasRole('DBA')")
// public String a2(){
// return "ADMIN 和 DBA";
// }
@GetMapping("/hello")
public String hello(){
return "999十大";
}
@GetMapping("/admin/hello")
public String admin(){
return "admin";
}
@GetMapping("/user/hello")
public String user(){
return "user";
}
@GetMapping("/db/hello")
public String dba(){
return "db";
}
}
gitee
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-websocketartifactId>
dependency>
@Configuration
public class WebSocketConfiguration {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
@Component
@Slf4j
@ServerEndpoint("/websocket/{userId}")
public class WebSocket {
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
/**
* 用户ID
*/
private String userId;
//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
//虽然@Component默认是单例模式的,但springboot还是会为每个websocket连接初始化一个bean,所以可以用一个静态set保存起来。
private static CopyOnWriteArraySet<WebSocket> webSockets =new CopyOnWriteArraySet<>();
// 用来存在线连接用户信息
private static ConcurrentHashMap<String,Session> sessionPool = new ConcurrentHashMap<String,Session>();
/**
* 链接成功调用的方法
*/
@OnOpen
public void onOpen(Session session, @PathParam(value="userId")String userId) {
try {
this.session = session;
this.userId = userId;
webSockets.add(this);
sessionPool.put(userId, session);
log.info("【websocket消息】有新的连接,总数为:"+webSockets.size());
} catch (Exception e) {
}
}
/**
* 链接关闭调用的方法
*/
@OnClose
public void onClose() {
try {
webSockets.remove(this);
sessionPool.remove(this.userId);
log.info("【websocket消息】连接断开,总数为:"+webSockets.size());
} catch (Exception e) {
}
}
/**
* 收到客户端消息后调用的方法
*/
@OnMessage
public void onMessage(String message) {
log.info("【websocket消息】收到客户端消息:"+message);
// sendAllMessage("此为广播消息:"+message);
sendOneMessage(this.userId,"此为单点消息:"+message);
// sendMoreMessage("此为单点消息(多人):"+message);
}
/** 发送错误时的处理
*/
@OnError
public void onError(Session session, Throwable error) {
log.error("用户错误,原因:"+error.getMessage());
error.printStackTrace();
}
// 此为广播消息
public void sendAllMessage(String message) {
log.info("【websocket消息】广播消息:"+message);
for(WebSocket webSocket : webSockets) {
try {
if(webSocket.session.isOpen()) {
webSocket.session.getAsyncRemote().sendText(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 此为单点消息
public void sendOneMessage(String userId, String message) {
Session session = sessionPool.get(userId);
if (session != null&&session.isOpen()) {
try {
log.info("【websocket消息】 单点消息:"+message);
session.getAsyncRemote().sendText(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 此为单点消息(多人)
public void sendMoreMessage(String message) {
for(WebSocket webSocket:webSockets) {
Session session = webSocket.session;
if (session != null&&session.isOpen()) {
try {
log.info("【websocket消息】 单点消息:"+message);
session.getAsyncRemote().sendText(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-activemqartifactId>
dependency>
@Bean
Queue queue(){
return new ActiveMQQueue("amq");
}
@Component
public class JmsComponent {
@Resource
JmsMessagingTemplate messagingTemplate;
@Resource
Queue queue;
public void send(Message msg){
messagingTemplate.convertAndSend(this.queue,msg);
}
@JmsListener(destination = "amq")
public void receive(Message msg){
System.out.println("re:"+msg);
}
}
class Message implements Serializable{
private String content;
private Date date;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
@Override
public String toString() {
return "Message{" +
"content='" + content + '\'' +
", date=" + date +
'}';
}
}
@Resource
JmsComponent jmsComponent;
@Test
void contextLoads() {
Message msg = new Message();
msg.setContent("hello jms");
msg.setDate(new Date());
jmsComponent.send(msg);
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-amqpartifactId>
dependency>
spring:
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
@Configuration
public class RabbitmqConfig {
public static final String QUEUE_ONE = "queue_inform_one";
public static final String QUEUE_TWO = "queue_inform_two";
public static final String EXCHANGE_TOPICS_INFORM="exchange_topics_inform";
public static final String ROUTINGKEY_ONE="inform.#.one.#";
public static final String ROUTINGKEY_TWO="inform.#.two.#";
//声明交换机
@Bean(EXCHANGE_TOPICS_INFORM)
public Exchange EXCHANGE_TOPICS_INFORM(){
//durable(true) 持久化,mq重启之后交换机还在
return ExchangeBuilder.topicExchange(EXCHANGE_TOPICS_INFORM).durable(true).build();
}
//声明 one 队列
@Bean(QUEUE_ONE)
public Queue QUEUE_INFORM_EMAIL(){
return new Queue(QUEUE_ONE);
}
//声明 two 队列
@Bean(QUEUE_TWO)
public Queue QUEUE_INFORM_SMS(){
return new Queue(QUEUE_TWO);
}
//ROUTINGKEY_ONE队列绑定交换机,指定routingKey
@Bean
public Binding BINDING_QUEUE_INFORM_EMAIL(@Qualifier(QUEUE_ONE) Queue queue,
@Qualifier(EXCHANGE_TOPICS_INFORM) Exchange exchange){
return BindingBuilder.bind(queue).to(exchange).with(ROUTINGKEY_ONE).noargs();
}
//ROUTINGKEY_TWO队列绑定交换机,指定routingKey
@Bean
public Binding BINDING_ROUTINGKEY_SMS(@Qualifier(QUEUE_TWO) Queue queue,
@Qualifier(EXCHANGE_TOPICS_INFORM) Exchange exchange){
return BindingBuilder.bind(queue).to(exchange).with(ROUTINGKEY_TWO).noargs();
}
}
@Component
public class ReceiveHandler {
//监听 one 队列
@RabbitListener(queues = {RabbitmqConfig.QUEUE_ONE})
public void receive_email(Object msg, Message message, Channel channel){
System.out.println("one"+msg);
}
//监听 two 队列
@RabbitListener(queues = {RabbitmqConfig.QUEUE_TWO})
public void receive_sms(Object msg, Message message, Channel channel){
System.out.println("two"+msg);
}
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-mailartifactId>
dependency>
spring:
mail:
host: smtp.qq.com
username: ***@qq.com # 邮箱
password: *** # 授权码
port: 465
protocol: smtp
default-encoding: utf-8
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
ssl:
enable: true
socketFactory:
port: 465
class: javax.net.ssl.SSLSocketFactory
@Component
public class MailService {
@Resource
JavaMailSender javaMailSender;
/**
* 普通邮件
*
* @param from 发送人邮箱
* @param to 接收人邮箱
* @param cc 抄送人邮箱
* @param subject 邮箱主题
* @param content 邮箱内容
*/
public void sendSimpleMail(String from, String to, String cc, String subject, String content) {
MimeMessage message = mimeMessage();
mimeMessageHelper(from, to, cc, subject, content,message);
javaMailSender.send(message);
}
/**
* 附件邮件
*
* @param from 发送人邮箱
* @param to 接收人邮箱
* @param cc 抄送人邮箱
* @param subject 邮箱主题
* @param content 邮箱内容
* @param file 邮箱附件
*/
public void sendAttachFileMail(String from, String to, String cc, String subject, String content, File file) {
try {
MimeMessage message = mimeMessage();
MimeMessageHelper helper = mimeMessageHelper(from, to, cc, subject, content,message);
helper.addAttachment(file.getName(), file);
javaMailSender.send(message);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 图片邮件
*
* @param from 发送人邮箱
* @param to 接收人邮箱
* @param cc 抄送人邮箱
* @param subject 邮箱主题
* @param content 邮箱内容
* @param srcPath 图片路径
* @param resIds 图片 ID
*/
public void sendMailImg(String from, String to, String cc, String subject, String content, String[] srcPath, String[] resIds) {
if (srcPath.length != resIds.length) {
System.out.println("发送失败");
return;
}
try {
MimeMessage message = mimeMessage();
MimeMessageHelper helper = mimeMessageHelper(from, to, cc, subject, content,message);
for (int i = 0; i < srcPath.length; i++) {
FileSystemResource res = new FileSystemResource(new File(srcPath[i]));
helper.addInline(resIds[i], res);
}
javaMailSender.send(message);
} catch (Exception e) {
e.printStackTrace();
}
}
private MimeMessage mimeMessage() {
return javaMailSender.createMimeMessage();
}
private MimeMessageHelper mimeMessageHelper(String from, String to, String cc, String subject, String content,MimeMessage message) {
try {
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
helper.setBcc(cc);
helper.setSubject(subject);
helper.setText(content, true);
return helper;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
@Resource
MailService mailService;
@Test
void contextLoads() { mailService.sendSimpleMail("***@qq.com","***@qq.com","***@qq.com","主题9999","内容运行阿三大苏打");
mailService.sendAttachFileMail("***@qq.com","***@qq.com","***@qq.com","主题99991","查看附件",new File("D:\\README.txt"));
mailService.sendMailImg("***@qq.com","***@qq.com","***@qq.com","主题图片","",new String[]{"D:\\1.png","D:\\2.png"},new String[]{"p01","p02"});
}
// 启动类
@EnableScheduling // 开启
@Component
public class MyScheduling {
// fixedDelay=1000 当前任务执行结束 1s 后开启另一个任务
// fixedRate=2000 当前任务开始执行 2s 后开启另一个任务
// initialDelay 首次执行延迟时间
// cron=* * * * * ? 每秒执行一次
@Scheduled(fixedDelay = 1000)
public void test1(){
System.out.println("test1:"+new Date());
}
@Scheduled(fixedRate = 2000)
public void test2(){
System.out.println("test2:"+new Date());
}
@Scheduled(fixedRate = 2000,initialDelay = 1000)
public void test3(){
System.out.println("test3:"+new Date());
}
@Scheduled(cron = "* * * * * ?")
public void test4(){
System.out.println("cron表达式:"+new Date());
}
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-quartzartifactId>
dependency>
spring:
quartz:
job-store-type: memory # Job 存储器类型。默认为 memory 表示内存,可选 jdbc 使用数据库。
auto-startup: true # Quartz 是否自动启动
startup-delay: 0 # 延迟 N 秒启动
wait-for-jobs-to-complete-on-shutdown: true # 应用关闭时,是否等待定时任务执行完成。默认为 false ,建议设置为 true
overwrite-existing-jobs: false # 是否覆盖已有 Job 的配置
properties: # 添加 Quartz Scheduler 附加属性
org:
quartz:
threadPool:
threadCount: 25 # 线程池大小。默认为 10 。
threadPriority: 5 # 线程优先级
class: org.quartz.simpl.SimpleThreadPool # 线程池类型
@Slf4j
public class FirstJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
String now = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now());
log.info("当前的时间: " + now);
}
}
@Slf4j
public class SecondJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
String now = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now());
log.info("SecondJob执行, 当前的时间: " + now);
}
}
@Configuration // 自动
public class QuartzConfig {
private static final String ID = "SUN";
@Bean
public JobDetail jobDetail1() {
return JobBuilder.newJob(FirstJob.class)
.withIdentity(ID + " 01")
.storeDurably()
.build();
}
@Bean
public Trigger trigger1() {
// 简单的调度计划的构造器
SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(5) // 频率
.repeatForever(); // 次数
return TriggerBuilder.newTrigger()
.forJob(jobDetail1())
.withIdentity(ID + " 01Trigger")
.withSchedule(scheduleBuilder)
.build();
}
}
@Component // 手动
public class JobInit implements ApplicationRunner {
private static final String ID = "SUN";
@Resource
private Scheduler scheduler;
@Override
public void run(ApplicationArguments args) throws Exception {
JobDetail jobDetail = JobBuilder.newJob(FirstJob.class)
.withIdentity(ID + " 01")
.storeDurably()
.build();
CronScheduleBuilder scheduleBuilder =
CronScheduleBuilder.cronSchedule("0/5 * * * * ? *");
// 创建任务触发器
Trigger trigger = TriggerBuilder.newTrigger()
.forJob(jobDetail)
.withIdentity(ID + " 01Trigger")
.withSchedule(scheduleBuilder)
.startNow() //立即執行一次任務
.build();
// 手动将触发器与任务绑定到调度器内
scheduler.scheduleJob(jobDetail, trigger);
}
}
<dependency>
<groupId>com.github.xiaoymingroupId>
<artifactId>knife4j-spring-boot-starterartifactId>
<version>3.0.3version>
dependency>
spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
knife4j:
enable: true
basic:
enable: true
username: sun
password: 123
@Configuration
@EnableSwagger2
public class Knife4jConfiguration {
@Bean(value = "defaultApi2")
public Docket defaultApi2() {
String groupName = "1.X版本";
Docket docket = new Docket(DocumentationType.OAS_30)
.apiInfo(new ApiInfoBuilder()
.title("999999999")
.description("文档")
.termsOfServiceUrl("https://gitee.com/sunlei0718")
.contact(new Contact("sunlei0718", "https://gitee.com/sunlei0718", "[email protected]"))
.version("1.0")
.build())
.securitySchemes(Collections.singletonList(HttpAuthenticationScheme.JWT_BEARER_BUILDER
.name("Authorization")//页面展示字段
.build()))
.securityContexts(Collections.singletonList(SecurityContext.builder()
.securityReferences(Collections.singletonList(SecurityReference.builder()
.scopes(new AuthorizationScope[0])
.reference("Authorization")
.build()))
.operationSelector(o -> o.requestMappingPattern().matches("/.*"))// 声明作用域
.build()))
//分组名称
.groupName(groupName)
.select()
//这里指定Controller扫描包路径
.apis(RequestHandlerSelectors.basePackage("com.example.demowebsocket.controller"))
.paths(PathSelectors.any())
.build();
return docket;
}
}
@Data
@ToString
@ApiModel(value = "测试",description = "描述")
public class Ceshi {
@ApiModelProperty(value = "id")
private Integer id;
@ApiModelProperty(value = "用户名称")
private String name;
@ApiModelProperty(value = "密码")
private String pass;
}
@RestController
@CrossOrigin
@Api(tags = "测试接口999")
public class ccccontroller {
@GetMapping("/get")
@ApiOperation(value = "get查询",notes = "备注")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "query",name="id",value="ID",required = true,defaultValue = "1")
})
public String get(@RequestParam Integer id){
return "99"+id;
}
@GetMapping("/cget")
@ApiIgnore
public String cget(@RequestParam Integer id){
return "99"+id;
}
@PostMapping("/p")
@ApiOperationSupport(ignoreParameters = {"id"})
@ApiOperation(value = "post新增",notes = "备注")
public String p(@RequestBody Ceshi id){
return "99"+id;
}
@PutMapping("/put")
@ApiOperation(value = "修改",notes = "备注")
public String pd(@RequestBody Ceshi id){
return "99"+id;
}
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-validationartifactId>
dependency>
public interface StatusCode {
public int getCode();
public String getMsg();
}
public enum ResultCode implements StatusCode{
SUCCESS(1000, "请求成功"),
FAILED(1001, "请求失败"),
VALIDATE_ERROR(1002, "参数校验失败"),
RESPONSE_PACK_ERROR(1003, "response返回包装失败");
private int code;
private String msg;
ResultCode(int code, String msg) {
this.code = code;
this.msg = msg;
}
@Override
public int getCode() {
return this.code;
}
@Override
public String getMsg() {
return this.msg;
}
}
@Data
public class ResultVo {
// 状态码
private int code;
// 状态信息
private String msg;
// 返回对象
private Object data;
// 手动设置返回vo
public ResultVo(int code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}
// 默认返回成功状态码,数据对象
public ResultVo(Object data) {
this.code = ResultCode.SUCCESS.getCode();
this.msg = ResultCode.SUCCESS.getMsg();
this.data = data;
}
// 返回指定状态码,数据对象
public ResultVo(StatusCode statusCode, Object data) {
this.code = statusCode.getCode();
this.msg = statusCode.getMsg();
this.data = data;
}
// 只返回状态码
public ResultVo(StatusCode statusCode) {
this.code = statusCode.getCode();
this.msg = statusCode.getMsg();
this.data = null;
}
}
@Data
public class User{
@NotNull(message = "用户id不能为空")
private Long id;
@NotNull(message = "用户账号不能为空")
@Size(min = 6, max = 11, message = "账号长度必须是6-11个字符")
private String account;
@NotNull(message = "用户密码不能为空")
@Size(min = 6, max = 11, message = "密码长度必须是6-16个字符")
private String password;
@NotNull(message = "用户邮箱不能为空")
@Email(message = "邮箱格式不正确")
private String email;
}
@RestController
@Validated
public class ValidController {
@PostMapping("/findByVo")
public ResultVo findByVo(@Valid @RequestBody User vo) {
return new ResultVo("999");
}
@PostMapping("/findByVo1")
public ResultVo findByVo1(@Validated User vo, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
List<String> ls = new ArrayList();
List<ObjectError> list = bindingResult.getAllErrors();
for (ObjectError o : list) {
ls.add(o.getDefaultMessage());
}
return new ResultVo(ls);
}
return new ResultVo("999");
}
@GetMapping("/findByVo12")
public ResultVo findByVo12(@NotNull(message="id不能为空") Integer id) {
return new ResultVo("999");
}
}
@ControllerAdvice
@ResponseBody
public class GlobleExceptionHandler {
/**
* 处理 json 请求体调用接口对象参数校验失败抛出的异常
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResultVo jsonParamsException(MethodArgumentNotValidException e) {
BindingResult bindingResult = e.getBindingResult();
List errorList = new ArrayList();
for (FieldError fieldError : bindingResult.getFieldErrors()) {
String msg = String.format("%s%s;", fieldError.getField(), fieldError.getDefaultMessage());
errorList.add(msg);
}
return new ResultVo(errorList);
}
/**
* 处理单个参数校验失败抛出的异常
*/
@ExceptionHandler(ConstraintViolationException.class)
public ResultVo ParamsException(ConstraintViolationException e) {
List errorList = new ArrayList();
Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
for (ConstraintViolation<?> violation : violations) {
errorList.add(violation.getMessageTemplate());
}
return new ResultVo(errorList);
}
/**
* handlerMapping 接口不存在跑出异常
*
* @param e
* @return
*/
@ExceptionHandler(NoHandlerFoundException.class)
public ResultVo noHandlerFoundException(NoHandlerFoundException e) {
return new ResultVo(e.getMessage());
}
/**
*
* @param e 未知异常捕获
* @return
*/
@ExceptionHandler(Exception.class)
public ResultVo UnNoException(Exception e) {
return new ResultVo(e.getMessage());
}
}
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.2.41version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-aopartifactId>
dependency>
@Data
@ToString
public class WebLog { // 操作日志
/**
* 描述信息
*/
private String description;
/**
* URL
*/
private String URL;
/**
* 请求方式
*/
private String manner;
/**
* 请求方法
*/
private String method;
/**
* IP
*/
private String IP;
/**
* 请求参数
*/
private String req;
/**
* 响应参数
*/
private String res;
/**
* userID 操作人 id
*/
private Integer userid;
}
@Data
@ToString
public class User {
private Integer id;
private String user;
private String name;
}
@Data
public class ResultVo<T> {
private Integer code;
private String msg;
private T data;
public ResultVo(T data){
this.code = 200;
this.msg = "成功";
this.data = data;
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface LogPrint {
String description() default "";
}
@Aspect
@Component
@Slf4j
public class LogPrintAspect {
private static final String LINE_SEPARATOR = System.lineSeparator();
// @Pointcut("@annotation(com.example.demoaop.LogPrint)")
// //@Pointcut("execution(* com.example.demoaop.controller.*.*(..))")
// public void logPrint() {
// }
/**
* 请求完成后执行
*/
@AfterReturning(pointcut = "@annotation(com.example.demoaop.LogPrint)",returning = "jsonResult")
public void doAfterReturnibng(JoinPoint joinPoint, Object jsonResult) throws Throwable {
log.info("=========================================== 执行操作日志 ===========================================");
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String methodDescription = getAspectLogDescription(joinPoint);
// 打印请求 url
log.info("URL : {}", request.getRequestURL().toString());
// 打印描述信息
log.info("描述信息 : {}", methodDescription);
// 打印 Http method
log.info("请求方式 : {}", request.getMethod());
// 打印调用 controller 的全路径以及执行方法
log.info("执行方法 : {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
// 打印请求的 IP
log.info("IP : {}", request.getRemoteAddr());
// 打印请求入参
log.info("请求参数 : {}", getParams(joinPoint));
log.info("请求返回 : {}", JSON.toJSONString(jsonResult));
log.info("=========================================== 结束操作日志 ===========================================");
}
/**
* 在切点之前
* @param joinPoint
* @throws Throwable
*/
// @Before("logPrint()")
// public void doBefore(JoinPoint joinPoint) throws Throwable {
// log.info("=========================================== 进入请求 ===========================================");
// ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
// HttpServletRequest request = attributes.getRequest();
// String methodDescription = getAspectLogDescription(joinPoint);
// // 打印请求 url
// log.info("URL : {}", request.getRequestURL().toString());
// // 打印描述信息
// log.info("描述信息 : {}", methodDescription);
// // 打印 Http method
// log.info("请求方式 : {}", request.getMethod());
// // 打印调用 controller 的全路径以及执行方法
// log.info("执行方法 : {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
// // 打印请求的 IP
// log.info("IP : {}", request.getRemoteAddr());
// // 打印请求入参
// log.info("请求参数 : {}", getParams(joinPoint));
// }
/**
* 在切点之后
*/
// @After("logPrint()")
// public void doAfter() throws Throwable {
// // 接口结束后换行,方便分割查看
// log.info("=========================================== 请求完成 ===========================================" + LINE_SEPARATOR);
// }
/**
* 环绕
*/
// @Around("logPrint()")
// public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
// long startTime = System.currentTimeMillis();
// Object result = proceedingJoinPoint.proceed();
// // 打印出参
// log.info("返回参数 : {}", JSONObject.toJSONString(result));
// // 执行耗时
// log.info("响应时间 : {} ms", System.currentTimeMillis() - startTime);
// return result;
// }
public String getAspectLogDescription(JoinPoint joinPoint)
throws Exception {
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
StringBuilder description = new StringBuilder("");
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class[] clazzs = method.getParameterTypes();
if (clazzs.length == arguments.length) {
description.append(method.getAnnotation(LogPrint.class).description());
break;
}
}
}
return description.toString();
}
private String getParams(JoinPoint joinPoint) {
String params = "";
if (joinPoint.getArgs() != null && joinPoint.getArgs().length > 0) {
for (int i = 0; i < joinPoint.getArgs().length; i++) {
Object arg = joinPoint.getArgs()[i];
if ((arg instanceof HttpServletResponse) || (arg instanceof HttpServletRequest)
|| (arg instanceof MultipartFile) || (arg instanceof MultipartFile[])) {
continue;
}
try {
params += JSONObject.toJSONString(joinPoint.getArgs()[i]);
} catch (Exception e1) {
log.error(e1.getMessage());
}
}
}
return params;
}
}
@RestController
@CrossOrigin
public class asdasd {
@GetMapping("/cgg")
public String gg(){
return "99:";
}
@PostMapping("/findByVo")
@LogPrint(description = "测试json验证")
public ResultVo findByVo(@RequestBody User vo) {
return new ResultVo("999");
}
@PostMapping("/findByVo1")
@LogPrint(description = "测试form验证")
public ResultVo findByVo1(User vo) {
return new ResultVo("999");
}
@GetMapping("/findByVo12")
@LogPrint(description = "测试单个验证")
public ResultVo findByVo12(Integer id) {
return new ResultVo("999");
}
}