SpringBoot實(shí)現(xiàn)WEB的常用功能案例詳解
前言
通常在 Web 開發(fā)中,會(huì)涉及靜態(tài)資源的訪問支持、視圖解析器的配置、轉(zhuǎn)換器和格式化器的定制、文件上傳下載等功能,甚至還需要考慮到與Web服務(wù)器關(guān)聯(lián)的 Servlet相關(guān)組件的定制。Spring Boot框架支持整合一些常用Web框架,從而實(shí)現(xiàn)Web開發(fā),并默認(rèn)支持Web開發(fā)中的一些通用功能。本文將對(duì)Spring Boot實(shí)現(xiàn)Web開發(fā)中涉及的三大組件Servlet、Filter、Listener以及文件上傳下載功能以及打包部署進(jìn)行實(shí)現(xiàn)。
SpringMVC整合支持
為了實(shí)現(xiàn)并簡化Web開發(fā),Spring Boot為一些常用的Web開發(fā)框架提供了整合支持,例如 Spring MVC、Spring WebFlux等框架。使用Spring Boot進(jìn)行Web開發(fā)時(shí),只需要在項(xiàng)目中引入對(duì)應(yīng)Web開發(fā)框架的依賴啟動(dòng)器即可。
Spring MVC自動(dòng)配置
在Spring Boot項(xiàng)目中,一旦引入了Web依賴啟動(dòng)器spring-boot-starter-web,那么SpringBoot整合 Spring MVC 框架默認(rèn)實(shí)現(xiàn)的一些xxxAutoConfiguration自動(dòng)配置類就會(huì)自動(dòng)生效,幾乎可以在無任何額外配置的情況下進(jìn)行Web開發(fā)。Spring Boot為整合Spring MVC 框架實(shí)現(xiàn)Web開發(fā),主要提供了以下自動(dòng)化配置的功能特性。
(1)內(nèi)置了兩個(gè)視圖解析器:ContentNegotatingViewResolver和BeanNameViewReso
(2)支持靜態(tài)資源以及WebJars。
(3)自動(dòng)注冊(cè)了轉(zhuǎn)換器和格式化器。
(4)支持Http消息轉(zhuǎn)換器。
(5)自動(dòng)注冊(cè)了消息代碼解析器。
(6)支持靜態(tài)項(xiàng)目首頁index.html。
(7)支持定制應(yīng)用圖標(biāo)favicon.ico。
(8)自動(dòng)初始化Web數(shù)據(jù)綁定器ConfigurableWebBindinglnitializer。
Spring Boot 整合 Spring MVC進(jìn)行Web開發(fā)時(shí)提供了很多默認(rèn)配置,而且大多數(shù)時(shí)候使用默認(rèn)配置即可滿足開發(fā)需求。例如,Spring Boot整合Spring MVC進(jìn)行Web開發(fā)時(shí),不需要外配置視圖解析器。
Spring MVC功能擴(kuò)展實(shí)現(xiàn)
Spring Boot 整合 Spring MVC進(jìn)行Web開發(fā)時(shí)提供了很多的自動(dòng)化配置,但在實(shí)際開發(fā)中還需要開發(fā)者對(duì)一些功能進(jìn)行擴(kuò)展實(shí)現(xiàn)。下面我們通過一個(gè)具體的案例講解 Spring Boot整合Spring MVC框架實(shí)現(xiàn)Web開發(fā)的擴(kuò)展功能。
項(xiàng)目基礎(chǔ)環(huán)境搭建
使用Spring Inifializr方式創(chuàng)建名稱為springboot02的Spring Boot項(xiàng)目,并導(dǎo)入Web依賴和Thymeleaf依賴。
讓后我們啟動(dòng)該項(xiàng)目訪問http://localhost:8080/ 可以看到下面的界面就表示訪問成功,也代表我們項(xiàng)目創(chuàng)建成功。
我們?cè)趓esources下的templates包里創(chuàng)建一個(gè)登錄界面login.html
<!DOCTYPE html> <html> <head> <title>login</title> </head> <body> <form> <input type="text" name="username"> <input type="password" name="password"> <input type="submit" value="submit"> </form> </body> </html>
最后在com.hjk包下創(chuàng)建controller包并創(chuàng)建LoginController類
package com.hjk.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import java.util.Calendar; @Controller public class LoginController { /** * 獲取并封裝當(dāng)前年份跳轉(zhuǎn)到登錄頁login.html */ @GetMapping("/toLoginPage") public String toLoginPage(Model model){ model.addAttribute("currentYear", Calendar.getInstance().get(Calendar.YEAR)); return "login"; } }
功能擴(kuò)展實(shí)現(xiàn)
接下來使用Spring Boot 整合Spring MVC進(jìn)行Web開發(fā),實(shí)現(xiàn)簡單的頁面跳轉(zhuǎn)功能,這里我們將使用Spring Boot提供的WebMvcConfigurer接口編寫自定義配置,并對(duì)Web功能進(jìn)行適當(dāng)擴(kuò)展。我們?cè)谶@里分別演示視圖管理器和攔截器的實(shí)現(xiàn)。
注冊(cè)視圖管理器
在springboot項(xiàng)目的 com.hjk下創(chuàng)建config包并創(chuàng)建一個(gè)實(shí)現(xiàn)WebMvcConfigurer 接口的配置類 MyMVCconfig,用于對(duì) MVC框架功能進(jìn)行擴(kuò)展
package com.hjk.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import javax.annotation.Resource; @Configuration public class MyMVCconfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry){ registry.addViewController("/toLoginPage").setViewName("login"); registry.addViewController("/login.html").setViewName("login"); } }
- MMVCconig實(shí)現(xiàn)了接口 WebMvcConigurer 的addViewControllerse(ViewControllerRegistry registry)方法。在addViewControllers()方法內(nèi)部,使用ViewControllerRegistry的 addviewController()方法分別定義了“tologinPage”和“login.html”的請(qǐng)求控制,并使setViewName("login")方法將路徑映射為login.html頁面。
- 定制完MVC的視圖管理功能后,
- 就可以進(jìn)行效果測試了。為了演示這種定制效果,重啟chapter05項(xiàng)目,項(xiàng)目啟動(dòng)成功態(tài),在瀏覽器上分別訪問http://localhost:8080/toLoginPage和http://localhost:8080/login.htm 都可以訪問login.html頁面
- 使用WebMvcConfigurer接口定義的用戶請(qǐng)求控制方法也實(shí)現(xiàn)了用戶請(qǐng)求控制跳轉(zhuǎn)的效果,相比于傳統(tǒng)的請(qǐng)求處理方法而言,這種方法更加簡潔、直觀和方便。同時(shí)也可以看出,使用這種方式無法獲取后臺(tái)處理的數(shù)據(jù)。需要說明的是,使用WebMvcConfigurer 接口中的addViewControllers(ViewControllelRegistry registry)方法定制視圖控制,只適合較為簡單的無參數(shù)視圖Get方式請(qǐng)求,有參數(shù)或需要業(yè)務(wù)處理的跳轉(zhuǎn)需求,最好還是采用傳統(tǒng)方式處理請(qǐng)求。
注冊(cè)自定義攔截器
WebMvcConfigurer接口提供了許多MVC開發(fā)相關(guān)方法,添加攔截器方法addInterceptors(),添加格式化的器的方法addFormatters()我們這里實(shí)現(xiàn)攔截器的方法。
我們?cè)赾onfig包下創(chuàng)建一個(gè)自定義攔截器類MyInterceptor,代碼如下。
package com.hjk.config; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Calendar; @Component public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String uri = request.getRequestURI(); Object loginUser = request.getSession().getAttribute("loginUser"); if (uri.startsWith("/admin")&& null==loginUser){ try { response.sendRedirect("/toLoginPage"); } catch (IOException e) { e.printStackTrace(); } return false; } return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("攔截器攔截"); public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { }
- 自定義攔截器類Mylnterceptor實(shí)現(xiàn)了HandlerInterceptor接口。在preHandle()方法方法中,如果用戶請(qǐng)求以“/admin”開頭,即訪問如http://localhost:8080/admin 的地址則判斷用戶是否登錄,如果沒有登錄,則重定向到“hoLoginPage”請(qǐng)求對(duì)應(yīng)的登錄頁面。
- 在postHandle()方法中,在控制臺(tái)打印攔截器攔截。
然后在config包下自定義配置類MyMVCconfig中,重寫addlnterceptors()方法注冊(cè)自定義的攔截器。添加以下代碼。
@Autowired private MyInterceptor myInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(myInterceptor).addPathPatterns("/**").excludePathPatterns("/login.html"); }
- 先使用@Autowired注解引入自定義的 Mylnterceptor攔截器組件,然后重寫其中的 addinterceptors()方法注冊(cè)自定義的攔截器。在注冊(cè)自定義攔截器時(shí),使用addPathPatterns("/**)方法攔截所有路徑請(qǐng)求,excludePathPatterns("/login.htm")方法對(duì)“login.html”路徑的請(qǐng)求進(jìn)行了放行處理。
測試:我們可以訪問http://localhost:8080/admin 可以發(fā)現(xiàn)它重定向大toLoginPage界面了。
Spring整合Servlet三大組件
在這里我們使用組件注冊(cè)方式對(duì)Servlet、Filter、Listener三大組件進(jìn)行整合,我們只需要將自定義的組件通過ServletRegistrationBean、FilterRegistrationBean、ServletListenerRegistrationBean類注冊(cè)到容器中即可。
使用注冊(cè)方式整合
使用組件注冊(cè)方式整合Servlet
我們?cè)赾om.hjk包下創(chuàng)建servletComponent的包,在該包下創(chuàng)建MyServlet類并繼承HttpServlet類。
package com.hjk.servletCompont; import org.springframework.stereotype.Component; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component public class MyServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doGet(req, resp); } protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().write("hello MyServlet"); }
- @Component注解將MyServlet類作為組件注入Spring容器。MySeret類繼承自HttpServlet,通過HttpServletResponse對(duì)象向頁面輸出“hello MyServlet”。
創(chuàng)建 Servlet組件配置類。在項(xiàng)目com.hjk.confg包下創(chuàng)建一個(gè)Servlet組件配置類servietConfig,用來對(duì) Servlet相關(guān)組件進(jìn)行注冊(cè),
package com.hjk.config; import com.hjk.servletCompont.MyServlet; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class ServletConfig { @Bean public ServletRegistrationBean getServlet(MyServlet myServlet){ ServletRegistrationBean registrationBean = new ServletRegistrationBean(myServlet, "/myServlet"); return registrationBean; } }
- 使用@Configuration 注解將ServletConfig標(biāo)注為配置類,ServletConfig類內(nèi)部的 getServlet()方法用于注冊(cè)自定義的MyServlet,并返回 ServletRegistrationBean類型的Bean對(duì)象。
測試:項(xiàng)目啟動(dòng)成功后,在瀏覽器上訪問“http://localhost:8080/myServlet"myServlet并正常顯示數(shù)據(jù),說明 Spring Boot成功整合Servlet組件。
使用組件注冊(cè)方式整合Filter
在servletCompont包下創(chuàng)建一個(gè)MyFilter類并實(shí)現(xiàn)Filter接口,這個(gè)Filter的包別導(dǎo)錯(cuò)了
package com.hjk.servletCompont; import org.springframework.stereotype.Component; import javax.servlet.*; import java.io.IOException; @Component public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("hello MyFilter"); public void destroy() { }
在config包下的ServletConfig類中進(jìn)行注冊(cè),即在該類中添加方法。
@Bean public FilterRegistrationBean getFilter(MyFilter myFilter){ FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(myFilter); filterRegistrationBean.setUrlPatterns(Arrays.asList("/toLogin","/myFilter")); return filterRegistrationBean; }
- 使用 setUrilPatterns(Arrays.asList("/toLoginPage",/myFilter')方法定義了過濾的請(qǐng)求路徑
“/toLoginPage”和“/myFilter”,同時(shí)使用@Bean 注解將當(dāng)前組裝好的FilterRegistrationBea對(duì)象作為Bean組件返回。
測試:在瀏覽器上訪問“http://localhost:8080/myFilter”查看控制臺(tái)打印效果(由于沒有編寫對(duì)應(yīng)路徑的請(qǐng)求處理方法,所以瀏覽器會(huì)出現(xiàn)404 錯(cuò)誤頁面,這里重點(diǎn)關(guān)注控制臺(tái)即可),瀏覽器訪問“http://localhost:8080/
myFilter”時(shí),控制臺(tái)打印出了自定義 Filter中定義 圖5-6 使用組件注冊(cè)方式整合Filter的運(yùn)行結(jié)果的輸出語句“hello MyFilter”,這也就說明Spring Boot 整合自定義Filter 組件成功。
使用組件注冊(cè)方式整合 Listener
(1)創(chuàng)建自定義Listener類。在com.itheima.senleiComponent包下創(chuàng)建一個(gè)類MyListener實(shí)現(xiàn)ServletContextListener接口
package com.hjk.servletCompont; import org.springframework.stereotype.Component; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; @Component public class MyListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("contextnitialized..."); } public void contextDestroyed(ServletContextEvent sce) { System.out.println("contextDestroyed..."); }
在servletConfig添加注冊(cè)
@Bean public ServletListenerRegistrationBean getServletListener(MyListener myListener){ ServletListenerRegistrationBean servletListenerRegistrationBean = new ServletListenerRegistrationBean(myListener); return servletListenerRegistrationBean; }
需要說明的是,Servlet 容器提供了很多 Listener 接口,例如 ServletRequestListener、ritpSessionListener、ServletContextListener等,我們?cè)谧远xListener類時(shí)要根據(jù)自身需求選擇實(shí)現(xiàn)對(duì)應(yīng)接口即可。
測試:程序啟動(dòng)成功后,控制臺(tái)會(huì)打印出自定義Listener組件中定義的輸出語句“contextlnitialized..”。單擊圖中的【Exit】按鈕關(guān)閉當(dāng)前項(xiàng)目(注意,如果直接單擊紅色按鈕會(huì)強(qiáng)制關(guān)閉程序,瀏覽器就無法打印關(guān)閉監(jiān)聽信息),再次查看控制臺(tái)打印效果。
程序成功關(guān)閉后,控制臺(tái)打印出了自定義Listener組件中定義的輸出語句“contextDestroyed..”。通過效果演示,說明了Spring Boot整合自定義Listener組件成功。
文件上傳與下載
開發(fā)web應(yīng)用時(shí),文件上傳是很常見的一個(gè)需求,瀏覽器通過表單形式將文件以流的形式傳遞給服務(wù)器,服務(wù)器在對(duì)上傳的數(shù)據(jù)解析處理。
文件上傳
編寫上傳表單界面
這個(gè)表單界面名為upload.html,在templates文件夾下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>文件上傳</title> </head> <body> <div style="text-align: center"> <form action="/uploadFile" method="post" enctype="multipart/form-data"> 上傳:<input type="file" name="filename"/> <input type="submit" value="submit"/> </form> </div> </body> </html>
我們通過表單上傳文件,表單提交給uploadFile控制器,提交方式為post必須為這種方式,因?yàn)間et上傳比較少,必須包含enctype="multipart/form-data".
我們通過提交的地址也應(yīng)該清楚,我們肯定會(huì)寫一個(gè)uploadFile的控制器。
添加文件上傳的相關(guān)配置
我們?cè)赼pplication.properties文件中添加配置,上傳文件的大小限制。
## 文件最大限制為10mb,默認(rèn)為1mb spring.servlet.multipart.max-file-size=1MB
如果文件超過限制大小,會(huì)報(bào)錯(cuò)。
編寫控制器
我們?cè)赾om.hjk.controller包下船艦一個(gè)名為FileController的類,用于實(shí)現(xiàn)文件上傳的控制器。
我們這個(gè)文件上傳只是實(shí)現(xiàn)一個(gè)簡單的文件上傳,并沒有考慮上傳文件重名的情況,實(shí)際上重名的話會(huì)覆蓋之前的文件。要實(shí)現(xiàn)文件上傳,我們肯定要給它一個(gè)唯一名稱這個(gè)可以使用uuid實(shí)現(xiàn),這里也沒考慮文件存放位置問題,都是我自己把地址寫死了,這里我們就不實(shí)現(xiàn)了。
實(shí)現(xiàn)歷程:寫這個(gè)控制器的時(shí)候,我的代碼是正確的,前端文件也能提交,但是后端獲取的文件就是null,我也看了很多博客,有的說是沒有注冊(cè)multipartResolver這個(gè)Bean,有的說是版本問題等等,但是都沒有解決。最后一個(gè)不經(jīng)意的小細(xì)節(jié)導(dǎo)致了我這次的代碼不能獲取到文件。那就是我們有在(@RequestParam("filename") MultipartFile file)
前面加@RequestParam這個(gè)注解。反正我的這個(gè)是加上之后就能用了,我的這個(gè)springboot版本是2.6.6.至于真正原因現(xiàn)在不想思考了,等以后遇到再改吧。
- @RequestPara("filename")必須獲取參數(shù)名為filename的file參數(shù)
- @RequestParam()默認(rèn)為必傳屬性,可以通過@RequestParam(required = false)設(shè)置為非必傳。因?yàn)閞equired值默認(rèn)是true,所以默認(rèn)必傳
- @RequestParam("filename")或者@RequestParam(value = "filename")指定參數(shù)名
- @RequestParam(defaultValue = "0")指定參數(shù)默認(rèn)值
package com.hjk.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; @Controller public class FileController { @GetMapping("/toUpload") public String toUpload(){ return "upload"; } @RequestMapping(value = "/uploadFile",method = RequestMethod.POST) public String uploadFile(@RequestParam("filename") MultipartFile file){ String filename = file.getOriginalFilename(); String dirPath = "D:/file/"; File filePath = new File(dirPath); if (!filePath.exists()){ filePath.mkdir(); } try { file.transferTo(new File(dirPath+filename)); } catch (IOException e) { e.printStackTrace(); }
在這里我們提交三張圖片用于下面的文件下載
文件下載
文件下載很多框架都沒有進(jìn)行封裝處理,不同的瀏覽器解析處理不同,有可能出現(xiàn)亂碼情況。
在添加完依賴之后我們創(chuàng)建一個(gè)名為filedownload.html的html,一會(huì)用于編寫下載界面。
添加依賴
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency>
下載處理控制器
我們還是再FileController類里添加下載處理方法。直接在里面添加就行。
@GetMapping("/toDownload") public String toDownload(){ return "filedownload"; } @GetMapping("/download") public ResponseEntity<byte[]> fileDownload(String filename){ //指定下載地址文件路徑 String dirPath = "D:/file/"; //創(chuàng)建文件下載對(duì)象 File file = new File(dirPath + File.separator + filename); //設(shè)置響應(yīng)頭 HttpHeaders httpHeaders = new HttpHeaders(); //通知瀏覽器以下載方式打開 httpHeaders.setContentDispositionFormData("attachment",filename); //定義以流的形式下載返回文件 httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); try { return new ResponseEntity<>(FileUtils.readFileToByteArray(file),httpHeaders, HttpStatus.OK); } catch (IOException e) { e.printStackTrace(); return new ResponseEntity<byte[]>(e.getMessage().getBytes(), HttpStatus.EXPECTATION_FAILED); }
編寫前端代碼
<!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>0000001.jpg</td> <td><a th:href="@{/download(filename='0000001.jpg')}">下載文件</a> </td> </tr> <tr> <td>0000002.jpg</td> <td><a th:href="@{/download(filename='0000002.jpg')}">下載文件</a> </td> </tr> <tr> <td>0000003.jpg</td> <td><a th:href="@{/download(filename='0000003.jpg')}">下載文件</a> </td> </tr> </table> </body> </html>
我們這次使用了thymeleaf寫前端代碼。
實(shí)際上我們可能會(huì)遇到下載中文文件的問題,那樣可能會(huì)亂碼。
我么在這里寫一個(gè)解決中文亂碼的例子。例如:我把0000001.jpg改為"你好jpg"再重新部署下載,會(huì)發(fā)現(xiàn)名字為_.jpg
下面我們直接在我們?cè)趂ileController類的里面加一個(gè)getFileName方法,并修改fileDownload方法上做修改。
public String getFileName(HttpServletRequest request,String filename) throws Exception { String[] IEBrowserKeyWords = {"MSIE","Trident","Edge"}; String userAgent = request.getHeader("User-Agent"); for (String ieBrowserKeyWord : IEBrowserKeyWords) { if (userAgent.contains(ieBrowserKeyWord)){ return URLEncoder.encode(filename,"UTF-8").replace("+"," "); } } return new String(filename.getBytes(StandardCharsets.UTF_8),"ISO-8859-1"); } @GetMapping("/download") public ResponseEntity<byte[]> fileDownload(HttpServletRequest request,String filename) throws Exception { //指定下載地址文件路徑 String dirPath = "D:/file/"; //創(chuàng)建文件下載對(duì)象 File file = new File(dirPath + File.separator + filename); //設(shè)置響應(yīng)頭 HttpHeaders httpHeaders = new HttpHeaders(); //通知瀏覽器下載七千及性能轉(zhuǎn)碼 filename = getFileName(request,filename); //通知瀏覽器以下載方式打開 httpHeaders.setContentDispositionFormData("attachment",filename); //定義以流的形式下載返回文件 httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); try { return new ResponseEntity<>(FileUtils.readFileToByteArray(file),httpHeaders, HttpStatus.OK); } catch (IOException e) { e.printStackTrace(); return new ResponseEntity<byte[]>(e.getMessage().getBytes(), HttpStatus.EXPECTATION_FAILED);
SpringBoot的打包部署
springboot使用的嵌入式Servlet容器,所以默認(rèn)是以jar包打包的。也可以進(jìn)行war包打包,但是需要進(jìn)行一些配置。
jar包形式打包
我們?cè)趧?chuàng)建springboot項(xiàng)目是默認(rèn)會(huì)給我們導(dǎo)入maven的打包插件,如果沒有我們手動(dòng)加上即可。
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
雙擊package等待即可
等待完成,可以看到打包時(shí)間,存放jar包位置等信息。我們也可以在target包下查看打成的jar包。
啟動(dòng)jar包
我們可以在關(guān)閉已啟動(dòng)的springboot項(xiàng)目后,在idea控制臺(tái)輸入命令啟動(dòng)。
java -jar target\springboot02-0.0.1-SNAPSHOT.jar
我們也可以在系統(tǒng)自帶的終端窗口啟動(dòng)
war包形式打包
我們首先要把默認(rèn)打包方式修改為war包
<name>springboot02</name> <description>Demo project for Spring Boot</description> <packaging>war</packaging> <properties> <java.version>1.8</java.version> </properties>
導(dǎo)入外部Tomcat服務(wù)器
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency>
打開啟動(dòng)類,繼承springbootServletInitializer類
package com.hjk; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; @ServletComponentScan @SpringBootApplication public class Springboot02Application extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(Springboot02Application.class, args); } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { return builder.sources(Springboot02Application.class); } }
然后就和jar包方式一樣了,雙擊package,等待打包完成。
war包的部署
war包的部署相比于jar包比較麻煩,我們需要外部的服務(wù)器,我們需要把war包復(fù)制到tomcat安裝目錄下的webapps目錄中,執(zhí)行目錄里的startup.bat命令啟動(dòng)war包,這樣我們就完成了。
總結(jié)
我們對(duì)MVC進(jìn)行了功能擴(kuò)展和定制、servlet三大組件定制、文件上傳和下載、以及兩種方式打包部署。
到此這篇關(guān)于SpringBoot實(shí)現(xiàn)WEB的常用功能的文章就介紹到這了,更多相關(guān)springboot web功能內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java 多線程學(xué)習(xí)詳細(xì)總結(jié)
本文主要介紹 Java 多線程的知識(shí)資料,這里整理了詳細(xì)的多線程內(nèi)容,及簡單實(shí)現(xiàn)代碼,有需要的朋友可以參考下2016-09-09如何修改logback.xml配置文件在resource以外的位置
這篇文章主要介紹了如何修改logback.xml配置文件在resource以外的位置,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-02-02Springboot設(shè)置統(tǒng)一的返回格式的方法步驟
在我們應(yīng)用中我們通常與前端交互使用json格式,設(shè)置統(tǒng)一的返回json 格式是非常必要的,本文主要介紹了Springboot設(shè)置統(tǒng)一的返回格式的方法步驟,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01java String、Json對(duì)象與byte數(shù)組轉(zhuǎn)換方式
這篇文章主要介紹了java String、Json對(duì)象與byte數(shù)組轉(zhuǎn)換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07java獲取當(dāng)前時(shí)間的四種方法代碼實(shí)例
這篇文章主要介紹了java獲取當(dāng)前時(shí)間的四種方法代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09