Spring-boot简单管理系统

先创建一个Controller包,在里面写一些网页的跳转:
@Controller注解标注类的方法,return时会被视图处理器识别成静态文件的路径。
因此先在Controller包中新建的类上标注@Controller@ResponseBody为返还json格式的数据。
注意:需加上页面渲染工具 Thymeleaf,否则不能跳转页面。
1、网站登录页

    //当访问 / 或者 /login时跳转到首页
    @GetMapping(value ={"/","/login"})
    public String loginPage(){
        return "login";
    } //return的login为login.html文件
    // 只要放在template中,去掉前和后缀只写需要跳转的html网页即可

2、登录后的页面
当在首页时,表单提交则进入登录后的页面(这里是简单测试,不管输入什么都会登录)
还有一点,如果登陆后一直刷新网页就相当于一直在重复提交,因此要把登陆后的状态识别开。这里使用了重定向。

    //当首页以 post提交到/login时,跳转到以下页面  因为接收方式和上面的get不一样所以可以一样为login
    @PostMapping("/login")
    public String main(User user, HttpSession session){
        //登录成功重定向到index.html
        if (!"".equals(user.getUsername())&&!"".equals(user.getPassword())) {
        	//不为空,将用户的值传到下一个跳转的页面
            session.setAttribute("user",user);
            //登录成功重定向跳转到index页面
            return "redirect:index.html";
        }
        else
            //如果什么都没输入直接登录,则回到登录页(相当于一直在登录页)
            return "login";
    }

3、防止在任何情况直接访问到index.html网页
如果一开始就直接访问index.html页面,由于用户没有登录,所以是为空的,直接跳转到登录页面,如果用户不为空,则继续留在index页面(防止了重复提交)

    /**
     * 去index页面
     * @return
     */
    //防止重复提交 造成一直登录 使用以上的重定向
    @GetMapping("/index.html")
    public String PreventRepetitionSubmit(HttpSession session, Model model){
        User user= (User) session.getAttribute("user");
        if (null!=user) {
            session.setAttribute("user",user);
            return "index";
        }
        else {
            model.addAttribute("msg","请登录");
            return "login";
        }
    }

Thymeleaf
这里面使用了Thymeleaf插件,th:text="${msg}代表的是后台Model中的msg值;
th:action="@{/login} 相当于将form表单中的属性值给他改了;
以上两个都是写在标签体内部的,标签体外的话使用;
[[${session.user.username}]]
注意!!!:因为我们的模板是放在template,用return访问这些html文件时一定要在
html文件的抬头加入<html xmlns:th="http://www.thymeleaf.org">,这样就能不加template和.html后缀直接访问里面的html文件,但是如果在template下面的文件夹中的html要加上这个文件夹的名字。类似table/dynamic_table这样。
还可以通过thymeleaf管理网页的公共部分,例如:
先创建一个common.html网页, 他们的这一部分是公共的,可以在引入以上的抬头后,在公共的地方加上th:fragment="commonheader",然后把公共的部分复制到这个里面去,要用的时候就直接在需要被用到的地方加上 <div th:include="common :: commonheader"></div>就可以了,include是包含在里面,replcae是代替原来的,insert是插入进去
如果是以id而不是<head th:fragment="commonheader">这样写的话,用<div th:replcae="common :: #leftmenu"></div>这样去表示。注意变化了#号

    <head th:fragment="commonheader">
        <meta charset="UTF-8">
        <title>Title</title>
        <!--common-->
        <link href="css/style.css" th:href="@{/css/style.css}" rel="stylesheet">
        <link href="css/style-responsive.css" th:href="@{/css/style-responsive.css}" rel="stylesheet">
        <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
        <!--[if lt IE 9]>
        <script src="js/html5shiv.js" th:src="@{/js/html5shiv.js}"></script>
        <script src="js/respond.min.js" th:src="@{/js/respond.min.js}"></script>
        <![endif]-->
    </head>
    在其他需要的地方输入以下这个引入
        <div th:insert="common :: #leftmenu"></div>

使用Thymeleaf,遍历(相当于)数据库中的信息,呈现到前端网页表格中(简单示例):
前端的html代码,user为封装的实体类,里面有username和password。
th:each="user,stats:${users} 相当于在遍历后台传的数据,stats为传过来的所有状态信息,有index和count可以看出有多少个,相当于编号。

        <tr class="gradeX" th:each="user,stats:${users}">
            <td th:text="${stats.count}"></td>
            <td th:text="${user.username}"></td>
            <td>[[${user.password}]]</td>
        </tr>

后端java代码,是通过Model放进去的,相当于request.setAttribute

	@GetMapping("/dynamic_table")
    public String dynamic_table(Model model){
        List<User> list= Arrays.asList(new User("syf","123"),new User("wfl","456"),
                      new User("wgx","471"),new User("mhy","qwe"));

        model.addAttribute("users",list);
        return "table/dynamic_table";
    }

拦截器

先创建一个自己的拦截器类,实现HandlerInterceptor接口,重写它的三个方法,

/**
 * 拦截器:
 * 做登录检查
 * 1、配置好拦截器要拦截哪些请求
 * 2、把这些配置放在容器
 * 3、
 */
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
    /**
     * 目标方法执行之前
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //登录检查逻辑
        log.info("拦截的请求路径"+request.getRequestURI());//打印拦截请求日志
        HttpSession session=request.getSession();
        Object loginUser=session.getAttribute("user");
        if (null!=loginUser) {
            //放行
            return true;
        }
        else {
            //不放行 未登录,跳转到登录界面
            request.setAttribute("msg","请登录");
            request.getRequestDispatcher("/").forward(request,response);
            return false;
        }
    }
    /**
     * 目标方法完成以后
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }
    /**
     * 页面渲染以后
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }
}

然后将自己写的拦截器添加进去,添加到标注了@Configuration标签的类里面

/**
 * 1、编写的拦截器实现HandlerInterceptor接口
 * 2、拦截器注册到容器中,通过实现WebMvcConfigurer的addInterceptors
 * 3、指定拦截规则【如果是拦截所有,静态资源也会被拦截】
 */
@Configuration
public class AdminWebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        /*
        添加新创建的拦截器,addPathPatterns要拦截的,excludePathPatterns要放行的
        */
        registry.addInterceptor(new LoginInterceptor())
                 .addPathPatterns("/**")//会把静态资源也拦截了
                 .excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**");//把静态资源下的这几个放行
    }
}

文件上传

先将底层写死的能够上传的文件大小修改,在application.properties中

#单个文件的最大上传大小
spring.servlet.multipart.max-file-size=1000MB
#整个上传的文件大小、
spring.servlet.multipart.max-request-size=10000MB

Html中提交文件的表单form写法:
<form class="form-horizontal" role="form" th:action="@{/upload}" method="post" enctype="multipart/form-data">文件上传表单的固定写法
如果是上传多个文件,在input中<input type="file" name="lifephoto" id="life" multiple>多了个multiple
表单提交过来的的数据处理:
其中form_layouts.html为文件表单上传所在的html文件名,MultipartFile 为上传的文件的数据类型,@RequestPart("headimage")用法和RequestParam一样,都是把表单中上传文件的name填进去即可。

@Slf4j
@Controller
public class FileUpload {
    @GetMapping("/form_layouts")
    public String uploadTest(){
        return "form/form_layouts.html";
    }
    //MultipartFile会自动封装上传过来的文件
    @PostMapping("/upload")
    public String upload(@RequestParam("username")String username,
                         @RequestParam("email")String email,
                         @RequestPart("headimage") MultipartFile headimage,//单文件
                         @RequestPart("lifephoto") MultipartFile[] lifephoto) throws IOException {//多文件,文件太大就不行了需要修改
        log.info("上传的信息 ,email={},username={},headimage={},lifephoto={}",
                email,username,headimage.getSize(),lifephoto.length);
        if (!headimage.isEmpty()) {
            String original=headimage.getOriginalFilename();
            headimage.transferTo(new File("C:\\Users\\syf\\Desktop\\test\\"+original));
        }
        if (lifephoto.length>0) {
            for (MultipartFile x:lifephoto)
                if (!x.isEmpty()){
                    x.transferTo(new File("C:\\Users\\syf\\Desktop\\test\\"+x.getOriginalFilename()));
                }
        }
        return "index";
    }
}

异常错误处理

可以在templates下创建error文件夹,将404.html和5xx.html放进去,这样我们就可以自定义错误界面了,还可以用Thymeleaf显示错误信息,也可以将404写成4xx。
1、自定义的异常处理器
这个能处理数学运算异常和空指针异常

/**
 * 处理整个 web Controller异常
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 代表当前为异常处理器
     * 下面的标注value中的内容代表处理数学异常和空指针异常
     */
    @ExceptionHandler({ArithmeticException.class,NullPointerException.class})
    public String handlerMathException(Exception e){
        log.info("异常是:"+e);
        return "login";
    }
}

2、自定义的异常

/**
 * 自定义的异常
 * 返回状态码信息的标注
 * HttpStatus.FORBIDDEN 拒绝403
 * reason为错误的原因
 */
@ResponseStatus(value = HttpStatus.FORBIDDEN,reason = "用户量太多")
public class UserTooManyException extends RuntimeException{
    public UserTooManyException(String message){
        super(message);
    }
    public UserTooManyException() {
    }
}

3、自定义的异常解析器
我们把优先级设置为最高相当于什么错误都是它处理

/**
 * 自定义的异常解析器
 */
@Order(value = PriorityOrdered.HIGHEST_PRECEDENCE)//异常处理的优先级,数字越小优先级越大
@Component
public class CustomerHandlerExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest,
                                         HttpServletResponse httpServletResponse,
                                         Object o, Exception e) {
        try {
            httpServletResponse.sendError(522,"522错误");
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
        return new ModelAndView();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

syf_wfl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值