SpringBoot学习笔记(二)实现简单网站

SpringBootWeb开发

@Bean为自己配置的组件
1.导入静态资源
  • webjars 通过访问localhost:8080/webjars/
  • public,static,resource 通过访问localhost:8080/static/
<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">
<img th:src="@{/img/bootstrap-solid.svg}">
  • 首页所有的配置都需要使用thymeleaf来接管
2.首页
  • 使用RequestMapping需要Thymeleaf的依赖
  • 在static文件夹添加favicon.ico会修改浏览器的默认图标
  • 首先使用thymeleaf语法替换原来的index.html
3.模板引擎Thymeleaf
变量表达式${}
国际化消息#{}
Link URL @{}
>,<,>=,<= (gt,lt,ge,le)
(if)?(then):(else)
  • 模板引擎是将视图与用户数据分离,也就是模板和数据通过模板引擎生成最终的html代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
  • thymeleaf的模板在template里
  • 在ThymeleafProperties里读源码找prefix和suffix找到前缀和后缀
//简单的th语法,在Controller的model赋值
model.addAttribute("msg","<h1>hello,springboot</h1>");
model.addAttribute("users", Arrays.asList("123","456"));
//使用RequestMapping("/test")跳转页面,同时渲染模板
<h1 th:text="${msg}"></h1>
//遍历取出每个元素,然后将元素渲染
<div th:each="user:${users}" th:text="${user}"></div>
  • 判断是否显示某个标签
///使用了#strings.isEmpty(msg)来判断是否为空
<p style="color:red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
4.装配扩展SpringMVC
@Configuration //进行扩展配置
public class MyMvcConfig implements WebMvcConfigurer {
    //自定义配置文件。通过@Bean,springBoot会将该解析器加入ViewResolver
    @Bean
    public ViewResolver myViewResolver(){
        return new MyViewResolver();
    }
    //定义了自己的视图解析器,实现了SpringBoot的视图接口
    public static class MyViewResolver  implements ViewResolver{

        @Override
        public View resolveViewName(String viewName, Locale locale) throws Exception {
            return null;
        }
    }
    //重新定向路由将setViewName里的路由映射到addViewController里,并显示addViewController里的新路由
    //setViewName的路由由Controller里的return得到
    
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index.html").setViewName("index");
        registry.addViewController("/main.html").setViewName("dashboard");//设置路由映射
    }
    //LoginController里的重定位代码
    if(!StringUtils.isEmpty(username) && password.equals("123456"))
        {
            return "redirect:/main.html";
        }
    @Bean
    public LocaleResolver localeResolver(){
        return new MyLocalResolver();
    }
}
5.增删改查
在pojo中增加@Data(getter && setter)
增加@AllArgsConstructor为无参构造,@NoArgsConstructor有参构造
  • 提取公共页面
  • 括号里可以传递参数,接受判断即可
<nav class="col-md-2 d-none d-md-block bg-light sidebar" th:fragment="sidebar">
<div th:replace="~{commons/common::sidebar(active='main.html')}"></div>
  • 列表循环展示,先提取单个变量,然后使用方法获得值
  • 注意其中有判断的地方和日期格式化
<tr th:each="emp:${emps}">
    <td th:text="${emp.getId()}"></td>
    <td th:text="${emp.getName()}"></td>
    <td th:text="${emp.getEmail()}"></td>
    <td th:text="${emp.getGender() == 0?'':''}"></td>
    <td th:text="${emp.getDepartment().getName()}"></td>
    <td th:text="${#dates.format(emp.getBirth(),'yyyy-MM-dd HH:mm:ss')}"></td>
    <td>
        <button class="btn btn-sm btn-primary">编辑</button>
        <button class="btn btn-sm btn-danger">编辑</button>
    </td>
</tr>
  • 大体思路是先通过页面的链接标签来对应Controller的方法
<a class="btn btn-sm btn-primary" th:href="@{/emp/{id}(id=${emp.getId()})}">编辑</a>
<a class="btn btn-sm btn-danger" th:href="@{/delemp/{id}(id=${emp.getId()})}">删除</a>
//提交表单对应后端的响应
<form th:action="@{/emp}" method="post">
  • 然后通过Java方法来对应后端的数据库操作
@GetMapping("/emp")
public String toAddPage(Model model){
    //查出所有部门的信息
    Collection<Department> departments = departmentDao.getAllDepartments();
    model.addAttribute("departments",departments);
    //跳转到后端页面add.html
    return "emp/add";
}
@PostMapping("/emp")
public String addEmp(Employee employee){
    //添加的操作
    System.out.println(employee);
    employeeDao.add(employee);
    //重定向是转向到emps的Controller重新渲染
    return "redirect:/emps";
}
  • 通过model视图来渲染前端页面
@GetMapping("/emp/{id}")
public String toUpdatePage(@PathVariable("id")Integer id, Model model)
{
    System.out.println(id);
    Employee employee = employeeDao.getEmployee(id);
    model.addAttribute("employee",employee);
    System.out.println(employee);
    Collection<Department> departments = departmentDao.getAllDepartments();
    model.addAttribute("departments",departments);
    return "emp/update";
}
  • model的addAttribute()方法会将设置的object值传给前端
<input type="hidden" name="id" th:value="${employee.getId()}">
<div class="form-group">
<label>department</label>
<!--提交的是一个属性,而不是一个对象-->
<select class="form-control" name="department.id">
    <option  th:each="department:${departments}" th:text="${department.getName()}" th:selected="${department.getId() == employee.getDepartment().getId()}" th:value="${department.getId()}"></option>
</select>
</div>
6.拦截器
  • 首先是拦截器的配置,需要实现HandlerInterceptor
public class LoginHandlerInterceptor implements HandlerInterceptor {
    //preHandle()是预处理
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //设置session的值
        Object loginUser = request.getSession().getAttribute("loginUser");
        if(loginUser == null)
        {
            request.setAttribute("msg","没有权限,请先登录");
            //将request数据返回到index.html
            request.getRequestDispatcher("/index.html").forward(request,response);
            return false;
        }
        else
            return true;
    }
}
  • 其次将拦截器加载到自定义的MVC视图文件里
@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/index.html","/","/user/login","/css/**","/js/**","/img/**");
//addInterceptors()添加一个拦截器,addPathPatterns()添加拦截路径,默认所有
//excludePathPatterns()被拦截时返回会被放行的内容,一般是静态文件,根目录,首页
}
7.国际化
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
<input type="text" class="form-control" th:placeholder="#{login.username}" required="" autofocus="">
<input type="password" class="form-control" th:placeholder="#{login.password}" required="">
  • 配置i18n文件
  • 自定义LocaleResolver()
  • 组件配置配置到自定义的MVC @Bean
@Bean
public LocaleResolver localeResolver(){
    return new MyLocalResolver();
}
public class MyLocalResolver implements LocaleResolver {
    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        String language = request.getParameter("l");
        Locale locale = Locale.getDefault();//没有就使用默认的
        if(!StringUtils.isEmpty(language)){
            String[] split = language.split("_");
            locale = new Locale(split[0], split[1]);
        }

        return locale;
    }

    @Override
    public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {

    }
}
  • 模板引擎渲染为@{xxx.html"(传入参数)}
<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值