一. 創(chuàng)建簡單工程
網(wǎng)頁SpringBoot
進(jìn)入[SpringBoot網(wǎng)站][],選擇自己需要的依賴(Web,Velocity,AOP),生成工程,減少自己配置的工作量。
打開Idea,導(dǎo)入工程,然后靜靜等待一會(huì)即可。
[SpringBoot網(wǎng)站]:http://start.spring.io/
- 簡單結(jié)構(gòu)
web請(qǐng)求--->控制器---->服務(wù)---->DAO(--->數(shù)據(jù)庫) - 注解和對(duì)應(yīng)方法參數(shù)
//相對(duì)路徑,參數(shù)value和path意義相同,可以寫多個(gè),{"/path1","/path2"}
@RequestMapping(value = {"/profile/{groupId}/{userId}"})
// 該注解用于將Controller的方法返回的對(duì)象,通過適當(dāng)?shù)腍ttpMessageConverter轉(zhuǎn)換為指定格式后,寫入到Response對(duì)象的body數(shù)據(jù)區(qū)。
//根據(jù)返回的字符串,去資源文件夾下找匹配的文件,否則直接返回字符串,
@ResponseBody
//路徑參數(shù)用PathVariable,請(qǐng)求參數(shù)用RequestParam
public String profile(@PathVariable("groupId") String groupId,
@PathVariable("userId") int userId,
@RequestParam(value = "type", defaultValue = "1") int type,
@RequestParam(value = "key", defaultValue = "nowcoder") String key) {
}
- Velocity 模板語法
##獲取變量值
$!{變量/表達(dá)式}
#*多行
注釋*#
##.index 0開始索引,.count為計(jì)數(shù)
#foreach($color in $colors)
Color$!(foreach.count)/$(foreach.index):$!(color)
#
- 資源文件
- 靜態(tài):static/templates css和images
- 模板文件: templates xxx.vn
a. 模板文件例子1
//java文件
@RequestMapping(value = {"/vm"})
//model 引入變量,多次使用時(shí)模板html中可以替換該值
public String news(Model model){
model.addAttribute("value1", "vv1");
List<String> colors = Arrays.asList(new String[]{"RED", "GREEN", "BLUE"});
Map<String,String> map = new HashMap<String,String>();
for (int i = 0; i < 4; i++) {
map.put(String.valueOf(i), String.valueOf(i * i));
}
model.addAttribute("colors", colors);
model.addAttribute("map", map);
return "news";
}
//然后可以在模板文件夾下的news.vm文件中調(diào)用value1變量
<html>
<body>
<pre>
Hello, VM
##你看不到我(注解格式)
$!{value1}##有則輸出,無則空行
$!{value2}
${value3}##完整輸出該字符
##for循環(huán)
#foreach ($color in $colors)
Color $!{foreach.index}/$!{foreach.count}:$!{color}
#end
#foreach($key in $map.keySet())
Number $!{foreach.index}/$!{foreach.count}:$!{key} $map.get($key)
#end
#foreach($kv in $map.entrySet())
Number $!{foreach.index}/$!{foreach.count}:$!{kv.key} $!{kv.value}
#end
User: $!{user.name}
User: $!{user.getName()}
#set($hello = "hello") ##類似宏定義
#set($hworld1 = "$!{hello} world")
#set($hworld2 = '$!{hello} world')
hworld1: $hworld1
hworld2: $hworld2
</pre>
</body>
</html>
b. include和parse
##header.vm
Title <h>$!title</h>
##news.vm
##設(shè)置title變量值
#set($title = "nowcoder")
Include: #include("header.vm")
Parse: #parse("header.vm")
/*輸出 Include: TiTle $!title Parse: TiTle nowcoder
說明,include嵌入文件,parse還會(huì)解析其中的變量*/
c. macro
#macro(render_color, $color, $index)
Color By Macro $index, $color
#end
#foreach ($color in $colors)
#render_color($color, $foreach.index)
#end
- 請(qǐng)求和響應(yīng)
a. 請(qǐng)求
參數(shù)解析,cookie讀取,http請(qǐng)求字段和文件上傳
@RequestMapping(value = {"/request"})
@ResponseBody
//一般都設(shè)置這三個(gè)參數(shù)
public String request(HttpServletRequest req,
HttpServletResponse resp,
HttpSession session){
StringBuilder sb = new StringBuilder();
//獲取請(qǐng)求頭的名字,返回枚舉類型
Enumeration<String> headerNames = req.getHeaderNames();
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
sb.append(name + ":" + req.getHeader(name) + "<br>");
}
return sb.toString();
}
b. 響應(yīng)
頁面內(nèi)容返回,cookie下發(fā),http字段設(shè)置,headers
@RequestMapping(value = {"/response"})
@ResponseBody
public String response(@CookieValue(value = "nowcoderid", defaultValue = "a") String nowcoderId,
@RequestParam(value = "key", defaultValue = "key") String key,
@RequestParam(value = "value", defaultValue = "value") String value,
HttpServletResponse resp) {
resp.addCookie(new Cookie(key,value));
resp.addHeader(key, value);
return "NowCoderId From COOkie: " + nowcoderId;}
- 重定向
301:永久轉(zhuǎn)移,第一次訪問后記錄在瀏覽器中,再次訪問時(shí),直接跳重定向的路徑,而不用先訪問原地址。
302:臨時(shí)轉(zhuǎn)移,直接的方式return "redirect:/"
@RequestMapping("/redirect/{code}")
public RedirectView redirect(@PathVariable("code") int code) {
RedirectView red = new RedirectView("/",true);
if (code == 301) {
red.setStatusCode(HttpStatus.MOVED_PERMANENTLY);
}
return red;
}
- 錯(cuò)誤處理
@RequestMapping("/admin")
@ResponseBodypublic
String admin(@RequestParam(value = "key", required = false) String key){
if ("admin".equals(key)) {
return "Hello admin! ";
}
//沒寫異常處理,拋出異常,類似沒找到資源,
throw new IllegalArgumentException("Key 錯(cuò)誤");
}
/*結(jié)果:Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Wed Nov 16 14:03:51 CST 2016
There was an unexpected error (type=Internal Server Error, status=500).
Key 錯(cuò)誤*/
//寫異常處理
@ExceptionHandler()
@ResponseBody
public String error(Exception e) {
return "error: " + e.getMessage();
}
//結(jié)果:error: Key 錯(cuò)誤
- IoC:控制反轉(zhuǎn)分成兩種類型,依賴注入(DI)和依賴查找(DL),前者應(yīng)用比較廣泛,IoC一般指前者
//常規(guī)方式,通過構(gòu)造器傳參,類中的其他方法就可以調(diào)用
//Service.java
public String service(){
return "service()";
}
//Application.java
public String application(){
private Service service;
public Application(Service service){
this.service = service;
}
}
//注解方式,通過使用注解,spring自動(dòng)匹配,可以直接調(diào)用,更方便
//Service.java
@Service
public String service(){
return "service()";
}
//Application.java
public String application(){
@AutoWired
private Service service;
}
}
- AOP:面向切面編程,所有業(yè)務(wù)都要處理的業(yè)務(wù),比如log服務(wù)
@Aspect
@Component
public class LogAspect {
private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
@Before("execution(* com.nowcoder.controller.*Controller.*(..))")
public void beforeMethod(JoinPoint joinPoint) {
StringBuilder sb = new StringBuilder();
for (Object arg : joinPoint.getArgs()) {
sb.append("arg:" + arg.toString() + "|");
}
logger.info("before time: " + new Date());
logger.info("before method: "+ sb.toString());
}
@After("execution(* com.nowcoder.controller.IndexController.*(..))")
public void afterMethod() {
logger.info("after method: ");
}
}