Spring Boot 实现Web 开发
Spring MVC 整合支持
-
使用Spring Initializer 创建spring boot 项目,创建时勾选添加Web 依赖启动器和Theymeleaf 启动器
-
注册视图管理器
addViewController 的参数填写虚拟路径,setViewName 的参数填写虚拟路径映射的页面名称
package cn.edu.sjzc.chapter05.config; @Configuration public class MyMVCConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/toLoginPage").setViewName("login"); registry.addViewController("/login.html").setViewName("login"); } }
测试:在浏览器地址访问 http://localhost:8080/toLoginPage 或者
http://localhost:8080/login.html 就可访问templates 下的login.html文件(已经添加后缀)
-
编写自定义拦截器
给页面添加当前年份currentYear
package cn.edu.sjzc.chapter05.config; @Configuration public class MyInterceptor implements HandlerInterceptor { @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { request.setAttribute("currentYear",Calendar.getInstance().get(Calendar.YEAR)); } }
在MVC配置类中注册自定义拦截器
@Autowired private MyInterceptor myInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(myInterceptor).addPathPatterns("/**").excludePathPatterns("/login.html"); }
访问上述页面后当前年份可以正常显示
整合Servlet
-
创建servletConfig 类
用于 注册servlet
@Configuration public class servletConfig { }
-
整合HttpServlet
-
编写MyServlet 继承HttpServlet
package cn.edu.sjzc.chapter05.servletComponent; @Component public class MyServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().write("hello servlet"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req,resp); } }
-
注册MyServlet
在configServlet 类中添加以下代码,设置myServlet 的映射路径位/myServlet
@Configuration public class servletConfig { @Bean public ServletRegistrationBean<MyServlet> getServlet(MyServlet myServlet){ ServletRegistrationBean<MyServlet> myServletServletRegistrationBean = new ServletRegistrationBean<>(myServlet,"/myServlet"); return myServletServletRegistrationBean; } }
访问http://localhost:8080/myServlet 成功输出hello servlet
-
-
整合MyFilter
-
创建myFilter类继承 Filter( package javax.servlet )
package cn.edu.sjzc.chapter05.servletComponent; @Component public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("myFilter 初始化了"); } @Override public void destroy() { System.out.println("myFilter 销毁了"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("myFilter 执行了"); filterChain.doFilter(servletRequest,servletResponse); } }
-
在config 类中注册myFilter
Arrays.asList 中填写要进行拦截的路径
@Bean public FilterRegistrationBean<MyFilter> getFilter(MyFilter myFilter){ FilterRegistrationBean<MyFilter> myFilterFilterRegistrationBean = new FilterRegistrationBean<>(myFilter); myFilterFilterRegistrationBean.setUrlPatterns(Arrays.asList("/myServlet")); return myFilterFilterRegistrationBean; }
访问http://localhost:8080/myServlet 控制台打印:myFiler执行了
-
-
整合ServletListener
-
创建MyListener 继承 ServletContextListener
package cn.edu.sjzc.chapter05.servletComponent; @Component public class MyListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("contextInitialized myListener监听到context 启动了"); } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("contextDestroyed myListener监听到context 销毁了"); } }
-
在config类中注册MyListener
@Bean public ServletListenerRegistrationBean getListenerRegistrationBean(MyListener myListener){ ServletListenerRegistrationBean<MyListener> myListenerServletListenerRegistrationBean = new ServletListenerRegistrationBean<>(myListener); return myListenerServletListenerRegistrationBean; }
启动服务器时listener 监听到context 初始化了,并打印出以上信息
-
文件上传
- 创建文件上传页面 upload.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>动态添加文件上传列表</title>
<link th:href="@{/login/css/bootstrap.min.css}" rel="stylesheet">
<script th:src="@{/login/js/jquery.min.js}"></script>
</head>
<body>
<div th:if="${uploadStatus}" style="color: red" th:text="${uploadStatus}">上传成功</div>
<form th:action="@{/uploadFile}" method="post" enctype="multipart/form-data">
上传文件: <input type="button" value="添加文件" onclick="add()"/>
<div id="file" style="margin-top: 10px;" th:value="文件上传区域"> </div>
<input id="submit" type="submit" value="上传"
style="display: none;margin-top: 10px;"/>
</form>
<script type="text/javascript">
// 动态添加上传按钮
function add(){
var innerdiv = "<div>";
innerdiv += "<input type='file' name='fileUpload' required='required'>" +
"<input type='button' value='删除' οnclick='remove(this)'>";
innerdiv +="</div>";
$("#file").append(innerdiv);
// 打开上传按钮
$("#submit").css("display","block");
}
// 删除当前行<div>
function remove(obj) {
$(obj).parent().remove();
if($("#file div").length ==0){
$("#submit").css("display","none");
}
}
</script>
</body>
</html>
- 编写配置文件 application.properties
# thymeleaf配置
# 模板缓存
spring.thymeleaf.cache=false
# 模板编码
spring.thymeleaf.encoding=UTF-8
# 模板样式
spring.thymeleaf.mode=HTML
# 模板页面存放路径
spring.thymeleaf.prefix=classpath:/templates/
# 指定页面名称的后缀名
spring.thymeleaf.suffix=.html
# 配置国际化文件基础名
spring.messages.basename=i18n.login
# 单个上传文件大小限制(默认1MB)
spring.servlet.multipart.max-file-size=10MB
# 总上传文件大小限制(默认10MB)
spring.servlet.multipart.max-request-size=50MB
- 创建文件上传类 FileController.java
package cn.edu.sjzc.chapter05.controller;
@Controller
public class FileController {
// 转到上传页面
@GetMapping("/toUpload")
public String toUploadPage(){
return "upload";
}
// 上传文件
@PostMapping("/uploadFile")
public String uploadFile(MultipartFile[] fileUpload, Model model) {
model.addAttribute("上传成功");
for (MultipartFile file : fileUpload) {
String fileName = file.getOriginalFilename();
fileName = UUID.randomUUID()+"_"+fileName;
String dirPath = "D:/File2/";
File filePath = new File(dirPath);
if(!filePath.exists()){
filePath.mkdirs();
}
try {
file.transferTo(new File(dirPath + fileName));
} catch (IOException e) {
e.printStackTrace();
model.addAttribute("uploadStatus","上传失败");
}
}
return "redirect:/toUpload";
}
访问http://localhost:8080/toUpload 选择文件进行上传
文件下载
准备:在pom.xml 中添加 commons-io依赖
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
1.创建下载页面 download.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>文件下载</title>
</head>
<body>
<div style="margin-bottom: 10px">文件下载列表:</div>
<table>
<tr>
<td>meiyin.text</td>
<td><a th:href="@{/download(filename='meiyin.txt')}">meiyin.text</a></td>
</tr>
<tr>
<td>美音.text</td>
<td><a th:href="@{/download(filename='美茵.txt')}">
美音.text</a></td>
</tr>
</table>
</body>
</html>
2.在FileController 中添加下载文件的方法
package cn.edu.sjzc.chapter05.controller;
@Controller
public class FileController {
@GetMapping("/toUpload")
public String toUploadPage(){
return "upload";
}
@PostMapping("/uploadFile")
public String uploadFile(MultipartFile[] fileUpload, Model model) {
model.addAttribute("上传成功");
for (MultipartFile file : fileUpload) {
String fileName = file.getOriginalFilename();
fileName = UUID.randomUUID()+"_"+fileName;
String dirPath = "D:/File2/";
File filePath = new File(dirPath);
if(!filePath.exists()){
filePath.mkdirs();
}
try {
file.transferTo(new File(dirPath + fileName));
} catch (IOException e) {
e.printStackTrace();
model.addAttribute("uploadStatus","上传失败");
}
}
return "redirect:/toUpload";
}
@GetMapping("/toDownload")
public String toDownloadPage(){
return "download";
}
@GetMapping("/download")
public ResponseEntity<byte[]> downloadFile(String filename,HttpServletRequest request) throws Exception {
String fileDir = "D:/File2/";
File file = new File(fileDir+File.separator+filename);
// 将文件名编码
filename = getFilename(request,filename);
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentDispositionFormData("attachment",filename);
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
try {
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers, HttpStatus.OK);
} catch (IOException e) {
return new ResponseEntity<byte[]>(e.getMessage().getBytes(),HttpStatus.EXPECTATION_FAILED);
}
}
// 根据不同浏览器选择不同空的编码格式,保证要下载的文件名不乱码
private String getFilename(HttpServletRequest request, String filename)
throws Exception {
String[] IEBrowserKeyWords = {"MSIE", "Trident", "Edge"};
String userAgent = request.getHeader("User-Agent");
for (String keyWord : IEBrowserKeyWords) {
if (userAgent.contains(keyWord)) {
return URLEncoder.encode(filename, "UTF-8").replace("+"," ");
}}
return new String(filename.getBytes("UTF-8"), "ISO-8859-1");
}
}
访问http://localhost:8080/toDownload 选择文件进行下载
jar 包方式打包部署
准备:在pom.xml 中添加如下build
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
打包方式:idea 中找到maven视图,双击package,项目被打成jar包并放被到target 目录下
运行方式:打开终端 输入java -jar 路径/包名.jar
war 包方式打包部署
准备:
- 在pom.xml 中设置打包的方式
<version>0.0.1-SNAPSHOT</version>
<name>chapter05</name>
<description>Demo project for Spring Boot</description>
<packaging>war</packaging> // 采用war包形式
<properties>
<java.version>1.8</java.version>
</properties>
- 声名使用外部tomcat
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency
- 为Spring Boot 提供启动的Servlet 初始化器
主程序启动类继承SpringBootServletInitializer 并实现configure 方法,首个参数为主程序启动类
package cn.edu.sjzc.chapter05;
@SpringBootApplication
public class Chapter05Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(Chapter05Application.class);
}
public static void main(String[] args) {
SpringApplication.run(Chapter05Application.class, args);
}
}
打包方式:和jar包相同
启动方式:将war 包放到tomcat 目录下的 webapps 目录下,启动tomcat 即可