文章目录
1. 登录页面
1.1 实现功能
在浏览器输入 http://localhost:8080 或者 http://localhost:8080/login 能够跳转到登陆界面
1.2 创建springboot项目
spring initializr创建项目 勾选springweb, dev开发,lombok, processce,以及 thymeleaf
spring-boot-configuration-processor的作用
坑的地方: 注意springboot与thymeleaf版本问题,使用了3.0.x版本一直报错
1.3 放静态资源
1.4 写controller
package com.chent.boot03admin.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@Controller
public class IndexController {
// 来登录页
@GetMapping(value={"/","/login"})
// @GetMapping("/login")
public String loginPage(){
return "login";
}
}
- 注意事项
注解必须写controller 不能写restcontroller 。Restcontroller会把你返回的当字符串处理
@Controller:标识一个Spring类是Spring MVC controller处理器,@RestController:@RestController是@Controller和@ResponseBody的结合体,两个标注合并起来的作用。@Controller类中的方法可以直接通过返回String跳转到jsp、ftl、html等模版页面。在方法上加@ResponseBody注解,也可以返回实体对象。@RestController类中的所有方法只能返回String、Object、Json等实体对象,不能跳转到模版页面。
2. 跳转主页
2.1 实现功能
输入用户名和密码后,点击登录跳转到对应主页
2.2 login.html文件
开启thymeleaf
<html lang="en" xmlns:th="http://www.thymeleaf.org">
2.3 修改Controller
@Controller
public class IndexController {
// 来登录页
@GetMapping(value={"/","/login"})
// @GetMapping("/login")
public String loginPage(){
return "login";
}
//加了post请求
@PostMapping("/login")
public String main(String userName,String password){
return "main";
}
}
3. 解决表单重复提交问题
3.1 问题描述
每次刷新主页,就相当于重新提交了一次表单
3.2 修改Controller
@Controller
public class IndexController {
// 来登录页
@GetMapping(value={"/","/login"})
// @GetMapping("/login")
public String loginPage(){
return "login";
}
@PostMapping("/login")
public String main(String userName,String password){
return "redirect:/main.html";//重定向
}
@GetMapping("/main.html")
public String mainPage(){
return "main";
}
}
4. 对登录用户名密码设定
4.1 问题描述
原来的系统无法对用户名密码进行验证,
4.2 创建User类记录用户信息,并对登录页login.html修改
@Data
public class User {
private String userName;
private String password;
}
4.3 修改controller
- 在post请求里面进行内容判断,并保留用户信息到session
- 在刷新的时候,get请求里面对session的内容进行判断
@Controller
public class IndexController {
// 来登录页
@GetMapping(value={"/","/login"})
// @GetMapping("/login")
public String loginPage(){
return "login";
}
@PostMapping("/login")
public String main(User user, HttpSession session, Model model){
if( StringUtils.hasLength(user.getUserName()) && "123456".equals(user.getPassword()) ){//用户名密码正确
session.setAttribute("loginUser",user);//实现数据共享
return "redirect:/main.html";//跳转到主页
}else{
model.addAttribute("msg","密码错误");
return "login";
}
}
@GetMapping("/main.html")
public String mainPage(HttpSession session,Model model){
Object loginUser = session.getAttribute("loginUser");//对上面的session进行判断
if(loginUser!= null){//若存在信息
return "main";
}else{
model.addAttribute("msg","错误");
return "login";
}
}
}
5. 修改用户信息
5.1 问题描述
动态显示右上角用户名
5.2 修改main.html代码
利用th修改
<a href="#" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<img src="images/photos/user-avatar.png" alt="" />
[[${session.loginUser.userName}]]
<span class="caret"></span>
</a>
6. 拦截器
6.1 问题描述
写一个拦截器,当未登录时,不能访问main页面(前面已经实现了)、table页面
6.2 编写拦截器Interceptor
继承 HandlerInterceptor
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//得到拦截的URI
String requestURI = request.getRequestURI();
log.info("preHandle拦截的路径是{}",requestURI);
HttpSession session = request.getSession();
Object loginUser = session.getAttribute("loginUser");
if (loginUser != null){
return true;
}
request.setAttribute("msg","请先登录");
response.sendRedirect("/");
return false;
}
}
6.3 设置添加拦截器
WebMvcConfiguer addInterceptors
@Configuration
public class AdminWebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor()) //新加一个拦截器
.addPathPatterns("/**")//表示拦截所有
.excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**");//放行的请求
}
}
7. 文件上传
7.1 实现页面跳转
能够跳转到form页面
- controller
@Controller
public class FormController {
@GetMapping("/form_layouts")
public String formGoto(){
return "/form/form_layouts";
}
}
- 修改mian文件,添加form_layouts.html
7.2 实现文件提交,打印并保存文件相关信息
- 页面表单
<form method="post" action="/upload" enctype="multipart/form-data">
<input type="file" name="file"><br>
<input type="submit" value="提交">
</form>
- 修改controller
@Slf4j
@Controller
public class FormController {
@GetMapping("/form_layouts")
public String formGoto() {
return "/form/form_layouts";
}
@PostMapping("/upload")
public String upload(@RequestParam("email") String email,
@RequestParam("username") String username,
@RequestPart("headerImg") MultipartFile headerImg,
@RequestPart("photos") MultipartFile[] photos) throws IOException {
log.info("上传的信息:email={},username={},headImg={},photos={}",
email,username,headerImg.getSize(),photos.length);
if(!headerImg.isEmpty()){
String originName = headerImg.getOriginalFilename();
headerImg.transferTo(new File("C:\\Users\\atrhu\\Desktop\\job\\尚硅谷资料\\springboot2\\image\\"+originName));//保存文件
}//单文件上传
if(photos.length>0){
for(MultipartFile photo:photos){
if(!photo.isEmpty()){
String originName = photo.getOriginalFilename();
photo.transferTo(new File("C:\\Users\\atrhu\\Desktop\\job\\尚硅谷资料\\springboot2\\image\\"+originName));//保存文件
}//多文件上传
}
}
return "main";//跳转回main页面
}
}
- 修改配置文件,改变上传文件大小
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=100MB
8. 错误处理
8.1 实现页面跳转
● 默认情况下,Spring Boot提供/error处理所有错误的映射
● 要完全替换默认行为,可以实现 ErrorController 并注册该类型的Bean定义,或添加ErrorAttributes类型的组件以使用现有机制但替换其内容
8.2 异常处理器
- ControllerAdvice+@ExceptionHandler处理全局异常
@Slf4j
@ControllerAdvice
//@ControllerAdvice的作用:结合方法型注解@ExceptionHandler,用于捕获Controller中抛出的指定类型的异常,从而达到不同类型的异常区别处理的目的
public class GlobalExceptionHandler {
@ExceptionHandler({ArithmeticException.class, NullPointerException.class})
public String handleArithException(Exception e){
log.error("异常是{}",e);
return "login";
}
}
- @ResponseStatus+自定义异常
@ResponseStatus(value= HttpStatus.FORBIDDEN,reason = "用户数量太多")
//使用时,先声明一个自定义异常类,在自定义异常类上面加上@ResponseStatus注释表示系统运行期间,当抛出自定义异常的时候,使用@ResponseStatus注解中声明的属性和reason属性将异常信息返回给客户端,提高可读性。
public class UserTooManyException extends RuntimeException{
public UserTooManyException(){
}
public UserTooManyException(String message){
super(message);
}
}
8.3 自定义HandlerExceptionResolver 处理异常
@Order(value = Ordered.HIGHEST_PRECEDENCE)
@Component
public class CustomerHandlerExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response,
Object handler, Exception ex) {
try {
response.sendError(511,"我喜欢的错误");
} catch (IOException e) {
throw new RuntimeException(e);
}
return new ModelAndView();
}
}
9. Web原生组件注入
-
有两种方法实现,此处采用注解格式完成
-
在SpringBootApplication上使用@ServletComponentScan注解后,Servlet(控制器)、Filter(过滤器)、Listener(监听器)可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册到Spring容器中,无需其他代码。
9.1 Servlet
@WebServlet(urlPatterns = "/my")
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("servlet success...");
}
}//doGet方法用来处理客户端浏览器直接访问和表单get方式提交的表单。
9.2 Filter
@Slf4j
@WebFilter(urlPatterns = "/css/*")
//注意Filter导入的是 javax.servlet.*;
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("MyFilter初始化.....");
}
@Override
public void destroy() {
log.info("MyFilter销毁中...");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// doGet方法用来处理客户端浏览器直接访问和表单get方式提交的表单。
log.info("myfilter工作中....");
filterChain.doFilter(servletRequest,servletResponse);
}
}
9.3 Listener
@Slf4j
@WebListener
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
log.info("监听器初始化..");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
log.info("监听器销毁...");
}
}
10. 嵌入式Servlet容器
- 方法一:修改配置文件 properties
- 方法二: ConfigurableServletWebServerFactory
@Component
public class CustomizationBean implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
@Override
public void customize(ConfigurableServletWebServerFactory server) {
server.setPort(9000);
}
}
11. 定制化原理(总结)
12. 自定义方式整合druid数据源 (繁琐,不推荐)
12.1 导入依赖、创建数据源
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.17</version>
</dependency>
@ConfigurationProperties("spring.datasource")//绑定属性
@Bean
public DataSource dataSource(){
DruidDataSource druidDataSource = new DruidDataSource();
return druidDataSource;
}
12.2 监控页功能
@Bean
public ServletRegistrationBean statViewServlet(){
//StatViewServlet的用途包括:
//● 提供监控信息展示的html页面
//● 提供监控信息的JSON API
StatViewServlet statViewServlet = new StatViewServlet();
ServletRegistrationBean<StatViewServlet> registrationBean = new ServletRegistrationBean<>(statViewServlet,"/druid/*");
return registrationBean;
}
12.3 监控、防火墙功能
@ConfigurationProperties("spring.datasource")//绑定属性
@Bean
public DataSource dataSource() throws SQLException {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setFilters("stat,wall");//加入监控、防火墙
return druidDataSource;
}
13. 使用官方Starter方式整合druid数据源 (比较方便)
13.1 引入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.17</version>
</dependency>
13.2 配置文件
spring:
datasource:
url: jdbc:mysql://localhost:3306/ssm_db
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
druid:
aop-patterns: com.atguigu.admin.* #监控SpringBean
filters: stat,wall # 底层开启功能,stat(sql监控),wall(防火墙)
stat-view-servlet: # 配置监控页功能
enabled: true
login-username: admin
login-password: admin
resetEnable: false
web-stat-filter: # 监控web
enabled: true
urlPattern: /*
exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'
filter:
stat: # 对上面filters里面的stat的详细配置
slow-sql-millis: 1000
logSlowSql: true
enabled: true
wall:
enabled: true
config:
drop-table-allow: false
14. 整合Mybatis
14.1 配置模式
14.1.1 引入mybatis-starter依赖
14.1.2 application.yml中指定mapper-location位置,写config文件
mybatis:
config-location: classpath:mybatis/mybatis-config.xml
mapper-locations: classpath:mybatis/mapper/*.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration>
14.1.3 编写mapper接口和实现类
@Mapper
public interface BookMapper {
public Book getBook(Long id);
}
@Service
public class BookService {
@Autowired
BookMapper bookMapper;
public Book getBookByid(Long id){
return bookMapper.getBook(id);
}
}
14.1.4 xml文件进行绑定
<?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.chent.boot03admin.mapper.BookMapper">
<!-- public Account getAcct(Long id); -->
<select id="getBook" resultType="com.chent.boot03admin.bean.Book">
select * from tbl_book where id=#{id}
</select>
</mapper>
14.1.5 controller
//需要写好book bean
@Controller
public class datasourceController {
@Autowired
BookService bookService;
@ResponseBody
@GetMapping("/book")
public Book getById(@RequestParam("id") Long id){
return bookService.getBookByid(id);
}
}
14.2 注解模式
不需要写xml文件,直接注解写
@Mapper
public interface BookMapper {
@Select("select * from tbl_book where id=#{id}")
public Book getBook(Long id);
}
15. 整合mybatis plus
15.1 引入依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
15.2 mapper映射文件的位置
15.3 User类
@Data
public class User {
@TableField(exist = false)
private String userName;
@TableField(exist = false)
private String password;//用户信息,需要排除在表外
public User(String userName, String password) {
this.userName = userName;
this.password = password;
}
private Long id;
private String name;
private Integer age;
private String email;
}
15.4 Mapper接口继承BaseMapper类
public interface UserMapper extends BaseMapper<User> {
}
15.5 Service和mapper
@Mapper
public interface UserMapper extends BaseMapper<User> {
}//继承BaseMapper类
public interface UserService extends IService<User> {
}//service接口
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}//实现类