在浏览器输入 http://localhost:8080 或者 http://localhost:8080/login 能够跳转到登陆界面
spring initializr创建项目 勾选springweb, dev开发,lombok, processce,以及 thymeleaf
spring-boot-configuration-processor的作用
坑的地方: 注意springboot与thymeleaf版本问题,使用了3.0.x版本一直报错
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";
}
}
输入用户名和密码后,点击登录跳转到对应主页
开启thymeleaf
<html lang="en" xmlns:th="http://www.thymeleaf.org">
@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";
}
}
每次刷新主页,就相当于重新提交了一次表单
@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";
}
}
原来的系统无法对用户名密码进行验证,
@Data
public class User {
private String userName;
private String password;
}
@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";
}
}
}
利用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>
写一个拦截器,当未登录时,不能访问main页面(前面已经实现了)、table页面
继承 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;
}
}
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/**");//放行的请求
}
}
能够跳转到form页面
@Controller
public class FormController {
@GetMapping("/form_layouts")
public String formGoto(){
return "/form/form_layouts";
}
}
<form method="post" action="/upload" enctype="multipart/form-data">
<input type="file" name="file"><br>
<input type="submit" value="提交">
form>
@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
● 默认情况下,Spring Boot提供/error处理所有错误的映射
● 要完全替换默认行为,可以实现 ErrorController 并注册该类型的Bean定义,或添加ErrorAttributes类型的组件以使用现有机制但替换其内容
@Slf4j
@ControllerAdvice
//@ControllerAdvice的作用:结合方法型注解@ExceptionHandler,用于捕获Controller中抛出的指定类型的异常,从而达到不同类型的异常区别处理的目的
public class GlobalExceptionHandler {
@ExceptionHandler({ArithmeticException.class, NullPointerException.class})
public String handleArithException(Exception e){
log.error("异常是{}",e);
return "login";
}
}
@ResponseStatus(value= HttpStatus.FORBIDDEN,reason = "用户数量太多")
//使用时,先声明一个自定义异常类,在自定义异常类上面加上@ResponseStatus注释表示系统运行期间,当抛出自定义异常的时候,使用@ResponseStatus注解中声明的属性和reason属性将异常信息返回给客户端,提高可读性。
public class UserTooManyException extends RuntimeException{
public UserTooManyException(){
}
public UserTooManyException(String message){
super(message);
}
}
@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();
}
}
有两种方法实现,此处采用注解格式完成
在SpringBootApplication上使用@ServletComponentScan注解后,Servlet(控制器)、Filter(过滤器)、Listener(监听器)可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册到Spring容器中,无需其他代码。
@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方式提交的表单。
@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);
}
}
@Slf4j
@WebListener
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
log.info("监听器初始化..");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
log.info("监听器销毁...");
}
}
@Component
public class CustomizationBean implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
@Override
public void customize(ConfigurableServletWebServerFactory server) {
server.setPort(9000);
}
}
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.1.17version>
dependency>
@ConfigurationProperties("spring.datasource")//绑定属性
@Bean
public DataSource dataSource(){
DruidDataSource druidDataSource = new DruidDataSource();
return druidDataSource;
}
@Bean
public ServletRegistrationBean statViewServlet(){
//StatViewServlet的用途包括:
//● 提供监控信息展示的html页面
//● 提供监控信息的JSON API
StatViewServlet statViewServlet = new StatViewServlet();
ServletRegistrationBean<StatViewServlet> registrationBean = new ServletRegistrationBean<>(statViewServlet,"/druid/*");
return registrationBean;
}
@ConfigurationProperties("spring.datasource")//绑定属性
@Bean
public DataSource dataSource() throws SQLException {
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setFilters("stat,wall");//加入监控、防火墙
return druidDataSource;
}
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>1.1.17version>
dependency>
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
mybatis:
config-location: classpath:mybatis/mybatis-config.xml
mapper-locations: classpath:mybatis/mapper/*.xml
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
configuration>
@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);
}
}
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">
<select id="getBook" resultType="com.chent.boot03admin.bean.Book">
select * from tbl_book where id=#{id}
select>
mapper>
//需要写好book bean
@Controller
public class datasourceController {
@Autowired
BookService bookService;
@ResponseBody
@GetMapping("/book")
public Book getById(@RequestParam("id") Long id){
return bookService.getBookByid(id);
}
}
不需要写xml文件,直接注解写
@Mapper
public interface BookMapper {
@Select("select * from tbl_book where id=#{id}")
public Book getBook(Long id);
}
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.4.1version>
dependency>
@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;
}
public interface UserMapper extends BaseMapper<User> {
}
@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 {
}//实现类