1 背景
基于java+springboot快速大家一个网站,简单时间登陆 访问。
相比于之间的springMVC,idea提供了快速搭建demo,基于springboot搭建已变得简单
2 项目架构
3 配置文件
3.1 pom.xml配置文件
<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.gaocl.demo</groupId><artifactId>SpringBoot-lastest</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.6</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.0</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.7.6</version></plugin></plugins></build><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties></project>
3.2 application.yml配置文件
spring thymeleaf cachefalse datasource url jdbc mysql //localhost 3306/test username root password123456server port8888
4 后端代码
4.1 实例类
packageorg.gaocl.demo.Entity; importlombok.Data; publicclassMyUser { privateIntegerid; privateStringusername; privateStringpassword; }
4.2 Dao层
packageorg.gaocl.demo.dao; importorg.apache.ibatis.annotations.Insert; importorg.apache.ibatis.annotations.Mapper; importorg.apache.ibatis.annotations.Select; importorg.gaocl.demo.Entity.MyUser; importjava.util.List; publicinterfaceUserDao { "select * from t_user") (publicList<MyUser>findAll(); "select * from t_user where username=#{username}") (publicMyUserfindByName(Stringusername); "insert into t_user (username, password) values(#{username}, #{password})") (publicintsave(MyUseruser); }
4.3 service层
packageorg.gaocl.demo.service; importlombok.extern.slf4j.Slf4j; importorg.gaocl.demo.Entity.MyUser; importorg.gaocl.demo.dao.UserDao; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.security.core.userdetails.User; importorg.springframework.security.core.userdetails.UserDetails; importorg.springframework.security.core.userdetails.UserDetailsService; importorg.springframework.security.core.userdetails.UsernameNotFoundException; importorg.springframework.security.crypto.password.PasswordEncoder; importorg.springframework.stereotype.Service; publicclassUserServiceimplementsUserDetailsService { privateUserDaouserDao; privatePasswordEncoderpasswordEncoder; publicintsave(MyUseruser){ user.setPassword(passwordEncoder.encode(user.getPassword())); returnuserDao.save(user); } publicUserDetailsloadUserByUsername(Stringusername) throwsUsernameNotFoundException { MyUsermyUser=userDao.findByName(username); // log.info(myUser.toString());if(myUser==null){ thrownewUsernameNotFoundException("用户名不存在"); } returnUser.builder() .username(myUser.getUsername()) .password(myUser.getPassword()) .roles("USER", "ADMIN") //roles(Arrays.asList("").toArray(new String[]{})) .build(); } }
4.4 controller层
packageorg.gaocl.demo.controller; importorg.gaocl.demo.Entity.MyUser; importorg.gaocl.demo.service.UserService; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.security.core.GrantedAuthority; importorg.springframework.security.core.context.SecurityContextHolder; importorg.springframework.security.core.userdetails.UserDetails; importorg.springframework.stereotype.Controller; importorg.springframework.web.bind.annotation.GetMapping; importorg.springframework.web.bind.annotation.PostMapping; importorg.springframework.web.bind.annotation.ResponseBody; importjava.util.Collection; importjava.util.List; publicclassUserController { privateUserServiceuserService; "/login") (publicStringlogin(){ return"login"; } "/index") (publicStringindex(){ return"index"; } "/logout") (publicStringlogout(){ return"login"; } "/sign") (publicStringsign(){ return"resign"; } "/resign") (publicStringresign(MyUseruser){ userService.save(user); return"redirect:/login"; } "/tree") (publicCollection<?extendsGrantedAuthority>permissionTree() { UserDetailsuserDetails= (UserDetails) SecurityContextHolder.getContext() .getAuthentication() .getPrincipal(); returnuserDetails.getAuthorities(); } }
4.5 security配置
(不用spring security可以忽略)
4.5.1 SecurityConfig
packageorg.gaocl.demo.config; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.context.annotation.Bean; importorg.springframework.context.annotation.Configuration; importorg.springframework.security.config.annotation.web.builders.HttpSecurity; importorg.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; importorg.springframework.security.crypto.password.PasswordEncoder; importorg.springframework.security.web.SecurityFilterChain; publicclassSecurityConfig { privatePasswordEncoderpasswordEncoder; publicSecurityFilterChainfilterChain(HttpSecuritysecurity) throwsException { //给请求加所有权限//form login 配置登录页的//logoutreturnsecurity .authorizeHttpRequests() .anyRequest() .authenticated() //跳转登录页面 permitAll() 放开请求,不用进去登录页 .and() .formLogin()//postmapping .successHandler(newSucessLogin())//这个与defaultSuccessUrl是冲突的 .failureHandler(newFailLogin()) .loginPage("/login") //这个必须要写getmapping// .defaultSuccessUrl("/index") //这个就相当于实现了 //redirect .permitAll() .and() .logout()//这个post要自己写 .logoutUrl("/logout") .logoutSuccessUrl("/login") .and() .csrf() .disable() .build(); } publicWebSecurityCustomizerwebSecurityCustomizer(){ return (web)->web.ignoring() .antMatchers("/resign") .antMatchers("/sign") .regexMatchers("/css/.*") .regexMatchers("/js/.*"); } }
4.5.2 passwordEncoderConfig
packageorg.gaocl.demo.config; importorg.springframework.context.annotation.Bean; importorg.springframework.context.annotation.Configuration; importorg.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; importorg.springframework.security.crypto.password.PasswordEncoder; publicclassCryptoConfig { publicPasswordEncoderpasswordEncoder(){ returnnewBCryptPasswordEncoder(); } }
4.5.3 sucessedHanler
packageorg.gaocl.demo.config; importorg.springframework.http.MediaType; importorg.springframework.security.core.Authentication; importorg.springframework.security.web.authentication.AuthenticationSuccessHandler; importjavax.servlet.ServletException; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importjava.io.IOException; importjava.io.PrintWriter; publicclassSucessLoginimplementsAuthenticationSuccessHandler { publicvoidonAuthenticationSuccess(HttpServletRequestrequest, HttpServletResponseresponse, Authenticationauthentication) throwsServletException, IOException { response.setStatus(200); response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE); PrintWriterprintWriter=response.getWriter(); printWriter.write("用户名:"+request.getParameter("username")+"登录成功"); //这个必须自己写printWriter.flush(); printWriter.close(); } }
4.5.4 failHandler
packageorg.gaocl.demo.config; importlombok.extern.slf4j.Slf4j; importorg.springframework.http.MediaType; importorg.security.core.AuthenticationException; importorg.springframework.security.web.authentication.AuthenticationFailureHandler; importjavax.servlet.ServletException; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importjava.io.IOException; importjava.io.PrintWriter; publicclassFailLoginimplementsAuthenticationFailureHandler { publicvoidonAuthenticationFailure(HttpServletRequestrequest, HttpServletResponseresponse, AuthenticationExceptionexception) throwsIOException, ServletException { response.setStatus(400); response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);; PrintWriterprintWriter=response.getWriter(); // log.info(response.getWriter().toString());// printWriter.write(response.getStatus());printWriter.write(exception.getMessage()); // printWriter.write("username error or password error!!!");// printWriter.write(exception.getMessage().toLowerCase());printWriter.flush(); printWriter.close(); } }
4.6 启动项
packageorg.gaocl.demo; importorg.springframework.boot.SpringApplication; importorg.springframework.boot.autoconfigure.SpringBootApplication; publicclassApplication { publicstaticvoidmain(String[] args) { SpringApplication.run(Application.class, args); } }
5 templates
5.1 登录页log.tml
<htmllang="en"><htmlxmlns:th="http://www.thymeleaf.org"><head><metacharset="UTF-8"><title>Title</title></head><body><style>input { width:100%; height: 40px; margin: 16px; border-radius: 8px; } </style><divstyle="width: 100%; margin-top: 100px"><!-- <p th:if="${param.error}" style="">--><!-- ⽤户名或密码错误--><!-- </p>--><h2style="width: 100px; margin: auto">登录界面</h2><formth:action="@{/login}"method="post"style="width:300px; margin: auto"><inputname="username"placeholder="输入名字:"/><br/><inputname="password"placeholder="输入密码"/><br/><inputtype="submit"th:value="登录"></form><ath:href="@{/sign}">注册</a></div></body></html>
5.2 首页 index.html
<htmllang="en"><htmlxmlns:th="http://www.thymeleaf.org"><head><metacharset="UTF-8"><title>Title</title></head><body><divstyle="margin-top: 100px; width: 100%"><divstyle="margin: auto; width: 300px; text-align: center"><h1style="color: red;"> hello spring</h1><br/><formth:action="@{/logout}"method="post"style="margin-top: 100px"><buttontype="submit">退出</button></form></div></div></body></html>
5.3 注册页 resign.html
<htmllang="en"><htmlxmlns:th="http://www.thymeleaf.org"><head><metacharset="UTF-8"><title>Title</title></head><body><style>input { width:100%; height: 40px; margin: 16px; border-radius: 8px; } </style><divstyle="width: 100%; margin-top: 100px"><!-- <p th:if="${param.error}" style="">--><!-- ⽤户名或密码错误--><!-- </p>--><h2style="width: 100px; margin: auto">注册界面</h2><formth:action="@{/resign}"method="post"style="width:300px; margin: auto"><inputname="username"placeholder="输入名字:"/><br/><inputname="password"placeholder="输入密码"/><br/><inputtype="submit"th:value="注册"></form><ath:href="@{/login}">返回登录页面</a></div></body></html>
6 数据库
mysql 数据库
create database test;use test;create talbe( id INTNOTNULL AUTO_INCREMENT PRIMARY KEY, username VARCHAR(100)NOTNULL, password VARCHAR(100)notnull);
7 run
跑起来,localhost:8080/index访问