------web 开发登录功能------

  修改login.html文件:注意加粗部分为 msg 字符串不为空时候 才进行显示

<!DOCTYPE html>
<!-- saved from url=(0050)http://getbootstrap.com/docs/4.0/examples/sign-in/ -->
<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="">
<link rel="icon" href="http://getbootstrap.com/favicon.ico"> <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" th:action="@{/user/login}" method="post">
<img class="mb-4" src="/asserts/img/bootstrap-solid.svg" th: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>
<p style="color: red;" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
<label for="username" class="sr-only" th:text="#{login.username}">Email address</label>
<input name="username" type="email" id="username" th:placeholder="#{login.username}" class="form-control" placeholder="Email address" required="" autofocus="">
<label for="inputPassword" th:text="#{login.password}" class="sr-only">Password</label>
<input name="password" type="password" th:placeholder="#{login.password}" id="inputPassword" class="form-control" placeholder="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" th:href="@{/index.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>
</form>
</body></html>

  添加一个controller 对应页面跳转

package com.lixuchun.springboot.controller;

import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam; import java.util.Map; @Controller
public class LoginController { // @RequestMapping(value = "/user/login", method = RequestMethod.POST)
@PostMapping(value = "/user/login")
public String login(@RequestParam String username, @RequestParam String password
,Map<String, Object> map) {
if (!StringUtils.isEmpty(username) && "123456".equals(password)) {
// 登录成功
return "dashboard";
} else {
map.put("msg", "用户登录失败!");
// 登录失败
return "login";
}
}
}

  实现效果:填写正确情况下跳转到 dashboard.html页面中,错误情况下 返回login页面 并且显示 用户登录失败!

  登录 开发期间模板引擎页面修改以后要实时生效

    禁用模板引擎缓存:spring.thymeleaf.cache=false

    修改页面完成以后 ctrl + f9 重新编译

  当页面位于 dashboard 页面 按 F5 会有是否表单再次提交提示 (表单重复提交)

    可以进行重定向防止重复提交

     if (!StringUtils.isEmpty(username) && "123456".equals(password)) {
// 登录成功
// 防止表单从夫提交 可以从定向导主页
return "redirect:/main.html";
} else {
map.put("msg", "用户登录失败!");
// 登录失败
return "login";
}

    修改Mvc View视图解析器

    @Bean
public WebMvcConfigurerAdapter webMvcConfigurerAdapter() {
WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("login");
registry.addViewController("/index.html").setViewName("login");
registry.addViewController("/main.html").setViewName("dashboard");
}
};
return adapter;
}

  如果这样修改了 直接访问 localhost:8080/main.html 就可以直接访问 登录功能没起到作用 那么引入拦截器

  拦截器 编写拦截器controller 必须实现 HandlerInterceptor

  pre 在登录之前进行检查:

package com.lixuchun.springboot.component;

import org.springframework.lang.Nullable;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* 进行登录检查
*/
public class LoginHandlerIntercepter 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", "没有用户权限 请先登录");
       // 没有登录跳转到 /index.html 页面
request.getRequestDispatcher("/index.html").forward(request, response);
return false;
} else {
// 已经登录 放行请求
return true;
}
} @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { }
}

  Mvc 配置文件添加 Interceptor 组件 进行注册:

    @Bean
public WebMvcConfigurerAdapter webMvcConfigurerAdapter() {
WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("login");
registry.addViewController("/index.html").setViewName("login");
registry.addViewController("/main.html").setViewName("dashboard");
} // 注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 拦截任意请求
// 已经做好了静态资源的映射 *.css *.js 访问等 不需要做处理
registry.addInterceptor(new LoginHandlerIntercepter()).addPathPatterns("/**")
.excludePathPatterns("/index.html", "/", "/user/login");
}
};
return adapter;
}

  访问效果:在没有登录的情况下 访问 localhost:8080/main.html

  登录后再次访问:左侧上面 test@test.com 为登录名称 dashboard 页面 [[${session.loginUser}]] 行内表达式取值

  CRUD-员工列表

  实验要求:

    1) RestfulCRUD: CRUD 满足Rest风格

    URI : /资源名称/资源标识  HTTP请求方式区分对资源的CRUD操作

       /emp/{id}

    

    2). 实验的请求架构

    

    

    3).员工列表

      抽取公共元素片段

        <div th:fragment="copy">&COPY 2011 thymes Virtual Grocery</div>

      引入公共元素片段

        <div th:insert="~{footer::copy}"></div>

        ~{templatename::selector} :模板名 :: 选择器

        ~{templatename::fragmentname}:模板名::片段名

      三种引入公共片段th属性:

        th:insert :将公共的片段整个插入到声明引用的div中

        th:replace: 将声明引入的元素替换为公共片段

        th:include:被引入的片段内容包含近这个标签中

        如果使用th:insert 等属性进行引入 可以不用写 ~{}

        行内写法加上 [[~{}]] , [(~{})] (转义不转义)

      dashboard 页面定义公共片段头 th:fragment="topbar"

<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0" th:fragment="topbar">
<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">[[${session.loginUser}]]</a>
<input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
<ul class="navbar-nav px-3">
<li class="nav-item text-nowrap">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">Sign out</a>
</li>
</ul>
</nav>

      list 页面头取法

<!-- 引入抽取的topbar -->
<!-- 模板名称:使用thymeleaf的配置规则进行解析 -->
<div th:replace="~{dashboard::topbar}"></div>

      dashboard 页面定义公共片段侧边栏 id="sideBar"

    <nav id="sideBar" class="col-md-2 d-none d-md-block bg-light sidebar" style="margin-top: 50px;">
<div class="sidebar-sticky">
<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link active" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-home"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg>
Dashboard <span class="sr-only">(current)</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file"><path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline></svg>
Orders
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shopping-cart"><circle cx="9" cy="21" r="1"></circle><circle cx="20" cy="21" r="1"></circle><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path></svg>
Products
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" th:href="@{/emps}">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-users"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M23 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg>
员工管理
</a>
</li>
</ul>
</div>
</nav>

      list 页面侧边栏取法

<!-- 引入侧边栏 -->
<div th:replace="~{dashboard::#sideBar}"></div>

    也可以单独提出一个bar文件 然后在各个页面进行调用

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- top bar -->
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0" th:fragment="topbar">
<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">[[${session.loginUser}]]</a>
<input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
<ul class="navbar-nav px-3">
<li class="nav-item text-nowrap">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">Sign out</a>
</li>
</ul>
</nav> <!-- side bar -->
<nav id="sideBar" class="col-md-2 d-none d-md-block bg-light sidebar" style="margin-top: 50px;">
<div class="sidebar-sticky">
<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-shopping-cart"><circle cx="9" cy="21" r="1"></circle><circle cx="20" cy="21" r="1"></circle><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path></svg>
Products
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" th:href="@{/emps}">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-users"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M23 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg>
员工管理
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-layers"><polygon points="12 2 2 7 12 12 22 7 12 2"></polygon><polyline points="2 17 12 22 22 17"></polyline><polyline points="2 12 12 17 22 12"></polyline></svg>
Integrations
</a>
</li>
</ul>
</div>
</nav>
</body>
</html>

    页面进行调用 list 页面 效果和之前的效果一样

<!-- 引入抽取的topbar -->
<!-- 模板名称:使用thymeleaf的配置规则进行解析 -->
<div th:replace="commons/bar::topbar"></div>
<!-- 引入侧边栏 -->
<div th:replace="commons/bar::#sideBar"></div>

    

  引入片段也可以传入参数:

    在 dashboard.html 页面引入左侧栏时候 传入参数

<div th:replace="commons/bar::#sideBar(activeUri='main.html')"></div>

    在 bar.html 页面设置左侧栏时候 通过传过来的参数设置 是否高亮

<li class="nav-item">
  <a class="nav-link active" href="#"
  th:href="@{/main.html}" th:class="${activeUri=='main.html'?'nav-link active':'nav-link'}">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-home"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg>
  Dashboard <span class="sr-only">(current)</span>
</a>
</li>

   

  员工列表做数据展示:

  list.html 页面编写

    <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
      <div class="chartjs-size-monitor" style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px; overflow: hidden; pointer-events: none; visibility: hidden; z-index: -1;">
        <div class="chartjs-size-monitor-expand" style="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;">
        <div style="position:absolute;width:1000000px;height:1000000px;left:0;top:0"></div>
        </div>
          <div class="chartjs-size-monitor-shrink" style="position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;">
            <div style="position:absolute;width:200%;height:200%;left:0; top:0">
          </div>
        </div>
      </div>
<h2><button class="btn btn-sm btn-success">员工添加</button></h2>
<h2>Section title</h2>
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th>#</th>
<th>lastName</th>
<th>email</th>
<th>gender</th>
<th>department</th>
<th>birth</th>
<th>options</th>
</tr>
</thead>
<tbody>
<tr th:each="emp:${emps}">
<td th:text="${emp.id}"></td>
<td>[[${emp.lastName}]]</td>
<td th:text="${emp.email}"></td>
<td th:text="${emp.gender}==0?'girl':'boy'"></td>
<td th:text="${emp.department.departmentName}"></td>
<td th:text="${#dates.format(emp.birth, 'yyyy-MM-dd HH:mm')}"></td>
<td>
<button class="btn btn-sm btn-primary">编辑员工</button>
<button class="btn btn-sm btn-danger">删除员工</button>
</td>
</tr>
</tbody>
</table>
</div>
</main>

  做一个伪处理 employeeDao

package com.lixuchun.springboot.dao;

import com.lixuchun.springboot.entities.Department;
import com.lixuchun.springboot.entities.Employee;
import org.springframework.stereotype.Repository; import java.util.ArrayList;
import java.util.Date;
import java.util.List; @Repository
public class EmployeeDao {
public Employee selectEmpById(Integer id) {
return new Employee();
} public List<Employee> selectEmps() {
List<Employee> empList = new ArrayList<Employee>();
for (int i = 0; i < 6; i++) {
Employee emp = new Employee(i, "emp" + i,
i + "emp@emp.com", 0,
new Department(i, "dep"+ i), new Date());
empList.add(emp);
}
return empList;
}
}

  employee / department

department
private Integer id;
private String departmentName; employee
id
lastName
email
gender
department
birth

  EmpController 编写

    @Autowired
EmployeeDao employeeDao; // 查询所有员工返回列表页面
@GetMapping("/emps")
public String list(Model model) {
List<Employee> employees = employeeDao.selectEmps();
model.addAttribute("emps", employees);
// classpath:/templates/xxx.html
return "emp/list";
}

  最后页面效果:

  员工添加功能:

    list 添加按钮  <a class="btn btn-sm btn-success" href="emp" th:href="@{/emp}">员工添加</a>

    emp get 请求到员工添加页面

    emp post 添加员工

  

  其中部门为后台查出来的,前后台处理

<select class="form-control">
<option th:value="${dept.id}" th:each="dept:${depts}" th:text="dept.departmentName"></option>
</select>

  点击添加按钮 post 到 emp为添加功能

<form ah:action="@{/emp}" method="post">

  员工添加controller

  修改日期格式:spring.mvc.date-format=yyyy-MM-dd

  员工修改:emp/id ------->get 方式

<a class="btn btn-sm btn-primary" th:href="@{/emp/} + ${emp.id}">编辑员工</a>

  页面需要回显:

    th:value="${emp!=null}?${emp.lastName}">

    th:checked="${emp!=null}?${emp.gender==1}" / gender==0

    th:selected="${emp!=null}?${dept.id==emp.department.id}"

  如何发送put请求,到员工修改controller

  删除:delete请求

  出现了按钮换行 因为 form的添加 所以进行修改

  设置按钮del_uri

    button 设置 :th:attr="del_uri=@{emp/} + ${emp.id}"

    form 设置:id="deleteEmpForm"

  最后效果:

spring boot 尚桂谷学习笔记05 ---Web的更多相关文章

  1. spring boot 尚桂谷学习笔记04 ---Web开始

    ------web开发------ 1.创建spring boot 应用 选中我们需要的模块 2.spring boot 已经默认将这些场景配置好了 @EnableAutoConfiguration ...

  2. spring boot 尚桂谷学习笔记10 数据访问02 mybatis

    数据访问 mybatis 创建一个 springboot 工程,模块选择 sql 中 mysql(数据驱动), jdbc(自动配置数据源), mybatis Web模块中选择 web pom 引入: ...

  3. spring boot 尚桂谷学习笔记11 数据访问03 JPA

    整合JPA SpringData 程序数据交互结构图 (springdata jpa 默认使用 hibernate 进行封装) 使用之后就关注于 SpringData 不用再花多经历关注具体各个交互框 ...

  4. spring boot 尚桂谷学习笔记09 数据访问

    springboot 与数据库访问 jdbc, mybatis, spring data jpa,  1.jdbc原生访问 新建项目 使用 springboot 快速构建工具 选中 web 组件 sq ...

  5. spring boot 尚桂谷学习笔记07 嵌入式容器 ---Web

    ------配置嵌入式servlet容器------ springboot 默认使用的是嵌入的Servlet(tomcat)容器 问题? 1)如何定制修改Servlet容器的相关配置: 1.修改和se ...

  6. spring boot 尚桂谷学习笔记08 Docker ---Web

    ------Docker------ 简介:Docker是一个开元的应用容器引擎,性能非常高 已经安装好的软件打包成一个镜像放到服务器中运行镜像 MySQL容器,Redis容器...... Docke ...

  7. spring boot 尚桂谷学习笔记06 异常处理 ---Web

    ------错误处理机制------ 默认效果 1 返回一个默认的错误页面 浏览器发送请求的请求头:优先接收 text/html 数据 客户端则默认响应json数据 : accept 没有说明返回什么 ...

  8. springboot 尚桂谷学习笔记03

    ------spring boot 与日志------ 日志框架: 市面上的日志框架: jul jcl jboss-logging logback log4j log4j2 ...... 左边一个门面 ...

  9. Spring实战第六章学习笔记————渲染Web视图

    Spring实战第六章学习笔记----渲染Web视图 理解视图解析 在之前所编写的控制器方法都没有直接产生浏览器所需的HTML.这些方法只是将一些数据传入到模型中然后再将模型传递给一个用来渲染的视图. ...

随机推荐

  1. 6、numpy——高级索引

    NumPy 比一般的 Python 序列提供更多的索引方式.除了之前看到的用整数和切片的索引外,数组可以由整数数组索引.布尔索引及花式索引. 1.整数数组索引 1.1 以下实例获取数组中(0,0),( ...

  2. Codeforces 770C Online Courses In BSU (DFS)

    <题目链接> 题目大意:给定$n$个任务,其中有$m$个主线任务,然后$n$个任务中,每个任务都有可能有一个list,表示完成这个任务之前必须要完成的任务,然后现在让你找出,完成这$m$个 ...

  3. JVM(10)之 年老代收集器

    开发十年,就只剩下这套架构体系了! >>>   在上一篇博文我们介绍了JAVA新生代收集器,本篇博文我们要讲的就是关于老年代的一些收集器.老年代存活的一般是大对象以及生命很顽强的对象 ...

  4. 20180105-Python中dict的使用方法

    字典是Python中常用的内置数据类型之一. 字典是无序的对象集合,只能通过key-value的方式存取数据,字典是一种映射类型,其次key的必须是可hash的不可变类型.字典中的key必须唯一. 1 ...

  5. Linux知识-不断更新2

    为了自己看的更清楚,也为了不断的总结,每次更新后都会另发一篇. 工作中遇到某一文件夹磁盘空间不够,当然每次都是清理日志,最后发现还是不太行,还不能扩容,只能先想办法迁移目录,避免此问题发生,但在这之前 ...

  6. 93-基于ATOM E3825的3U PXIe 主板控制器

    基于ATOM E3825的3U PXIe 主板控制器 一.板卡概述: 本主板采用intel ATOM 处理器 E3825 设计主板控制器,是一种低成本.低功耗解决方案.板卡采用Intel Bay Tr ...

  7. weblogic启动脚本

    DATE=`date +%Y%m%d%H%M%S` user=`whoami` logDir=/app/logs/sguap_admin #启动日志存放路径sguap是例子系统简称# logDestd ...

  8. 1、pip不是内部运行程序 解决方法

    一.方式一 1.切换到pip所在路径: shit+ 右键. 再此处打开运行窗口 2.执行 pip install pytest 脚本即可. 二.方式二,添加环境变量 1.将pip所在的文件路径 添加到 ...

  9. python在mapreduce运行Wordcount程序

    首先脚本文件: mapper.py: #!/usr/bin/env python import sys for line in sys.stdin: line = line.strip() words ...

  10. Spring----组合注解与元注解

    1.概述 1.1.Spring提供了大量的注解, 尤其是相同的注解用到各个类中,会相当的啰嗦: 1.2.元注解: 可以注解到别的注解上的注解: 组合注解: 被注解注解的注解称为 组合注解: 组合注解  ...