目录
1)Spring MVC auto-configuration
1、使用springboot
2、springboot对静态资源的映射规则
源码:
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
} else {
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
if (!registry.hasMappingForPattern("/webjars/**")) {
this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
}
}
3、模板引擎
web开发 ——引入thymelea
1)引入thymeleaf
在pom文件中添加依赖坐标,在github上搜索thymeleaf,进行查找
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <thymeleaf.version>3.0.9.RELEASE</thymeleaf.version> <!-- 布局功能的支持程序 thymeleaf3主程序 layout2以上版本 --> <!-- thymeleaf2 layout1--> <thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version> </properties> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
2)thymeleaf的使用和语法
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>使用thymeleaf实现页面的跳转</h1>
<div th:text="${hello}">这是显示欢迎信息</div>
<div th:utext="${hello}"></div><!--不转义特殊字符-->
<br/>
<br/>
<br/>
<!--th:each每次遍历都会生成当前这个标签-->
<h1 th:text="${user}" th:each="user:${users}"></h1>
<br/>
<h1>
<span th:text="${users}"></span>
</h1>
</body>
</html>
@Controller
public class TestController {
@ResponseBody
@RequestMapping(name = "/getString")
public String getString(){
return "SUCCESS";
}
/**
* 查询一些数据,显示在success页面上
* @return
*/
@RequestMapping("thymeleafTest")
public String getHtml(Map<String,Object> map){
map.put("hello","<h1>你好</h1>");
map.put("users", Arrays.asList("张三","李四","王五"));
return "success";
}
}
3)语法规则
4)表达式
4、SpringMVC自动配置
springboot底层对springmvc如何进行自动配置???
官方文档第四章29:https://docs.spring.io/spring-boot/docs/1.5.10.RELEASE/reference/htmlsingle/#boot-features-developing-
web-applications
1)Spring MVC auto-configuration
2)扩展SpringMVC
ctrl+o显示父类的所有可继承的方法
3)全面接管SpringMVC
5、如何修改SpringBoot的自动配置
6、RestfulCRUD
1)默认访问首页
登录界面使用thymeleaf语法格式,引入资源文件
2)国际化
spring mvc中的步骤:
SpringBoot中的步骤:四大步骤
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http‐equiv="Content‐Type" content="text/html; charset=UTF‐8">
<meta name="viewport" content="width=device‐width, initial‐scale=1, shrink‐to‐
fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>Signin Template for Bootstrap</title>
<!‐‐ Bootstrap core CSS ‐‐>
<link href="asserts/css/bootstrap.min.css"
th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.css}" rel="stylesheet">
<!‐‐ Custom styles for this template ‐‐>
<link href="asserts/css/signin.css" th:href="@{/asserts/css/signin.css}"
rel="stylesheet">
</head>
<body class="text‐center">
<form class="form‐signin" action="dashboard.html">
<img class="mb‐4" th:src="@{/asserts/img/bootstrap‐solid.svg}"
src="asserts/img/bootstrap‐solid.svg" alt="" width="72" height="72">
<h1 class="h3 mb‐3 font‐weight‐normal" th:text="#{login.tip}">Please sign
in</h1>
<label class="sr‐only" th:text="#{login.username}">Username</label>
<input type="text" class="form‐control" placeholder="Username" th:placeholder="#
{login.username}" required="" autofocus="">
<label class="sr‐only" th:text="#{login.password}">Password</label>
<input type="password" class="form‐control" placeholder="Password"
th:placeholder="#{login.password}" required="">
<div class="checkbox mb‐3">
<label>
<input type="checkbox" value="remember‐me"/> [[#{login.remember}]]
</label>
</div>
<button class="btn btn‐lg btn‐primary btn‐block" type="submit" th:text="#
{login.btn}">Sign in</button>
<p class="mt‐5 mb‐3 text‐muted">© 2017‐2018</p>
<a class="btn btn‐sm">中文</a>
<a class="btn btn‐sm">English</a>
</form>
</body>
</html>
/**
* 区域信息解析器
* 可以连接上携带区域信息
* 根据传递的信息,显示中文登录界面或者是英文的登录界面
*/
public class MyLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
String l = request.getParameter("l");
Locale locale = Locale.getDefault(); //没参数就说那个默认的
if(!StringUtils.isEmpty(l)){
String[] split = l.split("_");
locale = new Locale(split[0],split[1]); //带了参数就使用请求头的
}
return locale;
}
@Override
public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
}
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
}
3)登录
开发期间模板引擎页面修改以后,要实时生效
4)拦截器进行登录检验
拦截器:
/**
* 登录拦截器,对登录进行检查
*/
public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object user = request.getSession().getAttribute("loginuser");
if(user == null){
//用户没用登录
//转发到登录页面
request.setAttribute("msg","你没有权限进行访问!");
request.getRequestDispatcher("/login.html").forward(request,response);
return false;
}else{
//已经登录,放行
return true;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
获取登录的用户,HttpSession 向保存登录用户
注册拦截器:
@Configuration public class MyMvcConfig extends WebMvcConfigurerAdapter { @Override public void addViewControllers(ViewControllerRegistry registry) { // super.addViewControllers(registry); //浏览器发送 /nnnd请求到success页面 registry.addViewController("/nnnd").setViewName("success"); } //所有的WebMvcConfigurerAdapter组件会一起起作用 @Bean //将组件注册到容器中 public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){ WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter(){ @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("login"); registry.addViewController("/login.html").setViewName("login"); registry.addViewController("/main.html").setViewName("logSuccess"); } //注册拦截器 @Override public void addInterceptors(InterceptorRegistry registry) { // super.addInterceptors(registry); registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**") .excludePathPatterns("/","/login.html","/user/login"); /** * 静态资源 *.css *.js 等 * SpringBoot已经做好了静态资源的映射 */ } }; return adapter; } @Bean public LocaleResolver localeResolver(){ return new MyLocaleResolver(); } }
注:访问资源时,出现解析什么*.html文件错误,往往都是前台的错误,和后台代码没什么关系!
5)CRUD员工列表
员工添加 @PostMapping(“/****”)进行添加操作:
首先实现页面跳转,点击员工添加后跳转到一个员工添加的form表单(BootStrap表单);
添加员工信息的部门选项,应该从已有的部门显示部门名称(使用Model传递数据),然后
在前台遍历显示部门名称信息,实际添加的部门的id号;
在控制层编写添加实现方法:
/**
* 首现来到添加页面,请求的方式为get,而添加信息的方式是post请求
* @param model
* @return
*/
@GetMapping("/emp")
public String toAdd(Model model){
/**
* 添加信息时,部门信息要能够回显
*/
Collection<Department> departments = departmentDao.getDepartments(); //ctrl+alt+v生成返回值对象或集合
model.addAttribute("depts",departments);
return "emp/add";
}
/**
* 员工添加
* SpringMVC自动将请求参数和入参对象的属性进行一一绑定;
* 要求请求参数的名字和JavaBean入参的对象里面的属性名一样
* @param employee
* @return
*/
@PostMapping("/emp")
public String addEmp(Employee employee){
//来到源列表页面
System.out.println("将要保存的信息:"+employee);
employeeDao.save(employee);
return "redirect:/emps";//添加完后,重定向到信息页面,展示添加的信息
}
在add页面中将添加的数据传送到后台
SpringMVC自动将请求参数和入参对象的属性进行一一绑定,要求请求参数的名字和JavaBean入参的对象里面的属性名一样
日期格式:
修改员工信息 @PutMapping("/emp")执行修改操作:
修改员工信息的页面和添加员工信息的页面二合一,根据请求方法时,员工是否为空显示不同的情况;
<button type="submit" class="btn btn-primary" th:text="${emp!=null}?'修改':'添加'">添加</button>默认显示为添加操作,当员工不是空的时候,则为修改操作。
后台控制层:
首先进行修改请求,跳转到修改页面;要将待修改的员工信息以及所有的部门信息回显到页面中;
@GetMapping("/emp/{id}") public String toEditPage(@PathVariable("id") Integer id,Model model){ Employee employee = employeeDao.get(id); Collection<Department> departments = departmentDao.getDepartments(); model.addAttribute("emp",employee); model.addAttribute("depts",departments); //回到修改页面(add是一个修改添加二合一的页面) return "emp/add"; } @PutMapping("/emp") public String updateEmp(Employee employee){ System.out.println("修改的员工信息:"+employee); employeeDao.save(employee); return "redirect:/emps"; }
来到修改页面,要回显原信息
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4"> <!--需要区分是员工修改还是添加;--> <form th:action="@{/emp}" method="post"> <!--发送put请求修改员工数据--> <!-- 1、SpringMVC中配置HiddenHttpMethodFilter;(SpringBoot自动配置好的) 2、页面创建一个post表单 3、创建一个input项,name="_method";值就是我们指定的请求方式 --> <input type="hidden" name="_method" value="put" th:if="${emp!=null}"/> <input type="hidden" name="id" th:if="${emp!=null}" th:value="${emp.id}"> <div class="form-group"> <label>LastName</label> <input name="lastName" type="text" class="form-control" placeholder="请输入姓名" th:value="${emp!=null}?${emp.lastName}"> </div> <div class="form-group"> <label>Email</label> <input name="email" type="email" class="form-control" placeholder="请输入Email" th:value="${emp!=null}?${emp.email}">回显时进行判断 </div> <div class="form-group"> <label>Gender</label><br/> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="gender" value="1" th:checked="${emp!=null}?${emp.gender==1}"> <label class="form-check-label">男</label> </div> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="gender" value="0" th:checked="${emp!=null}?${emp.gender==0}"> <label class="form-check-label">女</label> </div> </div> <div class="form-group"> <label>department</label> <!--提交的是部门的id--> <select class="form-control" name="department.id"> <option th:selected="${emp!=null}?${dept.id == emp.department.id}" th:value="${dept.id}" th:each="dept:${depts}" th:text="${dept.departmentName}">1</option> </select> </div> <div class="form-group"> <label>Birth</label> <input name="birth" type="text" class="form-control" placeholder="请输入yyyy-MM-dd格式的日期" th:value="${emp!=null}?${#dates.format(emp.birth, 'yyyy-MM-dd HH:mm')}"> </div> <button type="submit" class="btn btn-primary" th:text="${emp!=null}?'修改':'添加'">添加</button> </form> </main>
删除员工信息 @DeleteMapping("/emp/{id}"):
执行删除操作,将待删除的信息的id传递到后台,根据id进行删除操作;
/**
* 删除员工信息
* @param id
* @return
*/
@DeleteMapping("/emp/{id}")
public String delEmp(@PathVariable("id") Integer id){
employeeDao.delete(id);
return "redirect:/emps";
}