目錄
1.Web開發
1.1簡介
1.2SpringBoot對靜態資源的映射規則
1.3模板引擎
1.3.1引入thymeleaf;
1.3.2Thymeleaf語法
1.3.2.1標準表達式語法
????????1.變量表達式
1.3.2.2表達式支持的語法
1.3.2.3常用的thymeleaf標簽
1.4Springboot整合springmvc
1.4.1Springmvc的自動解管理
1.4.1.1中央轉發器
1.4.1.2控制器
1.4.1.3視圖解析器自動管理
1.4.1.4靜態資源訪問
1.4.1.5消息轉換和格式化
1.4.1.6歡迎頁面的自動配置
1.4.2Springboot擴展springmvc?
1.4.2.1在容器中注冊視圖控制器(請求轉發)
1.4.2.2注冊格式化器
1.4.2.3消息轉換器擴展fastjson
1.4.2.4攔截器注冊
1.5配置嵌入式服務器
1.5.1如何定制和修改Servlet容器的相關配置;
1.5.2注冊Servlet三大組件【Servlet、Filter、Listener】
1.6使用外置的Servlet容器
1.Web開發
1.1簡介
使用SpringBoot;
1)、創建SpringBoot應用,選中我們需要的模塊;
2)、SpringBoot已經默認將這些場景配置好了,只需要在配置文件中指定少量配置就可以運行起來
3)、自己編寫業務代碼;
自動配置原理?
這個場景SpringBoot幫我們配置了什么?能不能修改?能修改哪些配置?能不能擴展?xxx
1.2SpringBoot對靜態資源的映射規則
@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties implements ResourceLoaderAware {
//可以設置和靜態資源有關的參數,緩存時間等
WebMvcAuotConfiguration:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {if (!this.resourceProperties.isAddMappings()) {logger.debug("Default resource handling disabled");return;}
Integer cachePeriod = this.resourceProperties.getCachePeriod();
if (!registry.hasMappingForPattern("/webjars/**")) {customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META‐INF/resources/webjars/").setCachePeriod(cachePeriod));
}
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
//靜態資源文件夾映射
if (!registry.hasMappingForPattern(staticPathPattern)) {customizeResourceHandlerRegistration(registry.
addResourceHandler(staticPathPattern).addResourceLocations(this.resourceProperties.getStaticLocations()).setCachePeriod(cachePeriod));
}
} /
/配置歡迎頁映射
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ResourceProperties resourceProperties) {return new WelcomePageHandlerMapping(resourceProperties.getWelcomePage(),
this.mvcProperties.getStaticPathPattern());
}
//配置喜歡的圖標
@Configuration
@ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true)
public static class FaviconConfiguration {private final ResourceProperties resourceProperties;public FaviconConfiguration(ResourceProperties resourceProperties) {this.resourceProperties = resourceProperties;
}@Bean
public SimpleUrlHandlerMapping faviconHandlerMapping() {SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);//所有 **/favicon.icomapping.setUrlMap(Collections.singletonMap("**/favicon.ico",
faviconRequestHandler());
return mapping;
}
@Bean
public ResourceHttpRequestHandler faviconRequestHandler() {ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();requestHandler.setLocations(this.resourceProperties.getFaviconLocations());return requestHandler;}
}
1)、所有?/webjars/** ,都去?classpath:/META-INF/resources/webjars/ 找資源;
webjars:以jar包的方式引入靜態資源;WebJars - Web Libraries in Jars
?
????????localhost:8080/webjars/jquery/3.3.1/jquery.js?
<!‐‐引入jquery‐webjar‐‐>在訪問的時候只需要寫webjars下面資源的名稱即可
<dependency><groupId>org.webjars</groupId><artifactId>jquery</artifactId><version>3.3.1</version>
</dependency>
2)、"/**" 訪問當前項目的任何資源,都去(靜態資源的文件夾)找映射
"classpath:/META‐INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/"
"/":當前項目的根路徑
localhost:8080/abc === 去靜態資源文件夾里面找abc
3)、歡迎頁;?靜態資源文件夾下的所有index.html頁面;被"/**"映射;
localhost:8080/ 找index頁面
1.3模板引擎
JSP、Velocity、Freemarker、Thymeleaf
SpringBoot推薦的Thymeleaf;
語法更簡單,功能更強大;
1.3.1引入thymeleaf;
????????在pom.xml中引入
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
????????從spring父文件中能看到Springboot2.0.1所使用的thymeleaf版本是3.0.9
????????springBoot啟動的時候會自動配置
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration
????????從ThymeleafAutoConfiguration的源代碼中我們可以得知ThymeleafProperties中配置了Thymeleaf的規則
public class ThymeleafProperties {private static final Charset DEFAULT_ENCODING;public static final String DEFAULT_PREFIX = "classpath:/templates/";public static final String DEFAULT_SUFFIX = ".html";private boolean checkTemplate = true;private boolean checkTemplateLocation = true;private String prefix = "classpath:/templates/";private String suffix = ".html";private String mode = "HTML";private Charset encoding;private boolean cache;
}
我們使用html作為模板,而且默認的前綴是放在classpath:/templates/下,后綴是.html
當然這些屬性我們都可以通過application.properties來修改。我們采用默認即可。
示例:
- 在templates下創建一個success.html
- 在html中引入thymeleaf的命名空間
<html lang="en" xmlns:th="http://www.thymeleaf.org"> - 創建一個Controller提供一個訪問的方法
@RequestMapping("/success") public String hello(Model model){model.addAttribute("hello","<h1>zhangsan</h1>");return "success"; }
- 在thymeleaf模板中取值
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head><title>Title</title> </head> <body> <div th:text="${hello}"> </div> </body> </html>
1.3.2Thymeleaf語法
1.3.2.1標準表達式語法
????????1.變量表達式
變量表達式即OGNL表達式或Spring EL表達式(在Spring術語中也叫model attributes)。如下所示:?${session.user.name}
它們將以HTML標簽的一個屬性來表示:
<span th:text="${book.author.name}">
????????2.選擇(星號)表達式
????????選擇表達式很像變量表達式,不過它們用一個預先選擇的對象來代替上下文變量容器(map)來執行,如下:?*{customer.name}
????????被指定的object由th:object屬性定義:
<div th:object="${book}"> ... <span th:text="*{title}">...</span> ...
</div>
????????3.文字國際化表達式
????????文字國際化表達式允許我們從一個外部文件獲取區域文字信息(.properties),用Key索引Value,還可以提供一組參數(可選).
#{main.title}
????????4.URL表達式
URL表達式指的是把一個有用的上下文或回話信息添加到URL,這個過程經常被叫做URL重寫。不需要指定項目名字
@{/order/list}?
URL還可以設置參數:
@{/order/details(id=${orderId})}?
讓我們看這些表達式:
<form th:action="@{/createOrder}">
<a href="main.html" rel="external nofollow" th:href="@{/main}" rel="external n
1.3.2.2表達式支持的語法
字面(Literals)
- 文本文字(Text literals): 'one text', 'Another one!',…
- 數字文本(Number literals): 0, 34, 3.0, 12.3,…
- 布爾文本(Boolean literals): true, false
- 空(Null literal): null
- 文字標記(Literal tokens): one, sometext, main,…
文本操作(Text operations)
- 字符串連接(String concatenation): +
- 文本替換(Literal substitutions): |The name is ${name}|
算術運算(Arithmetic operations)
- 二元運算符(Binary operators): +, -, *, /, %
- 減號(單目運算符)Minus sign (unary operator): -
布爾操作(Boolean operations)
- 二元運算符(Binary operators):and, or
- 布爾否定(一元運算符)Boolean negation (unary operator):!, not
比較和等價(Comparisons and equality)
- 比較(Comparators): >, <, >=, <= (gt, lt, ge, le)
- 等值運算符(Equality operators):==, != (eq, ne)
條件運算符(Conditional operators)
If-then: (if) ? (then)
If-then-else: (if) ? (then) : (else)
Default: (value) ?: (defaultvalue)
示例代碼:
'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ?: 'Unknown'))
1.3.2.3常用的thymeleaf標簽
關鍵字 | 功能介紹 | 案例 |
th:id | 替換id | <input th:id="'xxx' + ${collect.id}"/> |
th:text | 文本替換 | <p th:text="${collect.description}">description</p> |
th:utext | 支持html的文本替換 | <p th:utext="${htmlcontent}">conten</p> |
th:object | 替換對象 | <div th:object="${session.user}"> |
th:value | 屬性賦值 | <input th:value="${user.name}" /> |
th:onclick | 點擊事件 | th:οnclick="'getCollect()'" |
th:each | 屬性賦值 | tr th:each="user,userStat:${users}"> |
th:if | 判斷條件 | <a th:if="${userId == collect.userId}" > |
th:unless | 和th:if判斷相反 | <a th:href="@{/login}" rel="external nofollow" rel="external nofollow" rel="external nofollow" th:unless=${session.user != null}>Login</a> |
th:href | 鏈接地址 | <a th:href="@{/login}" rel="external nofollow" rel="external nofollow" rel="external nofollow" th:unless=${session.user != null}>Login</a> /> |
th:switch | 多路選擇 配合th:case 使用 | <div th:switch="${user.role}"> |
th:case | th:switch的一個分支 | <p th:case="'admin'">User is an administrator</p> |
th:fragment | 布局標簽,定義一個代碼片段,方便其它地方引用 | <div th:fragment="alert"> |
th:include | 布局標簽,替換內容到引入的文件 | <head th:include="layout :: htmlhead" th:with="title='xx'"></head> /> |
th:replace | 布局標簽,替換整個標簽到引入的文件 | <div th:replace="fragments/header :: title"></div> |
th:selected | selected選擇框 選中 | th:selected="(${xxx.id} == ${configObj.dd})" |
th:src | 圖片類地址引入 | <img class="img-responsive" alt="App Logo" th:src="@{/img/logo.png}" /> |
th:action | 表單提交的地址 | <form action="subscribe.html" th:action="@{/subscribe}"> |
????????標簽測試
????????模板:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><title>Title</title>
</head>
<body>
<div th:text="${hello}" th:id="${hello.toUpperCase()}">xxxx</div>
<input th:value="${user.getUsername()}">
<hr>
<div th:object="${user}">
<span th:text="*{username}"></span></div><a th:href="" th:if="${user.getAge() == 2}" >年齡</a><a th:class="${user.getAge() > 2}?'class1':'class2'" >年齡</a><p th:if="${user.score >= 60 and user.score < 85}">B</p>
<p th:if="${user.score < 60}">C</p>
<p th:if="${user.score > 85}">優秀</p><span th:switch="${user.gender}"><p th:case="1">男</p><p th:case="2">女</p>
</span><table><tr th:each="a,aState:${uList}"><td th:text="${a.username}"></td><td th:text="${a.password}"></td><td th:text="${aState.index}"></td></tr>
</table></body>
</html>
????????Controller中給數據
@RequestMapping("/success")
public String hello(HttpServletRequest req, HttpSession httpSession, Model model){model.addAttribute("hello","<h1>renliang</h1>");User user = new User();user.setPassword("111");user.setUsername("renliang");user.setAge(1);user.setScore(78);user.setGender(2);List<User> uList = new ArrayList<>();for (int i = 0; i < 10; i++){User u = new User();u.setUsername("renliang"+i);u.setPassword("111"+i);uList.add(u);}// httpSession.setAttribute("user", user);model.addAttribute("user", user);model.addAttribute("uList", uList);return "success";
}
1.4Springboot整合springmvc
? ??https://docs.spring.io/spring-boot/docs/2.0.2.RELEASE/reference/htmlsingle/#boot-features-spring-mvc
????????學習springmvc和springboot的自動配置我們必須對springmvc的組件足夠了解,起碼知道怎么用。Springmvc的組件基本都被springboot來做了自動的配置。
1.4.1Springmvc的自動解管理
- 中央轉發器(DispatcherServlet)
- 控制器
- 視圖解析器
- 靜態資源訪問
- 消息轉換器
- 格式化
- 靜態資源管理
-
1.4.1.1中央轉發器
-
????????Xml無需配置
-
<servlet><servlet-name>chapter2</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><load-on-startup>1</load-on-startup> </servlet> <servlet-mapping><servlet-name>chapter2</servlet-name><url-pattern>/</url-pattern> </servlet-mapping>
????????中央轉發器被springboot自動接管,不再需要我們在web.xml中配置,我們現在的項目也不是web項目,也不存在web.xml,
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
-
-
1.4.1.2控制器
????????控制器Controller在springboot的注解掃描范圍內自動管理。
1.4.1.3視圖解析器自動管理
Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
ContentNegotiatingViewResolver:組合所有的視圖解析器的;
曾經的配置文件無需再配
<bean id="de" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> |
????????源碼:
public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();resolver.setContentNegotiationManager((ContentNegotiationManager)beanFactory.getBean(ContentNegotiationManager.class));resolver.setOrder(-2147483648);return resolver;
}
????????當我們做文件上傳的時候我們也會發現multipartResolver是自動被配置好的頁面
<form action="/upload" method="post" enctype="multipart/form-data"><input name="pic" type="file"><input type="submit">
</form>
????????Controller
@ResponseBody
@RequestMapping("/upload")
public String upload(@RequestParam("pic")MultipartFile file, HttpServletRequest request){String contentType = file.getContentType();String fileName = file.getOriginalFilename();/*System.out.println("fileName-->" + fileName);System.out.println("getContentType-->" + contentType);*///String filePath = request.getSession().getServletContext().getRealPath("imgupload/");String filePath = "D:/imgup/";try {this.uploadFile(file.getBytes(), filePath, fileName);} catch (Exception e) {// TODO: handle exception}return "success";
}public static void uploadFile(byte[] file, String filePath, String fileName) throws Exception {File targetFile = new File(filePath);if(!targetFile.exists()){targetFile.mkdirs();}FileOutputStream out = new FileOutputStream(filePath+fileName);out.write(file);out.flush();out.close();
}
文件上傳大小可以通過配置來修改
打開application.properties, 默認限制是10MB,我們可以任意修改
1.4.1.4靜態資源訪問
????????參見4.2
1.4.1.5消息轉換和格式化
????????Springboot自動配置了消息轉換器
????????格式化轉換器的自動注冊
????????時間類型我們可以在這里修改
????????在配置文件中指定好時間的模式我們就可以輸入了
1.4.1.6歡迎頁面的自動配置
????????Springboot自動指定resources下的index.html
1.4.2Springboot擴展springmvc?
????????在實際開發中springboot并非完全自動化,很多跟業務相關我們需要自己擴展,springboot給我提供了接口。
????????我們可以來通過實現WebMvcConfigurer接口來擴展
public interface WebMvcConfigurer {default void configurePathMatch(PathMatchConfigurer configurer) {}default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {}default void configureAsyncSupport(AsyncSupportConfigurer configurer) {}default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {}default void addFormatters(FormatterRegistry registry) {}default void addInterceptors(InterceptorRegistry registry) {}default void addResourceHandlers(ResourceHandlerRegistry registry) {}default void addCorsMappings(CorsRegistry registry) {}default void addViewControllers(ViewControllerRegistry registry) {}default void configureViewResolvers(ViewResolverRegistry registry) {}default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {}default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {}default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {}default void extendMessageConverters(List<HttpMessageConverter<?>> converters) {}default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {}default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {}@Nullabledefault Validator getValidator() {return null;}@Nullabledefault MessageCodesResolver getMessageCodesResolver() {return null;}
}
1.4.2.1在容器中注冊視圖控制器(請求轉發)
????????創建一個MyMVCCofnig實現WebMvcConfigurer接口,實現一下addViewControllers方法,我們完成通過/tx訪問,轉發到success.html的工作
@Configuration
public class MyMVCCofnig implements WebMvcConfigurer{@Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController("/tx").setViewName("success");}
}
1.4.2.2注冊格式化器
????????用來可以對請求過來的日期格式化的字符串來做定制化。當然通過application.properties配置也可以辦到。
@Override
public void addFormatters(FormatterRegistry registry) {registry.addFormatter(new Formatter<Date>() {@Overridepublic String print(Date date, Locale locale) {return null;}@Overridepublic Date parse(String s, Locale locale) throws ParseException {return new SimpleDateFormat("yyyy-MM-dd").parse(s);}});
}
1.4.2.3消息轉換器擴展fastjson
????????在pom.xml中引入fastjson
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.47</version>
</dependency>
????????配置消息轉換器,添加fastjson
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {FastJsonHttpMessageConverter fc = new FastJsonHttpMessageConverter();FastJsonConfig fastJsonConfig = new FastJsonConfig();fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);fc.setFastJsonConfig(fastJsonConfig);converters.add(fc);
}
????????在實體類上可以繼續控制
public class User
{private String username;private String password;private int age;private int score;private int gender;@JSONField(format = "yyyy-MM-dd")private Date date;}
1.4.2.4攔截器注冊
1.創建攔截器
public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("前置攔截");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("后置攔截");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("最終攔截");}
}
攔截器注冊
@Override
public void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/hello2");
}
1.5配置嵌入式服務器
1.5.1如何定制和修改Servlet容器的相關配置;
修改和server有關的配置(ServerProperties);
server.port=8081
server.context‐path=/tx
server.tomcat.uri‐encoding=UTF‐8
1.5.2注冊Servlet三大組件【Servlet、Filter、Listener】
????????由于SpringBoot默認是以jar包的方式啟動嵌入式的Servlet容器來啟動SpringBoot的web應用,沒有web.xml文件。
????????1.servlet
//注冊三大組件
@Bean
public ServletRegistrationBean myServlet(){ServletRegistrationBean registrationBean = new ServletRegistrationBean(newMyServlet(),"/myServlet");return registrationBean;
}
????????2.?FilterRegistrationBean
@Bean
public FilterRegistrationBean myFilter(){FilterRegistrationBean registrationBean = new FilterRegistrationBean();registrationBean.setFilter(new MyFilter());registrationBean.setUrlPatterns(Arrays.asList("/hello","/myServlet"));return registrationBean;
}
????????3.?ServletListenerRegistrationBean
@Bean
public ServletListenerRegistrationBean myListener(){ServletListenerRegistrationBean<MyListener> registrationBean = newServletListenerRegistrationBean<>(new MyListener());return registrationBean;
}
SpringBoot幫我們自動SpringMVC的時候,自動的注冊SpringMVC的前端控制器;DispatcherServlet;
DispatcherServletAutoConfiguration中:
@Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)
@ConditionalOnBean(value = DispatcherServlet.class, name =
DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public ServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet) {ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet, this.serverProperties.getServletMapping());//默認攔截: / 所有請求;包靜態資源,但是不攔截jsp請求; /*會攔截jsp//可以通過server.servletPath來修改SpringMVC前端控制器默認攔截的請求路徑registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);registration.setLoadOnStartup(this.webMvcProperties.getServlet().getLoadOnStartup());if (this.multipartConfig != null) {registration.setMultipartConfig(this.multipartConfig);}return registration;
}
1.6使用外置的Servlet容器
嵌入式Servlet容器:應用打成可執行的jar
優點:簡單、便攜;
缺點:默認不支持JSP、優化定制比較復雜.;
????????外置的Servlet容器:外面安裝Tomcat---應用war包的方式打包;
步驟
1)、必須創建一個war項目;(利用idea創建好目錄結構)
2)、將嵌入式的Tomcat指定為provided;?
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring‐boot‐starter‐tomcat</artifactId><scope>provided</scope>
</dependency>
3)配置項目的目錄結構
?
4)部署Tomcat
3)、必須編寫一個SpringBootServletInitializer的子類,并調用configure方法
public class ServletInitializer extends SpringBootServletInitializer {@Overrideprotected SpringApplicationBuilder configure(SpringApplicationBuilder application) {//傳入SpringBoot應用的主程序return application.sources(SpringBoot04WebJspApplication.class);}
}
4)、啟動服務器就可以使用;
原理
jar包:執行SpringBoot主類的main方法,啟動ioc容器,創建嵌入式的Servlet容器;
war包:啟動服務器,服務器啟動SpringBoot應用【SpringBootServletInitializer】,啟動ioc容器;