SpringBoot基本使用
3.1 自定义控制器
我们创建的是一个基于SpringBoot的WEB项目,那么怎么处理客户端提交的请求呢?这时我们可以直接在启动器所在的子目录下创建对应的Controller即可
代码语言:javascript复制package com.bobo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/*@Controller
@ResponseBody*/
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(){
System.out.println("hello ...");
return "Hello ...";
}
}
访问即可
为什么能够扫描到这个@Controller注解,根本原因是在我们的启动器中的那个@SpringBootApplication注解,这个注解本身是一个组合注解
代码语言:javascript复制@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
// 以上四个是JAVA中提供的元注解
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
注解 | 说明 |
---|---|
@SpringBootConfiguration | 也是一个组合注解,包含@Configuriation,标注当前注解的类是一个配置类 |
@EnableAutoConfiguration | 完成依赖的自动配置的一个注解,是自动装配的核心注解 |
@ComponentScan | 指定扫描路径的注解,如果不去指定默认会将当前类所在的目录及其子目录作为扫描路径 |
3.2 静态资源
在SpringBoot项目中默认的静态资源【html,css,js,图片....】是放置在resource/static目录中
效果
3.3 定制Banner
如果我们想要修改服务启动时的那个banner图标,我们只需要在resource目录下创建一个banner.txt文件,然后将我们要显示的信息写入即可 http://patorjk.com/software/taag/#p=display&f=Graffiti&t=HELLO
当然我们也可以不显示Banner信息
代码语言:javascript复制@SpringBootApplication
public class SpringBootDemo03Application {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(SpringBootDemo03Application.class);
app.setBannerMode(Banner.Mode.OFF); // 关闭掉Banner
app.run(args);
}
}
3.4 属性文件
在resource目录下的application.properties文件
3.4.1 默认设置
我们可以通过application.properties文件来修改系统默认的属性,比如修改Tomcat相关配置信息
代码语言:javascript复制server.port=8082
server.servlet.context-path=/springboot
3.4.2 自定义属性
我们可以在application.properties文件中自定义属性,供我们在代码中使用
自定义属性
代码语言:javascript复制# 默认属性修改
server.port=8082
server.servlet.context-path=/springboot
# 自定义属性
user.userName=admin
user.realName=波波
user.address=湖南长沙
获取自定义属性
代码语言:javascript复制/*@Controller
@ResponseBody*/
@RestController
public class HelloController {
@Value(value = "${user.userName}")
private String userName;
@Value(value = "${user.realName}")
private String realName;
@Value(value = "${user.address}")
private String address;
@RequestMapping("/hello")
public String hello(){
System.out.println("hello ..." userName " " realName " " address);
return "Hello ...";
}
}
出现乱码的情况
解决方法
修改了乱码后的效果
3.4.3 yml文件
yml是我们在配置系统属性或者自定义属性的另外一种方式
代码语言:javascript复制user.hello.username=a
user.hello.password=123
user.hello.address=cs
user.hello.age=1
改成yml
代码语言:javascript复制user:
hello:
username:a
password:123
address:cs
age:1
3.5 日志
SpringBoot中支持 JavaUtil Logging, Log4J, Log4J2和Logback作为日志框架,而在SpringBoot中默认支持的是Logback作为日志框架
简单配置
代码语言:javascript复制# 日志配置
#logging.file.path=d:/tools/log
logging.file.name=d:/tools/log/log.log
logging.level.org.springframework.web=DEBUG
引入日志文件的扩展配置文件
代码语言:javascript复制<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--日志文件主目录:这里${user.home}为当前服务器用户主目录-->
<property name="LOG_HOME" value="${user.home}/log"/>
<!--日志文件名称:这里spring.application.name表示工程名称-->
<springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
<!--默认配置-->
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<!--配置控制台(Console)-->
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<!--配置日志文件(File)-->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--设置策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件路径:这里%d{yyyyMMdd}表示按天分类日志-->
<FileNamePattern>${LOG_HOME}/%d{yyyyMMdd}/${APP_NAME}.log</FileNamePattern>
<!--日志保留天数-->
<MaxHistory>15</MaxHistory>
</rollingPolicy>
<!--设置格式-->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<!-- 或者使用默认配置 -->
<!--<pattern>${FILE_LOG_PATTERN}</pattern>-->
<charset>utf8</charset>
</encoder>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>100MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- 多环境配置 按照active profile选择分支 -->
<springProfile name="dev">
<!--root节点 全局日志级别,用来指定最基础的日志输出级别-->
<root level="DEBUG">
<appender-ref ref="FILE"/>
<appender-ref ref="CONSOLE"/>
</root>
<!-- 子节点向上级传递 局部日志级别-->
<logger level="WARN" name="org.springframework"/>
<logger level="WARN" name="com.netflix"/>
<logger level="DEBUG" name="org.hibernate.SQL"/>
</springProfile>
<springProfile name="prod">
<!--root节点 全局日志级别,用来指定最基础的日志输出级别-->
<root level="INFO">
<appender-ref ref="FILE"/>
<appender-ref ref="CONSOLE"/>
</root>
</springProfile>
</configuration>
引入
3.6 Profile
项目开发中会出现开发环境的切换,为了更好的处理我们可以通过Profile来实现,之前在Spring的阶段就已经给大家介绍过了Profile,但是实现相对复杂了点,在SpringBoot中也提供了对Profile的支持,而且更加简化,
创建对应的属性文件
开发环境
代码语言:javascript复制user.host=192.168.100.120
生产环境
代码语言:javascript复制user.host=192.168.111.123
文件名称的命名规则是 application-环境.properties
要让哪个文件生效,我们只需要在application.properties文件中指定即可
测试效果
3.7 静态资源文件
在SpringBoot项目中默认的存放路径是在static目录下,但是实际开发的时候有可能我们需要调整资源的目录。
在main目录下创建一个webapp目录 设置类型为 ResourceRoot
可以直接访问
自定义目录
有些情况下我们需要将特定的目录作为我们存放静态资源文件的目录
代码语言:javascript复制## 设置自定义的路径
spring.mvc.static-path-pattern=/**
## 覆盖掉默认的配置录
spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,classpath:/sfile/
3.8 Servlet操作
我们在项目开发过程中可以要碰到直接操作Servlet的情况,这时我们应该怎么去实现
3.8.1 Servlet
第一种方式
定义Servlet
代码语言:javascript复制@WebServlet(name="firstServlet",urlPatterns = "/first")
public class FirstServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("--firstServlet -- doGet 方法");
PrintWriter writer = resp.getWriter();
writer.write("success");
writer.flush();
writer.close();
}
}
在启动类中添加扫描的注解
代码语言:javascript复制@SpringBootApplication
// 在SpringBoot项目启动的时候会扫描 @WebServlet注解
@ServletComponentScan
public class SpringbootDemo06Application {
public static void main(String[] args) {
SpringApplication.run(SpringbootDemo06Application.class, args);
}
}
测试访问
第二种方式
创建Servlet,不用添加WebServlet注解
代码语言:javascript复制package com.bobo.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class SecondServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("--secondServlet -- doGet 方法");
PrintWriter writer = resp.getWriter();
writer.write("success");
writer.flush();
writer.close();
}
}
在启动类中注入ServletRegistrationBean对象
代码语言:javascript复制@SpringBootApplication
// 在SpringBoot项目启动的时候会扫描 @WebServlet注解
@ServletComponentScan
public class SpringbootDemo06Application {
public static void main(String[] args) {
SpringApplication.run(SpringbootDemo06Application.class, args);
}
@Bean
public ServletRegistrationBean servletRegistrationBean(){
ServletRegistrationBean bean = new ServletRegistrationBean(new SecondServlet());
bean.addUrlMappings("/second");
return bean;
}
}
测试
3.8.2 Filter
第一种方式
创建过滤器
代码语言:javascript复制@WebFilter(urlPatterns = "/first")
public class FirstFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("FirstFilter before");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("FirstFilter end");
}
}
在启动器中添加注解
测试
第二种方式
在该过滤器中我们不用添加对应的注解
代码语言:javascript复制public class SecondFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("SecondFilter before");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("SecondFilter end");
}
}
启动器中注入 注册器
代码语言:javascript复制 @Bean
public FilterRegistrationBean filterRegistrationBean(){
FilterRegistrationBean bean = new FilterRegistrationBean(new SecondFilter());
bean.addUrlPatterns("/second");
return bean;
}
测试
3.8.3 Listener
第一种方式
代码语言:javascript复制package com.bobo.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class FirstListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("FirstListener ... 初始化");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("FirstListener ... 销毁");
}
}
启动器中注解
测试效果
第二种方式
代码语言:javascript复制package com.bobo.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
public class SecondListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("SecondListener ... 初始化");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("SecondListener ... 销毁");
}
}
代码语言:javascript复制 @Bean
public ServletListenerRegistrationBean servletListenerRegistrationBean(){
return new ServletListenerRegistrationBean(new SecondListener());
}
测试
3.9 文件上传
3.9.1 表单页面
代码语言:javascript复制<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户管理</title>
</head>
<body>
<h1>文件上传案例:</h1>
<form action="/user/upload" method="post" enctype="multipart/form-data" >
<label>账号:</label><input type="text" name="username"><br>
<label>头像:</label><input type="file" name="upload"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
3.9.2 控制器
代码语言:javascript复制package com.bobo.controller;
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
@RestController
@RequestMapping("/user")
public class UserContoller {
@RequestMapping("/upload")
public String fileUpload(String username, MultipartFile upload) throws IOException {
System.out.println(username " " upload.getOriginalFilename());
upload.transferTo(new File("d:/tools/",upload.getOriginalFilename()));
return "success";
}
}
3.9.3 属性文件设置
代码语言:javascript复制server.port=8082
spring.servlet.multipart.enabled=true
# 设置单个文件上传的大小
spring.servlet.multipart.max-file-size=20MB
# 设置一次请求上传文件的总的大小
spring.servlet.multipart.max-request-size=200MB
3.9.4 测试
上传成功的文件