简单了解
自从 B/S 架构 (Browser/Server,浏览器/服务器模式) 被发明以来,因为其具有跨平台、 易移植、方便使用等特点,迅速地成为了技术架构的首选,前端 Web 技术迅速发展起来。人 们利用前端 Web 技术构建各种应用场景,如电子商务平台、在线聊天室、后台管理系统等。 页面技术也从最初的 JSP 演化为现在的模板引擎;信息交互由以前的 XML 发展到现在更流行 的 JSON;Spring IoC、Aop 等概念的发展更加方便人们构建 Web 系统。
Spring Boot 对 Web 开发的支持很全面,包括开发、测试和部署阶段都做了支持。 spring-boot-starter-web 是 Spring Boot 对 Web 开发提供支持的组件,主要包括 JSON、RESTful, 使用 Tomcat 作为内嵌容器等等功能。
快速上手
-
创建项目
-
在pom.xml文件中导入依赖
<!-- Spring Boot web 启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- MySQL 驱动,根据自己的MySQL版本而定 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.18</version> </dependency> <!-- Lombok 插件,支持生成 setter/getter --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- Mybatis-Plus 启动器 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.1.1</version> </dependency>
-
在application.properties中配置数据源
# 数据源
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/boot?useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456
完成以上步骤后之后 —> 创建实体类 —> 创建Dao层接口(需继承BaseMapper)—> 创建业务逻辑层 —> 测试
注: 需要在测试类上添加 @MapperScan(“com.ymq.demo”) 注解,用于扫描Mapper文件。
首先来编写一下最常用的增删改查(因为继承BaseMapper后会提供很多常用方法,所有就直接调用即可)
Service层(业务逻辑层)
public interface StudentService {
//查询全部
public List<Student> findByAll();
//新增
public Integer InsertByStudent(Student student);
//修改
public Integer UpdateByStudent(Student student);
//删除
public Integer DeleteByStuId(Integer stuId);
}
@Service
public class StudentServiceImpl implements StudentService {
@Resource
private StudentDao studentDao;
/**
* 查询全部:selectList(null),返回List集合类型
* 新增:insert(),参数为对象类型,返回int类型
* 删除:deleteById(),参数为id类型,返回int类型
* 修改:updateById(),参数为对象类型,返回int类型
*/
}
JSON 的支持
JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式,易于阅读和编写,同时也 易于机器解析和生成。JSON 采用完全独立于语言的文本格式,但是也使用了类似于 C 语言家 族的习惯(包括 C、C++、C#、Java、JavaScript、Perl、Python 等),这些特性使 JSON 成为理 想的数据交换语言。
早期人们习惯使用 XML 进行信息交互,后来 JSON 的使用更加简单,到了现在信息交互 大部分都以 JSON 为主。早期在 Spring 体系中使用 JSON 还比较复杂,需要配置多项 XML 和 注解,现在在 Spring Boot 体系中,对 JSON 支持简单而又完善,在 Web 层使用仅仅只需要 一个注解即可完成。
Controller层(控制层)
@RestController
public class StudentController {
@Resource
public StudentService studentService;
@RequestMapping(value = "/select",method = RequestMethod.GET)
public List<Student> toAll(){
//调用业务逻辑层方法或直接调用Dao层提供的方法实现即可
List<Student> list = studentService.findByAll();
return list;
}
/**
* 此处只演示一个查询的方法,其余方法想要了解可以自行百度,大致方法都差不多。
*/
}
注解解析:
- @RestController: 相当于 @ResponseBody + @Controller 合在一起的作用,如果 Web 层的类上使用了 @RestController 注解,就代表这个类中所有的方法都会以 JSON 的形式返回结果,也相当于 JSON 的一种快捷使用方式。
- @RequestMapping(value="/select", method= RequestMethod.GET): 以 /select 的方式 去请求,method= RequestMethod.GET 是指只可以使用 GET 的方式去请求,如果使用 POST 的方式去请求的话,则会报 405 不允许访问的错误。
最后运行启动类,然后打开浏览器在地址栏中输入 localhost:8080/select 即可预览查询结果,端口号默认为 8080,也可自行在配置文件中进行修改!
RESTful 的支持
什么是 RESTful ?
-
RESTful 是目前最流行的一种互联网软件架构。REST(Representational State Transfer,表述性状态转移)一词是由 Roy Thomas Fielding 在他 2000 年博士论文中提出的,定义了他对互联 网软件的架构原则,如果一个架构符合 REST 原则,则称它为 RESTful 架构。
-
RESTful 架构一个核心概念是”资源”(Resource)。从 RESTful 的角度看,网络里的任何东西都是资源,它可以是一段文本、一张图片、一首歌曲、一种服务等,每个资源都对应一个特定的 URI(统一资源定位符),并用它进行标示,访问这个 URI 就可以获得这个资源。
URI与URL的区别:
URI: URI,通一资源标志符(Uniform Resource Identifier, URI),表示的是web上每一种可用的资源,如HTML文档、图像、视频片段、程序等都由一个URI进行定位的。
URL: URL是URI的一个子集。它是Uniform Resource Locator的缩写,译为 “统一资源定位 符”。通俗地说,URL是 Internet 上描述信息资源的字符串,主要用在各种 WWW 客户程序和服务器程序上。采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。URL是URI概念的一种实现方式。
-
资源可以有多种表现形式,也就是资源的 “表述”(Representation),比如一张图片可以使 用 JPEG 格式也可以使用 PNG 格式。URI 只是代表了资源的实体,并不能代表它的表现形式。
-
互联网中,客户端和服务端之间的互动传递的就只是资源的表述,我们上网的过程,就是 调用资源的 URI,获取它不同表现形式的过程。这种互动只能使用无状态协议 HTTP,也就是 说,服务端必须保存所有的状态,客户端可以使用 HTTP 的几个基本操作,包括 GET(获取)、 POST(创建)、PUT(更新)与 DELETE(删除),使得服务端上的资源发生“状态转化”(State Transfer)、也就是所谓的 “表述性状态转移”。
Spring Boot 对 RESTful 的支持
Spring Boot 全面支持开发 RESTful 程序,通过不同的注解来支持前端的请求,除了经常使 用的注解外,Spring Boot 还提了一些组合注解。这些注解来帮助简化常用的 HTTP 方法的映射, 并更好地表达被注解方法的语义。
-
@GetMapping:处理 Get 请求
-
@PostMapping:处理 Post 请求
-
@PutMapping:用于更新资源
-
@DeleteMapping:处理删除请求
-
@PatchMapping:用于更新部分资源其实这些组合注解就是我们使用的 @RequestMapping 的简写版本,RESTful 在请求的类型 中 就 指定 了对 资源 的操 控 。
比如 @GetMapping(value="/xxx") 等价于 @RequestMapping(value = “/xxx”,method = RequestMethod.GET)。
如果是想写jsp页面的话还需要完成如下几个操作:
-
添加配置
# 为jsp文件添加前后缀 spring.mvc.view.prefix=/WEB-INF/jsp/ spring.mvc.view.suffix=.jsp
-
创建webapp文件夹
首先选择File—》Project Structure—》如图所示
然后在选择文件夹的路径后添加webapp,点击OK即可自动让创建的webapp文件夹生效,生效的文件夹上会有一个小蓝点。
以下为创建好的目录
-
导入依赖(不导的话jsp将无法正常运行)
<!-- 添加 jstl 标签库依赖 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency> <!-- 添加 jsp 引擎依赖,Spring Boot 内置 tomcat 没有此依赖 --> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> </dependency>
然后就可以在webapp中编写jsp页面啦
示例(用户登录):
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!-- ${pageContext.request.contextPath}为项目的相对路径 -->
<form action="${pageContext.request.contextPath}/stu/toLogin" method="post">
用户名:
<input type="text" name="stuName" required ><br/>
密码:
<input type="password" name="stuPassword" required ><br/>
<input type="submit" value="登录">
</form>
Controller层
@Controller
@RequestMapping("/stu")
public class StudentController {
@Resource
public StudentDao studentDao;
//登录验证
@PostMapping(value = "/Login")
public String Login(String stuName,String stuPassword,HttpSession session){
//此步骤可以在业务逻辑层中完成,我这里省略了业务逻辑层所以就直接写在控制层中
QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("stu_name",stuName); //第一个值为数据库字段名,第二个为参数名
queryWrapper.eq("stu_password",stuPassword);
//登录的方法
Student student = studentDao.selectOne(queryWrapper);
//查询全部用户的方法
List<Student> list = studentDao.selectList(null);
//验证是否登录成功;成功就则跳转至主页面(mian.jsp),失败则跳转至失败页面(error.jsp)
if (student != null){
System.err.println("登录成功!");
//把值返回至主页面,实现一个欢迎XXX的功能,然后在显示所有用户的信息
session.setAttribute("student",student);
session,setAttribute("StudentList",list);
return "main";
}else {
System.err.println("登录失败!");
return "error";
}
}
}
JSP主页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<h3>欢迎您:${student.stuName}</h3>
<table>
<tr>
<th>Id</th>
<th>用户名</th>
<th>密码</th>
<th>操作</th>
</tr>
<!-- 使用c标签循环遍历查询出的数据 -->
<c:forEach var="stu" items="${StudentList}">
<tr>
<td>${stu.stuId}</td>
<td>${stu.stuName}</td>
<td>${stu.stuPassword}</td>
<td>
<a href="${pageContext.request.contextPath}/stu/findByStuId?stuId=${stu.stuId}">修改</a>
<a href="#" onclick="expurgate(this,${stu.stuId})">删除</a>
</td>
</tr>
</c:forEach>
</table>
以上就完成了一个简单的登录功能啦,另外还可以直接在测试层直接运行,结果会直接输出至控制台中,不需要使用打开浏览器预览,接下来就给大家简单讲解一下。
示例(使用test层进行测试):
Controller层
@RestController
public class StudentController {
//查询方法
@GetMapping(value = "/select")
public List<Student> findAllStudent(){
//因为我这里是简单的演示,所以这里直接省略业务逻辑层的代码,直接使用dao.方法来实现
List<Student> list = studentDao.selectList(null);
return list;
}
//新增方法
@PostMapping(value = "/toInsert")
public void toInsert(Student student){
studentDao.insert(student);
}
}
添加依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
test层
@RunWith(SpringRunner.class)
@SpringBootTest
public class StudentTest {
@Resource
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup(){
//配置MVC环境
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
//查询所有用户
@Test
public void All() throws Exception {
String mvc= mockMvc.perform(MockMvcRequestBuilders.get("/select")).andReturn().getResponse().getContentAsString();
//直接输出即可
System.err.println(mvc);
}
@Test
public void testInsert() throws Exception {
final MultiValueMap<String, String> mvm = new LinkedMultiValueMap<>();
mvm.add("stuName","wangwu");
mvm.add("stuPassword", "12345");
mockMvc.perform(MockMvcRequestBuilders.post("/toInsert").params(mvm))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
}
}
属性解析:
-
Perform(…)构建一个请求,并且返回 ResultActions 实例,该实例则可以获取到请求的 返回内容等。
-
WebApplicationContext:注入Spring Web的上下文环境
-
MockMvc :MockMvc 实现了对 Http 请求的模拟,能够直接使用网络的形式,转换到 Controller 的调用, 这样可以使得测试速度更快、不依赖网络环境,而且提供了一套验证的工具,可以使得请求的 验证统一而且更方便。
-
@Before注解:代表在测试启动时候需要提前加载的内容。
-
MockMvcRequestBuilders.get("/select"):测试的路径,与controller层中设置的路径对应即可。
-
andExpect(…) 预期结果判断,可以多次调用。
-
andReturn()返回 MvcResult 对象,该对象可以获取到返回的视图名称、返回的 Response 状态、获取拦截请求的拦截器集合。
-
andDo(…) 继续一些操作,例如 MockMvcResultHandlers.print()打印响应信息。
除了以上两种方式,还可以使用外部工具的方式来进行测试,比如Postman、PostWoman等,有兴趣大家可以去试一试。
接下来在给大家演示一下JSP页面实现的删除与修改(修改与新增差不多,所以这里就简单说一下修改)
-
删除用户(需要使用ajax)
controller层
//删除用户 @DeleteMapping(value = "/toDelete/{id}") @ResponseBody //使用ajax时需要加上 public Integer toDelete(@PathVariable("id") Integer id) throws IOException { Integer row = studentDao.deleteById(id); return row; }
导入jQuery依赖
<!-- jQuery依赖 --> <dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId> <version>3.4.1</version> </dependency>
配置过滤器(ajax局部刷新时需要)
# 启用hiddenMethod过滤器 spring.mvc.hiddenmethod.filter.enabled=true
主页面删除单击事件(使用ajax实现局部刷新)
<script src="${pageContext.request.contextPath}/webjars/jquery/3.4.1/jquery.js"></script> <script> function expurgate(th,id) { if (confirm("您确定要删除该用户吗?")){ $.ajax({ url:"${pageContext.request.contextPath}/stu/toDelete/"+id, type:"POST", data:{_method:"DELETE"}, dataType:"json", success:function(data){ if (data > 0){ $(th).parent().parent().remove(); alert("删除成功!") }else { alert("删除失败!") } } }); } } </script>
ajax属性解析:
url: 发送请求的地址 。
type: 请求方式 ,可以为POST或GET,默认为GET。
data: 发送到服务器的数据,如果已经不是字符串格式,将自动转换为字符串格式 ,写法一般为data:{_method:“DELETE”}。
dataType: 预期服务器返回的数据类型 。
success: 要求为Function类型的参数,请求成功后调用的回调函数。
完成以上操作即可实现局部刷新的删除功能。
-
修改用户
Controller层
@Controller @RequestMapping("/stu") public class StudentController { @Resource public StudentDao studentDao; //根据被修改的用户id进行查询,然后跳转至修改页面进行给予默认值 @GetMapping(value = "/findByStuId") public String findByStuId(Integer stuId, Model model){ //根据id进行查询 Student stu = studentDao.selectById(stuId); model.addAttribute("student",stu); return "amend"; } //修改用户信息 @PutMapping(value = "/toUpdate") public String toUpdate(Student student){ Integer row = studentDao.updateById(student); if (row > 0){ System.err.println("修改成功!"); //修改成功后使用重定向的方式返回主页面 return "redirect:Main"; }else { System.err.println("修改失败!"); return "error"; } } //跳转至主页面 @GetMapping("/Main") public String Main(HttpSession session){ //查询所有数据,数据修改后重新加载数据 List<Student> list = studentService.findByAll(); session.setAttribute("StudentList",list); return "main"; } }
修改信息页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <form action="${pageContext.request.contextPath}/stu/toUpdate?stuId=${student.stuId}" method="post"> <input hidden value="put" name="_method"> <table border="1px"> <tr> <th style="font-size: 20px;" colspan="2">修改用户</th> </tr> <tr> <td>用户名</td> <td><input type="text" name="stuName" value="${student.stuName}" required /></td> </tr> <tr> <td>密码</td> <td><input type="text" name="stuPassword" value="${student.stuPassword}" required /></td> </tr> <tr> <td colspan="2"> <input type="submit" value="保存" /> <input type="button" value="返回" onclick="history.go(-1);" /> </td> </tr> </table> </form>
完成后修改功能就可以啦。
支持热部署
热部署作用:使用idea来开发web这类的项目时, 每次修改了 Controller、JSP 等,都需要重新启动项目才能生效 ,所以它提供了一个组件来实现不需要重新启动项目即可生效完成的功能(简单来说就是写完代码不需要重新启动项目,而是直接在浏览器中刷新即可)!
快速上手
-
导入依赖
<!-- 添加 spring-boot-devtools 组件依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <!-- 在 plugin 中配置另外一个属性 fork,并且配置为 true --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> </configuration> </plugin>
-
配置IDEA
2.1: 选择 File –> Settings ->Compiler 命令,然后勾选 Build project automatically 。
2.2: 使用快捷键 Ctrl + Shift + A,在输入框中输入Registry ,双击第一个 Registry,在打开 的界面勾选 compile.automake.allow.when.app.running 复选框 。
2.3: 在 Edit Configurations 选项中配置 Update classes and resources 。
拦截器与过滤器
Web 项目中,控制器可以处理具体的业务请求,公共功能的处理则可以利用 AOP 的思想, 通过过滤器或拦截器实现。过滤器和拦截器都属于面向切面编程的具体实现。
两者的区别:
- Filter 是依赖于 Servlet 容器,属于 Servlet 规范的一部分,而拦截器则是独立存在的, 可以在任何情况下使用。
- Filter 的执行由 Servlet 容器回调完成,而拦截器通常通过动态代理的方式来执行。
- Filter 的生命周期由 Servlet 容器管理,而拦截器则可以通过 IoC 容器来管理,因此可以 通过注入等方式来获取其他 Bean 的实例,因此使用会更方便。
自定义过滤器
-
Filter 也称之为过滤器,可以在前端拦截所有用户的请求。Web 开发人员通过 Filter 技术, 对 Web 服务器管理的所有 Web 资源,例如 JSP、Servlet、控制器、静态图片文件或静态 HTML 文件等进行拦截,从而实现一些特殊的功能。例如,实现 URL 级别的权限访问控制、过滤敏感词汇、排除有 XSS 威胁的字符、记录请求日志等一些高级功能。
-
Spring Boot内置了一些 Filter,比如处理编码的 OrderedCharacterEncodingFilter 和请求 转化的 HiddenHttpMethodFilter,也支持根据我们的需求来可以自定义 Filter。
-
自 定 义 Filter 有两种实现 方式 , 第一种是使 用 @WebFilter , 第 二 种是使 用 FilterRegistrationBean,经过实践之后发现使用 @WebFilter 自定义的过滤器优先级顺序不能生 效(只能根据 Filter 类名的字母顺序倒序排列,且优先级都高于 FilterRegistrationBean 配置的过滤 器),因此推荐使用第二个方案。
自定义过滤器的实现步骤:
实现 Filter 接口,重写其中的 doFilter() 方法。
添加 @Configuration 注解,将自定义 Filter 加入过滤链。
示例
实现 Filter 接口,重写doFilter() 方法
//自定义过滤器
public class AuthorizationFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//转换为http协议类型
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//判断该Session中有没有值
if (request.getSession().getAttribute("student") == null){
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//提示后跳回登录页面请求用户进行登录操作
out.print("<script>alert('请先进行登陆!');location.href='"+request.getContextPath()+"/login.jsp';</script>");
}else {
//传递到下一个过滤器,如果没有下一个则返回当前的请求
filterChain.doFilter(request,response);
}
}
}
添加 @Configuration 注解表示是一个配置类,然后将自定义 Filter 加入过滤链
//自定义过滤器
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean filterRegistrationBean(){
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new AuthorizationFilter());
registrationBean.setName("AuthorizationFilter");
//如果用户不登录而直接进入主页面则会被拦截,然后跳转至指定的页面
registrationBean.addUrlPatterns("/stu/Main");
registrationBean.setOrder(5);
return registrationBean;
}
}
jsp(index.jsp)页面
此过滤器实现的功能为,如果用户在没有登录的情况下想要进入主页面,则会触发过滤器,从而返回至登录页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>选择页面</title>
</head>
<body>
<a href="login.jsp">登录</a>
<a href="${pageContext.request.contextPath}/stu/Main">主页面</a>
</body>
</html>
Controller层
@Controller
@RequestMapping("/stu")
public class StudentController {
@GetMapping("/Main")
public String Main(HttpSession session){
List<Student> list = studentService.findByAll();
session.setAttribute("StudentList",list);
return "main";
}
}
完成以上操作后在浏览器中直接访问index.jsp页面,然后当用户还没有登录却直接点击主页面的超链接后就会触发过滤器,然后跳转至指定的页面!
自定义拦截器
自定义 Interceptor 的实现步骤:
- 实现 HandlerInterceptor 接口,重写其中的三个方法;
- 实现 WebMvcConfigurer 接口,重写 addInterceptors 方法,注册拦截器。
示例
实现 HandlerInterceptor 这个接口,这个接口包括三个方法,preHandle 是请求执行前执行 的,postHandler 是请求结束执行的,但只有 preHandle 方法返回 true 的时候才会执行, afterCompletion 是视图渲染完成后才执行,同样需要 preHandle 返回 true,该方法通常用于清理资源等工作。
//自定义拦截器
public class AuthorizationInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//判断session中是否有值
if (request.getSession().getAttribute("student") == null){
//设置字符编码
response.setContentType("text/html;charset=UTF-8");
//输入错误路径时跳转至登录页面
PrintWriter out = response.getWriter();
out.print("<script>alert('请先进行登陆!');window.location.href='login.jsp';</script>");
return false;
}
return true;
}
}
除了实现上面的接口外,我们还需对其进行配置注册:
//自定义拦截器
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthorizationInterceptor())
.addPathPatterns("/**") //表示拦截全部路径
.excludePathPatterns("/stu/login","/stu/toLogin"); //表示放行的路径,通过放行的路径就可以使用其他的路径了
}
}
实现 WebMvcConfigurer 接口;重写了 addInterceptors 这个方法,进行拦截器的配置,主要配置项就两是这两个,第一个是指定拦截器,第二个是指定拦截的 URL 和排除 URL。
自定义拦截器到此就开发成功了,对比过滤器就可以发现,拦截器在配置排除路径规则时更简单方便,且因为由 IOC 容器管理,灵活性更高。
注: 以上只是一个简单的拦截器编写,当程序运行后在浏览器地址栏中输入错误地址会直接跳转至指定的路径页面,但是如果通过拦截器放行的路径进入其他路径之后,如果再次输入错误路径,则会导致404报错!!
打包部署
-
Spring Boot 使用了内嵌容器,因此它的部署方式也变得非常简单灵活,一方面可以将 Spring Boot 项目打包成独立的 Jar 或者 War 包来运行,也可以单独打包成 War 包部署到 Tomcat 容器中运行,如果涉及到大规模的部署 Jinkins 就成为最佳选择之一。
-
内嵌容器技术的发展为 Spring Boot 部署打下了坚实的基础,内嵌容器不只在部署阶段发 挥着巨大的作用,在开发调试阶段也会带来极大的便利性,对比以往开发 Web 项目时配置 Tomcat 的繁琐,会让大家使用 Spring Boot 内嵌容器时有更深的感触。使用 Spring Boot 开发 Web 项目,不需要关心容器的环境问题,专心写业务代码即可。
-
内嵌容器对部署带来的改变更多,现在 Maven 、Gradle 已经成了我们日常开发必不可少 的构建工具,使用这些工具很容易的将项目打包成 Jar 或者 War 包,在服务器上仅仅需要一 条命令即可启动项目。
多环境配置
在我们开发过程中必定会面临多环境的 问题,比如开发环境、测试环境、生产环境,在不同的环境下会有不同的数据库连接池等配置信息。如果都写在一个配置文件中,在不同的环境下启动需要手动修改对应的环境参数,这种方式容易出错。Spring Boot 支持多配置文件的使用,只需要启动时指定对应的配置文件即可。
首先在 pom.xml 文件中添加如下配置:
<profiles>
<profile>
<id>dev</id>
<properties>
<env>dev</env>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<env>test</env>
</properties>
</profile>
<profile>
<id>pro</id>
<properties>
<env>pro</env>
</properties>
</profile>
</profiles>
然后在 pom.xml 文件的 buile 标签内添加以下配置:
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>application-dev.properties</exclude>
<exclude>application-pro.properties</exclude>
<exclude>application-test.properties</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>application-${env}.properties</include>
</includes>
</resource>
</resources>
在 Spring Boot 中多环境配置文件名需要满足 application-{profile}.properties 的格式,其中 {profile} 对应环境标识。
在 resources 目录下创建以下三个文件:
- application-dev.properties:开发环境使用({profile}=dev)
- application-test.properties:测试环境使用 {profile}=test)
- application-prod.properties:生产环境使用 ({profile}=prod)
不同的配置文件对应不同的环境,启动的时候通过参数设置来启用不同的配置。 开发过程中在 application.properties 文件中通过 spring.profiles.active 属性来设置,其值对 应 {profile} 值。
# 在application.properties文件中配置使用的配置环境即可应用对应环境中的配置
spring.profiles.active=dev
解析: 在一个项目中会有多个环境,所有就需要使用多环境配置,用于测试、开发等用途。在不同的环境中可以设置不同的配置,比如数据库、项目根目录、端口号等配置。
服务器配置
常用配置:
# 项目 contextPath,一般不用配置
server.servlet.context-path=/crm
# 错误页,指定发生错误时,跳转的 URL
server.error.path=/error
# 服务端口
server.port=8090
# session 最大超时时间(分钟),默认为 30
server.session-timeout=60
如果使用了 Tomcat 还可以进行如下设置:
# tomcat 最大线程数,默认为 200
server.tomcat.max-threads=600
# tomcat 的 URI 编码
server.tomcat.uri-encoding=UTF-8
# 存放 Tomcat 的日志、Dump 等文件的临时文件夹,默认为系统的 tmp 文件夹
server.tomcat.basedir=/tmp/log
# 打开 Tomcat 的 Access 日志,并可以设置日志格式
server.tomcat.access-log-enabled=true
# accesslog 目录,默认在 basedir/logs
server.tomcat.accesslog.directory=basedir/logs
# 日志文件目录
logging.path=/tmp/log
# 日志文件名称,默认为 spring.log
logging.file=crm.log
项目打包
这里使用maven项目进行演示,打包方式分为两种,分别是 jar 包与 war 包(默认为 jar 包)
使用 IDEA 的 Maven 插件可以自动打包:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gzh64CjR-1583660559966)(C:\Users\ymq\AppData\Roaming\Typora\typora-user-images\1583658529906.png)]
也可以点击 install 打包在maven的本地仓库中,在控制台打印完 DUILD SUCCESS 就表示已经打包完成。
如果想要打成 war 包,则在pom文件中设置即可。
打包完成后 jar 包会生成到 target 目录下,命名一般是“项目名+版本号.jar”的形式。
如果想要运行 jar 包则可以在 cmd 中启动
使用 Win+R 然后输入 cmd 打开页面,然后根据如下步骤即可运行:
//先跳转至存放jar包的盘中
C:\Users>e:
//跳转之后进入对应项目文件夹中
E:\>cd E:\springWeb
//输入 java -jar target/demo-0.0.1-SNAPSHOT.jar 命令即可开始运行
E:\springWeb>java -jar target/demo-0.0.1-SNAPSHOT.jar
按两次 Ctrl+C 或者关闭 cmd 页面即可退出程序。