Java开发SpringBoot开发(狂神说Java)

Posted A1oe

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java开发SpringBoot开发(狂神说Java)相关的知识,希望对你有一定的参考价值。

Java SpringBoot 开发学习(狂神说Java)

SpringBoot概述

Spring

  • Spring开源框架(容器),简化开发

  • 4种策略:

  • 1.基于POJO的轻量级和最小侵入性编程

  • 2.通过IOC,依赖注入(DI)和面向接口实现松耦合

  • 3.基于切面(AOP)和惯例进行声明式变成

  • 4.通过切面和模板减少样式代码

SpringBoot的核心思想:约定大于配置

微服务

  • 微服务是一种架构风格。MVC三层架构,MVMM,微服务架构。

  • 业务=>模块,把每个功能独立出来,吧独立出来的功能元素动态组合

SpringBoot程序

安装

jdk1.8,maven3.6.1,springboot,IDEA

  • 直接官网下载,import

  • IDEA直接创建

测试

  • Application程序主入口,application.properties核心配置文件

  • Application同级目录建立controller进行测试(访问locahost:8080/hello/hello)

  • Maven-Lifecycle-package打成jar包,java -jar xxx.jar运行服务

配置文件

  • 端口号修改 server.port=8081

  • 修改log:配置文件同目录创建banner.txt,从springboot banner等创建粘贴

原理

自动配置

步骤

  • springboot在启动的时候,从类路径下/META-INF/spring.factories获取指定的值

  • 将这些自动配置的类导入容器,自动配置就会生效,帮我进行自动配置

  • 以前需要自动配置的东西,sprintboot做了

  • 整个javaEE,解决方案和自动配置的东西都在sprint-bbot-autoconfigure-version.jar这个包下

  • 它会把所有需要导入的组件,以类名的方式返回,这些组件就会被添加到容器

  • 容器中也会存在非常多的xxxxAutoConfiguration,就是这些类给容器中导入了这个场景需要的所有组件,并自动配置

  • 有了自动配置类,免去了手动编写配置文件的工作

sprintboot所有的自动配置都在启动类种扫描并加载:sprint.factories所有的自动配置类都在这里,但是不一定生效,要判断条件是否成立。只要导入了对应的start,就有对应的启动器了,有了启动器,我们自动装配就会生效,然后就配置成功了。

  • springboot dependecies: 核心依赖在父工程中

  • 写或者引入Sprintboot依赖时,不需要指定版本,因为有这些版本仓库

启动器

  • <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    
  • sprintboot将所有功能场景都变成一个个的启动器

  • 官网可以寻找需要使用的starter

主程序

  • SpringBootApplication 标注类是一个springboot的应用,启动类下的所有资源被导入

  • SpringApplication.run(SpringbootHelloworldApplication.class, args);将springboot启动

  • @SprintBootConfiguration: sprintboot配置
        @Configuration: sprint配置类
        @component:  一个sprint组件
    @EnableAutoConfiguration:自动配置
        @AutoConfigurationPackage: 自动配置包
            @Import(AutoConfigurationPackages.Registrar.class) :自动配置 包注册
        @Import(AutoConfigurationImpoSelector.class): 自动配置导入选择
    

主启动类

SpringApplication

  • 1.推断应用的类型时普通的项目还是web项目

  • 2.查找并加载所有可用初始化器,设置到initializers属性中

  • 3.找出所有的应用程序监听器,设置到listeners属性中

  • 4.推断并设置main方法的定义类,找到运行的主类

yaml语法

官方文档:https://docs.spring.io/spring-boot/docs/2.6.11/reference/htmlsingle/#using.build-systems.starters

  • 删除默认配置文件,新建application.yaml

  • 语法: key: 空格 value

  • server:
      port: 8081
    //2
    server: port: 8081, xxx: yyy
    //3
    server:
        - port
        - xxx
    

给属性赋值的几种方式

  • @Value("xxx"),测试时用@Autowired自动装配,才能使用private Dog dog;

  • yaml可用直接给实体类赋值,实体类使用@ConfigurationProperties(perfix = "person")。 松散绑定last-name和lastName一样的。 原理是通过set方法实现

person:
    name: A1oe
    age: 3
    lists:
        - code
        - music
    dog:
        name: "旺财"
  • properties,@propertySource(value = "classpath:A1oe.properties") => @Value("$name") SPEL表达式

JR303校验

  • 类上面@Validated

  • 属性上面@Email(message="xxx") 等

多环境配置及配置文件位置

springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件:(优先级从上到下)

1.当前目录
  1.当前目录中的/config子目录
  2.当前目录
2.类路径
  1.类路径/config直接子目录
  2.类路径

多环境切换(yaml使用"---"进行分割)

  • 在主配置文件编写的时候,文件名可以是 application-profile.properties/yml , 用来指定多个环境版本;如:application-test.yml:代表测试环境配置、application-dev.yml:代表开发环境配置

  • Springboot并不会直接启动这些配置文件,它默认使用application.properties主配置文件,如果没有就会找application.yml。

  • 需要通过一个配置来选择需要激活的环境

spring:
  profiles:
    active: dev #使用开发环境。

SpringBoot Web开发理论

  • xxxAutoConfiguration: 向容器中自动配置文件

  • xxxProperties: 自动配置类,装配配置文件中自定义的一些内容

解决的问题:

  • 导入静态资源

  • 首页

  • jsp,模板引擎Thymeleaf

  • 装配扩展SpringMVC

  • 增删改查数据库

  • 拦截器

  • 国际化

静态资源

  • 默认情况下,Spring Boot 从类路径中的/static (或/public 或/resources 或/META-INF/resources)目录或 ServletContext的根目录提供静态内容。

  • 优先级:resources>static>public

  • 一般static放静态资源,resources放上传的文件,public放公共访问的资源

首页

首页

  • index.html放静态资源下可直接访问,但是一般使用controller跳转

  • 在templates目录下的所有页面,只能通过controller来跳转

图标

模板引擎

导入themyleaf依赖,刷新Maven

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

ThymeleafProperties.java查看目录,解析templates下的.html文件

templates目录创建test.html,使用IndexController调用。访问localhost:8080/test,显示页面

package com.example.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class IndexController 
    @RequestMapping("/test")
    public String test()
        return "test";
    

Thymeleaf使用文档:https://www.thymeleaf.org/doc/tutorials/3.1/usingthymeleaf.html

Variable Expressions: $...
Selection Variable Expressions: *...
Message Expressions: #...
Link URL Expressions: @...
Fragment Expressions: ~...

所有的html元素都可以被thymeleaf替换接管: th:元素名。

在/test路由显示hello springboot

package com.example.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class IndexController 
    @RequestMapping("/test")
    public String test(Model model)
        model.addAttribute("msg","hello springboot");
        return "test";
    

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div th:text="$msg"></div>

</body>
</html>

Thymeleaf语法

Thymeleaf使用文档:https://www.thymeleaf.org/doc/tutorials/3.1/usingthymeleaf.html

例子:遍历users,使用each

package com.example.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.Arrays;

@Controller
public class IndexController 
    @RequestMapping("/test")
    public String test(Model model)
        model.addAttribute("msg","hello springboot");
        model.addAttribute("users", Arrays.asList("AAA","BBB"));
        return "test";
    

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h3 th:each="user:$users" th:text="$user"></h3>
<h3 th:each="user:$users">[[ $user ]]</h3>
</body>
</html>

MVC配置原理,扩展SpringMVC

Spring Boot官方文档[Web](https://springdoc.cn/spring-boot/web.html#web.servlet.spring-mvc.auto-configuration)

如果你想保留那些Spring Boot MVC定制,并进行更多的 [MVC定制](https://docs.spring.io/spring-framework/docs/6.0.5/reference/html/web.html#mvc)(Interceptor、Formatter、视图控制器和其他功能),你可以添加你自己的 @Configuration 类,类型为 WebMvcConfigurer ,但 **不** 含 @EnableWebMvc

视图解析

config-MyMvcConfig.java下

package com.example.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.Locale;

@Configuration
public class MyMvcConfig implements WebMvcConfigurer 
    
    @Bean
    public ViewResolver myViewResolver()
        return new MyViewResolver()
    
    
    public static class MyViewResolver implements ViewResolver
        @Override
        public View resolveViewName(String viewName, Locale locale) throws Exception 
            return null;
        
    

视图跳转

addViewControllers,将/a1oe跳转到/test

package com.example.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyMvcConfig implements WebMvcConfigurer 
    @Override
    public void addViewControllers(ViewControllerRegistry registry) 
        registry.addViewController("/a1oe").setViewName("test");
    

结论:springboot中,有很多xxxx Configuration 帮助我们进行扩展配置,看见了需要注意。

员工管理系统(基于Spring Boot)

准备工作

BootStrap模板下载:[bootstrap模板 bootstrap模板免费下载](https://sc.chinaz.com/tag_moban/bootstrap.html)

页面放templates,资源放static(静态资源找不到的话可以私信找我要)。

建立部门信息表和员工信息表,需要引入依赖lombok

  • Department.java

  • Employee.java

package com.example.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

//部门表
@Data
@AllArgsConstructor // 有参
@NoArgsConstructor // 无参
public class Department 
    private Integer id;
    private String departmentName;

package com.example.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

//员工表
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee 
    private Integer id;
    private String lastName;
    private String email;
    private Integer gender; // 0女 1男;
    private Department department;
    private Date birth;

    public Employee(Integer id, String lastName, String email, Integer gender, Department department) 
        this.id = id;
        this.lastName = lastName;
        this.email = email;
        this.gender = gender;
        this.department = department;
        //默认的创建日期
        this.birth = new Date();
    


Da层模拟数据库

  • DepartmentDao

  • EmployeeDao

package com.example.dao;

import com.example.pojo.Department;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

//部门Dao
@Repository
public class DepartmentDao 
    //模拟数据库数据
    private static Map<Integer, Department> departments = null;
    static 
        departments = new HashMap<Integer, Department>();  //创建一个部门表
        departments.put(101, new Department(101,"教学部"));
        departments.put(102, new Department(102,"市场部"));
        departments.put(103, new Department(103,"教研部"));
        departments.put(104, new Department(104,"运营部"));
        departments.put(105, new Department(105,"后勤部"));
    

    //获得所有部门信息
    public Collection<Department> getDepartments() 
        return departments.values();
    

    //通过id得到部门
    public Department getDepartmentById(Integer id)
        return departments.get(id);
    

package com.example.dao;

import com.example.pojo.Department;
import com.example.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,"AA","A123456@qq.com",1,new Department(101,"教学部")));
        employees.put(1002,new Employee(1002,"BB","B123456@qq.com",0,new Department(102,"市场部")));
        employees.put(1003,new Employee(1003,"CC","C123456@qq.com",1,new Department(103,"教研部")));
        employees.put(1004,new Employee(1004,"DD","D123456@qq.com",0,new Department(104,"运营部")));
        employees.put(1005,new Employee(1005,"EE","E123456@qq.com",1,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 getEmploeeById(Integer id)
        return employees.get(id);
    
    //删除员工
    public void delete(Integer id)
        employees.remove(id);
    


首页实现

两种方式

  • IndexController,但不建议
@Controller
public class IndexController
    @RequestMapping("/","/index.html")
    public String index() 
        return "index";
    

  • config目录下的MyMvcConfig,重写addViewControllers接管
package com.example.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyMvcConfig implements WebMvcConfigurer 
    @Override
    public void addViewControllers(ViewControllerRegistry registry) 
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index.html").setViewName("index");
    

静态资源加载,修改html文件,使用thymeleaf接管,举例如下:

index.html中
<link th:href="@/css/bootstrap.min.css" rel="stylesheet">
<link th:href="@/css/signin.css" rel="stylesheet">
404.html,dashboard.html中
<script type="text/javascript" th:src="@/js/jquery-3.2.1.slim.min.js"></script>
<script type="text/javascript" th:src="@/js/popper.min.js"></script>
<script type="text/javascript" th:src="@/js/bootstrap.min.js"></script>

页面国际化

  • 确认IDEA设置中FIle Encoding的所有编码为UTF-8

  • resourcces下创建文件夹i18n目录(internationalization缩写),存放国际化配置文件

  • 创建配置文件login.properties和中文的login_zh_CN.properties(文件合并,自动创建一个下级目录)

  • 再使用新的方法在新的目录这上面去新建一个文件,再添加一个英文的

  • 可视化配置,点击Text旁边的Resource Bundle

  • 配置message路径,spring.messages.basename=i18n.login

  • Thymeleaf中使用#号转换国际化消息

  • 国际化解析器,LocaleResolver。写一个自己的LocaleResolver。思路就是点击中文或English时进行跳转,然后使用组件类进行处理。
<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>
package com.example.config;

import org.springframework.web.servlet.LocaleResolver;
import org.thymeleaf.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;

public class MyLocaleResolver implements LocaleResolver 
    //解析请求
    @Override
    public Locale resolveLocale(HttpServletRequest request) 
        //获取l参数
        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 request, HttpServletResponse response, Locale locale) 

    

为了让我们的类能够生效,需要再配置一下这个组件,在我们自己的MvcConofig下添加Bean

//自定义国际化生效
    @Bean
    public LocaleResolver localeResolver() 
        return new MyLocaleResolver();
    

登录功能

  • 首先需要修改登录页面的表单,修改请求地址、提交的参数和返回信息的输出
<form class="form-signin" th:action="@/user/login">
<p  th:text="$msg" th:if="$not #strings.isEmpty(msg)"></p>
<input type="text" name="username" class="form-control" th:placeholder="#login.username" required="" autofocus="">
<input type="password" name="password" class="form-control" th:placeholder="#login.password" required="">
  • 解决密码泄露问题:加一个main.html映射在MyMvcConfig中,然后再控制器中跳转到main.html
@Override
    public void addViewControllers(ViewControllerRegistry registry) 
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index.html").setViewName("index");
        registry.addViewController("/main.html").setViewName("dashboard");
    
if (!StringUtils.isEmpty(username) && "123456".equals(password))
            return "redirect:/main.html";
        

登录拦截器

  • 只有登录成功才能进main.html

  • 需要先给登录拥护session,再LoginController中添加

package com.example.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.thymeleaf.util.StringUtils;

import javax.servlet.http.HttpSession;

@Controller
public class LoginContoller 
    @RequestMapping("/user/login")
    public String login(@RequestParam("username") String username, @RequestParam("password") String password, Model model
    ,HttpSession session)
        //具体业务
        if (!StringUtils.isEmpty(username) && "123456".equals(password))
            session.setAttribute("loginUser",username);
            return "redirect:/main.html";
         else 
            model.addAttribute("msg","用户名或密码错误");
            return "index";
        
    

  • 然后在config中创建LoginHanlderInterceptor拦截器,实现HandlerInterceptor接口
package com.example.config;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginHandleInterceptor implements HandlerInterceptor 
    @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.getRequestDispatcher("/index.html").forward(request, response);
            return false;
         else
            return true;
        
    

  • 在MyMvcConfig中重写拦截器方法,添加我们的拦截器(需要排除某些页面和静态资源)
package com.example.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyMvcConfig implements WebMvcConfigurer 
    @Override
    public void addViewControllers(ViewControllerRegistry registry) 
        registry.addViewController("/").setViewName("index");
        registry.addViewController("/index.html").setViewName("index");
        registry.addViewController("/main.html").setViewName("dashboard");
    
    //自定义国际化生效
    @Bean
    public LocaleResolver localeResolver() 
        return new MyLocaleResolver();
    
    //添加拦截器

    @Override
    public void addInterceptors(InterceptorRegistry registry) 
        // 添加拦截路径,排除index.html路径
        registry.addInterceptor(new LoginHandleInterceptor()).addPathPatterns("/**").excludePathPatterns("/index.html","/",
        "/user/login","/css/*","/js/**","/img/**");
    

员工列表展示

  • list.html和dashboard.html中修改地址
<li class="nav-item">
    <a class="nav-link" th:href="@/emps">
  • 抽取公共部分代码(不重复造轮子),命名成组件
<!--顶部导航栏-->
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0" th:fragment="topbar">
    <!--...-->
</nav>

<!--侧边栏-->
<nav class="col-md-2 d-none d-md-block bg-light sidebar" th:fragment="sidebar">
   <!--...-->
</nav>
  • Thymeleaf的插入语法是th:insert="~",在list.html中插入公共部分代码
<!--顶部导航栏-->
<div th:insert="~dashboard::topbar"></div>


<!--侧边栏-->
<div th:insert="~dashboard::sidebar"></div>
  • 进一步:将公共部分代码存入commoms文件夹,并创建commons.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">

<!--头部导航栏-->
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0" th:fragment="topbar">
  ···
</nav>

<!--侧边栏-->
<nav class="col-md-2 d-none d-md-block bg-light sidebar" th:fragment="sidebar">
  ···
</nav>

</html>
  • 将dashboard.html和list.html代码的公共部分用commons.html的内容进行插入
<!--顶部导航栏-->
<div th:insert="~commons/commons::topbar"></div>

<!--侧边栏-->
<div th:insert="~commons/commons::sidebar"></div>
  • 侧边栏添加高亮,在dashboard.html和list.html页面侧边栏传参,参数在括号中
<div th:replace="~commons/commons::sidebar(active=\'list.html\')"></div>
  • 在commons.html中接受并判断是否使用active激活高亮
<a th:class="$active==\'main.html\'?\'nav-link active\':\'nav-link\'" th:href="@/main.html">
  • 循环显示th:each,删除list.html原始数据,再加入循环代码

    id lastName email gender department birth 操作
  • 添加编辑/删除工作

<td>
    <button class="btn btn-sm btn-primary">编辑</button>
    <button class="btn btn-sm btn-danger">删除</button>
</td>

添加员工

  • 按钮提交,跳转到添加页面,添加员工成功,返回首页
<div class="container-fluid">
			<div class="row">
				<div th:insert="~common/common::sidebar(active=\'list.html\')"></div>
  • 后台编写,点击添加,跳转到add.html页面
@GetMapping("/emp")
    public String toAddpage(Model model)
        //查出所有部门信息
        Collection<Department> departments = departmentDao.getDepartments();
        model.addAttribute("departments", departments);
        return "emp/add";
    
  • add.html,从bootstarp官网拉一个表单
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
      <form th:action="@/emp" method="post">
        <div class="form-group">
          <label>LastName</label>
          <input type="text" name="lastName" class="form-control" placeholder="A1oe">
        </div>
        <div class="form-group">
          <label>Email</label>
          <input type="email" name="email" class="form-control" placeholder="12345678@qq.com">
        </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">
            <label class="form-check-label">男</label>
          </div>
        </div>
        <div class="form-check form-check-inline">
          <input class="form-check-input" type="radio" name="gender" value="0">
          <label class="form-check-label">女</label>
        </div>
        <div class="form-group">
          <label>department</label>
          <select class="form-control" name="department.id">
            <option th:each="dept:$departments" th:text="$dept.getDepartmentName()" th:value="$dept.getId()">1</option>
          </select>
        </div>
        <div class="form-group">
          <label>Birth</label>
          <input type="text" name="birth" class="form-control" placeholder="2023/05/07 23:00:00">
        </div>
        <button type="submit" class="btn btn-primary">添加</button>
      </form>
    </main>
  • 后端接收post到/emp的数据
@Autowired
    DepartmentDao departmentDao;
@PostMapping("/emp")
    public String addEmp(Employee employee) 
        //添加的操作
        employeeDao.save(employee);
        return "redirect:/emps";
    

修改员工信息

  • 编辑按钮设置提交
<a class="btn btn-sm btn-primary" th:href="@/emp/+$emp.getId()">编辑</a>
  • 后台接收参数,并返回查询出的信息到update.html
//去员工修改页面
    @GetMapping("/emp/id")
    public String toUpdateEmp(@PathVariable("id") Integer id, Model model)
        //查出原来的数据
        Employee employee = employeeDao.getEmploeeById(id);
        model.addAttribute("emp", employee);
        //查出所有部门的信息
        Collection<Department> department = departmentDao.getDepartments();
        model.addAttribute("departments",department);
        return "emp/update";
    
  • 编写update.html
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
      <form th:action="@/updateEmp" method="post">
        <input type="hidden" name="id" th:value="$emp.getId()">
        <div class="form-group">
          <label>LastName</label>
          <input th:value="$emp.getLastName()" type="text" name="lastName" class="form-control" placeholder="A1oe">
        </div>
        <div class="form-group">
          <label>Email</label>
          <input th:value="$emp.getEmail()" type="email" name="email" class="form-control" placeholder="123@qq.com">
        </div>
        <div class="form-group">
          <label>Gender</label><br>
          <div class="form-check form-check-inline">
            <input th:checked="$emp.getGender()==1" class="form-check-input" type="radio" name="gender" value="1">
            <label class="form-check-label">男</label>
          </div>
        </div>
        <div class="form-check form-check-inline">
          <input th:checked="$emp.getGender()==0" class="form-check-input" type="radio" name="gender" value="0">
          <label class="form-check-label">女</label>
        </div>
        <div class="form-group">
          <label>department</label>
          <select class="form-control" name="department.id">
            <!--我们在controller接收的是一个Employee,所以我们需要提交的是其中的一个属性-->
            <option th:selected="$dept.getId()==emp.getDepartment().getId()" th:each="dept:$departments" th:text="$dept.getDepartmentName()" th:value="$dept.getId()"></option>
          </select>
        </div>
        <div class="form-group">
          <label>Birth</label>
          <input th:value="$#dates.format(emp.getBirth(),\'yyyy-MM-dd HH:mm:ss\')" type="text" name="birth" class="form-control" placeholder="2020-07-25 00:00:00">
        </div>
        <button type="submit" class="btn btn-primary">修改</button>
      </form>
    </main>
  • 添加更新路由功能
@PostMapping("/updateEmp")
    public String updateEmp(Employee employee) 
        employeeDao.save(employee);
        return "redirect:/emps";
    

删除及404处理

  • list.html添加删除按钮提交地址,注意a标签
<a class="btn btn-sm btn-danger" th:href="@/delemp/+$emp.getId()">删除</a>Controller后端控制
//删除员工
    @GetMapping("/delemp/id")
    public String deleteEmp(@PathVariable("id") Integer id)
        employeeDao.delete(id);
        return "redirect:/emps";
    
  • 404页面,templates文件下创建error文件夹,创建404.html,500.html

注销功能

  • commons.html中修改提交链接
<a class="nav-link" th:href="@/user/logout">注销</a>
  • LoginController实现注销功能
//注销
    @RequestMapping("/user/logout")
    public String logout(HttpSession session) 
        session.invalidate();
        return "redirect:/index.html";
    

如何写一个网站

  • 前端:页面张什么也昂子:数据

  • 设计数据库(难点)

  • 前端让他能自动运行,独立化工程

  • 数据接口如何对接:json,对象 all in one

  • 前后端联调测试

  • 有一套自己熟悉的后台模板:工作必要 x-admin

  • 前端界面:至少自己能够通过前端框架,组合出来一个网站页面

    • index,about,blog,post,user
  • 让这个网站独立运行

狂神说SpringBoot01:Hello,World!

狂神说SpringBoot系列连载课程,通俗易懂,基于SpringBoot2.2.5版本,欢迎各位狂粉转发关注学习。未经作者授权,禁止转载



SpringBoot简介


回顾什么是Spring

Spring是为了解决企业级应用开发的复杂性而创建的,简化开发。


Spring是如何简化Java开发的

为了降低Java开发的复杂性,Spring采用了以下4种关键策略:

1、基于POJO的轻量级和最小侵入性编程,所有东西都是bean;

2、通过IOC,依赖注入(DI)和面向接口实现松耦合;

3、基于切面(AOP)和惯例进行声明式编程;

4、通过切面和模版减少样式代码,RedisTemplate,xxxTemplate;

什么是SpringBoot

学过javaweb的同学就知道,开发一个web应用,从最初开始接触Servlet结合Tomcat, 跑出一个Hello Wolrld程序,是要经历特别多的步骤;后来就用了框架Struts,再后来是SpringMVC,到了现在的SpringBoot,过一两年又会有其他web框架出现;你们有经历过框架不断的演进,然后自己开发项目所有的技术也 不断的变化、改造吗?建议都可以去经历一遍;
言归正传,什么是SpringBoot呢,就是一个javaweb的开发框架,和SpringMVC类似,对比其他javaweb框架的好处,官方说是简化开发,约定大于配置,  you can "just run",能迅速的开发web应用,几行代码开发一个http接口。
所有的技术框架的发展似乎都遵循了一条主线规律:从一个复杂应用场景 衍生 一种规范框架,人们只需要进行各种配置而不需要自己去实现它,这时候强大的配置功能成了优点;发展到一定程度之后,人们根据实际生产应用情况,选取其中实用功能和设计精华,重构出一些轻量级的框架;之后为了提高开发效率,嫌弃原先的各类配置过于麻烦,于是开始提倡“约定大于配置”,进而衍生出一些一站式的解决方案。
是的这就是Java企业级应用->J2EE->spring->springboot的过程。
随着 Spring 不断的发展,涉及的领域越来越多,项目整合开发需要配合各种各样的文件,慢慢变得不那么易用简单,违背了最初的理念,甚至人称配置地狱。Spring Boot 正是在这样的一个背景下被抽象出来的开发框架,目的为了让大家更容易的使用 Spring 、更容易的集成各种常用的中间件、开源软件;
Spring Boot 基于 Spring 开发,Spirng Boot 本身并不提供 Spring 框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于 Spring 框架的应用程序。也就是说,它并不是用来替代 Spring 的解决方案,而是和 Spring 框架紧密结合用于提升 Spring 开发者体验的工具。Spring Boot 以 约定大于配置的核心思想 ,默认帮我们进行了很多设置,多数 Spring Boot 应用只需要很少的 Spring 配置。同时它集成了大量常用的第三方库配置(例如 Redis、MongoDB、Jpa、RabbitMQ、Quartz 等等),Spring Boot 应用中这些第三方库几乎可以零配置的开箱即用。
简单来说就是SpringBoot其实不是什么新的框架,它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,spring boot整合了所有的框架 。
Spring Boot 出生名门,从一开始就站在一个比较高的起点,又经过这几年的发展,生态足够完善,Spring Boot 已经当之无愧成为 Java 领域最热门的技术。

Spring Boot的主要优点:

  • 为所有Spring开发者更快的入门

  • 开箱即用,提供各种默认配置来简化项目配置

  • 内嵌式容器简化Web项目

  • 没有冗余代码生成和XML配置的要求

真的很爽,我们快速去体验开发个接口的感觉吧!




Hello,World


准备工作

我们将学习如何快速的创建一个Spring Boot应用,并且实现一个简单的Http请求处理。通过这个例子对Spring Boot有一个初步的了解,并体验其结构简单、开发快速的特性。

我的环境准备:

  • java version "1.8.0_181"

  • Maven-3.6.1

  • SpringBoot 2.x 最新版

开发工具:

  • IDEA

创建基础项目说明

Spring官方提供了非常方便的工具让我们快速构建应用

Spring Initializr:https://start.spring.io/

项目创建方式一:使用Spring Initializr 的 Web页面创建项目

1、打开  https://start.spring.io/

2、填写项目信息

3、点击”Generate Project“按钮生成项目;下载此项目

4、解压项目包,并用IDEA以Maven项目导入,一路下一步即可,直到项目导入完毕。

5、如果是第一次使用,可能速度会比较慢,包比较多、需要耐心等待一切就绪。


项目创建方式二:使用 IDEA 直接创建项目

1、创建一个新项目

2、选择spring initalizr , 可以看到默认就是去官网的快速构建工具那里实现

3、填写项目信息

4、选择初始化的组件(初学勾选 Web 即可)

5、填写项目路径

6、等待项目构建成功


项目结构分析:

通过上面步骤完成了基础项目的创建。就会自动生成以下文件。

1、程序的主启动类

2、一个 application.properties 配置文件

3、一个 测试类

4、一个 pom.xml


pom.xml 分析

打开pom.xml,看看Spring Boot项目的依赖:

<!-- 父依赖 --><parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.5.RELEASE</version> <relativePath/></parent>
<dependencies> <!-- web场景启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- springboot单元测试 --> <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>


编写一个http接口

1、在主程序的同级目录下,新建一个controller包,一定要在同级目录下,否则识别不到

2、在包中新建一个HelloController类

@RestControllerpublic class HelloController {
@RequestMapping("/hello") public String hello() { return "Hello World"; } }

3、编写完毕后,从主程序启动项目,浏览器发起请求,看页面返回;控制台输出了 Tomcat 访问的端口号!

狂神说SpringBoot01:Hello,World!


简单几步,就完成了一个web接口的开发,SpringBoot就是这么简单。所以我们常用它来建立我们的微服务项目!


将项目打成jar包,点击 maven的 package

狂神说SpringBoot01:Hello,World!

如果遇到以上错误,可以配置打包时 跳过项目运行测试用例

<!-- 在工作中,很多情况下我们打包是不想执行测试用例的 可能是测试用例不完事,或是测试用例会影响数据库数据 跳过测试用例执 --><plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <!--跳过项目运行测试用例--> <skipTests>true</skipTests> </configuration></plugin>

如果打包成功,则会在target目录下生成一个 jar 包

狂神说SpringBoot01:Hello,World!


打成了jar包后,就可以在任何地方运行了!OK


彩蛋


如何更改启动时显示的字符拼成的字母,SpringBoot呢?也就是 banner 图案;

只需一步:到项目下的 resources 目录下新建一个banner.txt 即可。

图案可以到:https://www.bootschool.net/ascii 这个网站生成,然后拷贝到文件中即可!

狂神说SpringBoot01:Hello,World!

SpringBoot这么简单的东西背后一定有故事,我们之后去进行一波源码分析!

开了赞赏,请这次一定!



以上是关于Java开发SpringBoot开发(狂神说Java)的主要内容,如果未能解决你的问题,请参考以下文章

狂神说Java

狂神说Java

狂神说JavaSpringBoot最新教程IDEA版通俗易懂

B站狂神说Java笔记-java方法

Java后端开发工程师学习笔记狂神说Java笔记

Java后端开发工程师学习笔记狂神说Java笔记