项目搭建主要过程
- 百度确定bootstrap模板(bootstrap.min.js,jquery-3.2.1.slim.min.js)(模板之家免费)
- Springboot(2.2.6.RELEASE)(任何项目不能脱离版本来谈)
- 首页实现
- 国际化
- 登录功能实现
- 登录拦截器
- 员工列表CRUD
- 404处理
实操
新建一个springboot项目(确定jdk,maven环境)
进入pom.xml确认版本
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent>
导入确定的一些依赖
<dependencies> <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!--加入thymeleaf--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional> true </optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
把资源堆进来(thymeleaf改造,各种调试)
编译项目,直接运行http://localhost:8080/
模拟数据库
package com.example.sampleemployeemgr.dao; import com.example.sampleemployeemgr.pojo.Department; import com.example.sampleemployeemgr.pojo.Employee; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import java.util.Collection; import java.util.HashMap; import java.util.Map; //员工dao @Repository public class EmployeeDao { //模拟数据库的信息 private static Map<Integer, Employee> employees=null; //员工所属的部门 @Autowired private DepartmentDao departmentDao; static { employees=new HashMap<Integer, Employee>(); employees.put(1001,new Employee(1001,"AA1","1918308849@qq.com",0,new Department(101,"教学部"))); employees.put(1002,new Employee(1002,"AA2","1918308849@qq.com",1,new Department(102,"市场部"))); employees.put(1003,new Employee(1003,"AA3","1918308849@qq.com",0,new Department(103,"教研部"))); employees.put(1004,new Employee(1004,"AA4","1918308849@qq.com",1,new Department(104,"运营部"))); employees.put(1005,new Employee(1005,"AA5","1918308849@qq.com",0,new Department(105,"后勤部"))); } //主键自增 private static Integer initId=1006; //增加一个员工 public void save(Employee employee){ if(employee.getId()==null){ employee.setId(initId++); } employee.setDepartment(departmentDao.getDepartmentById(employee.getDepartment().getId())); employees.put(employee.getId(),employee); } //查询全部员工信息 public Collection<Employee> getAll(){ return employees.values(); } //通过id查询员工 public Employee getEmployeeById(Integer id){ return employees.get(id); } //删除员工通过id public void delete(Integer id){ employees.remove(id); } }
首页实现
(template中的页面需要controller进行跳转)
首页,自然就是index.html页面
当然如下做法可以实现
但是对于这种根目录下的视图控制,正规的做法是扩展SpringMVC,重写添加视图控制方法
(main.html可以是一个不存在的页面)
接下来就是把找来的html页面按照Thymeleaf模板引擎的规则进行修改
- 导命名空间<html lang="en" xmlns:th="http://www.thymeleaf.org">
- 所有的超链接/静态资源用@{} 包起来,并在其属性名前加上th:
- 关闭模板引擎缓存spring.thymeleaf.cache=false(非必须)
国际化
确保File Encodings都是UTF-8
html页面需要国际化的内容用th:text="#{login.tip}" th:placeholder="#{login.username}" [[#{login.remember}]]等方式替换
上面写的三个国际化配置文件,实际上都是静态资源文件,对于页面来说唾手可得,只不过浏览器要显示中文还是英文,它需要通过Http请求服务器,再由服务器地区解析器决定显示哪种语言
WebMvcAutoConfiguration自动配置类中搜索地区locale找到localeResolver解析器
(被@ConditionalOnMissingBean注解修饰表示执行此方法的必须要求容器中没有这个东西 ,现在为了要定制化的实现解析器的规则 ,需要自行去构造一个实现了LocaleResolver接口的对象 ,在MyMvcConfig中用@Bean的方式扔到容器中)
默认返回的是AcceptHeaderLocaleResolver localeResolver,它实现了LocaleResolver接口,则它就是一个LocaleResolver
那么我们也同样的,搞一个对象继承LocaleResolver,实现其resolveLocale方法,并交给容器。
(交给容器这个交的动作,我们也学WebMvcAutoConfiguration)
@Bean public LocaleResolver localeResolver(){ return new MyLocaleResolver(); }
制造的对象
public class MyLocaleResolver implements LocaleResolver { @Override public Locale resolveLocale(HttpServletRequest request) { //获取请求 String language=request.getParameter("l"); Locale locale=Locale.getDefault();//如果没有就使用默认的 //如果请求的链接携带了国际化的参数 if(!StringUtils.isEmpty(language)){ //zh_CN String[] split=language.split("_"); //国家,地区 locale=new Locale(split[0],split[1]); } return locale; } @Override public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) { } }
(断点调试发现每次Http请求都会进入此方法,当get请求参数中有“l”时才会切换,否则都是默认语言,而默认语言是服务端认定的,以每次切换后的为默认)
登陆功能实现
处理登陆请求
@Controller public class LoginController { @RequestMapping("/user/login") public String login(@RequestParam("username") String username, @RequestParam("password") String password, Model model, HttpSession session){ if(!StringUtils.isEmpty(username) && password.equals("123456")){ session.setAttribute("loginUser",username); return "redirect:/main.html"; }else{ model.addAttribute("msg","用户名或密码错误!"); return "index"; } } }
<!-- 如果msg值不为空,则显示消息 --> <p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
处理登录成功后的重定向
可见登陆成功后跳转到了dashboard.html
拦截器
MyMvcConfig
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginHandlerInterceptor()) .addPathPatterns("/**") .excludePathPatterns("/index.html","/","/user/login","/css/**","/img/**","/js/**"); }
拦截所有请求(除了登陆页面,登陆请求,页面资源请求)
public class LoginHandlerInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Object loginUser = request.getSession().getAttribute("loginUser"); if (loginUser==null){ request.setAttribute("msg","没有权限,请先登录!"); request.getRequestDispatcher("/index.html").forward(request,response); return false; }else{ return true; } } }
404
https://github.com/ChenCurry/springboot-collection/tree/main/sb-07-employee-mgr