velocity
標(biāo)簽內(nèi)使用判斷語(yǔ)句汰聋,修改標(biāo)簽屬性
<li #if(${module}=="users") class="active" #end><a href="/admin/users">賬號(hào)管理</a></li>
使用模板布局,并傳輸參數(shù)
#set($module="users")
#parse( '/admin/nav_bar.html' )
讓velocity解析url上的參數(shù)
在application.properties上添加配置:
spring.velocity.exposeRequestAttributes=true
velocity頁(yè)面中文亂碼問(wèn)題
需要添加以下三個(gè)配置項(xiàng)
spring.velocity.charset=UTF-8
spring.velocity.properties.input.encoding=UTF-8
spring.velocity.properties.output.encoding=UTF-8
velocity 中的null值處理
后臺(tái)傳的值為null虾啦,默認(rèn)情況下,velocity會(huì)把變量 ${variable} 直接顯示出來(lái),而不會(huì)解析為空字符串纹冤。
如果要解析為空字符串,需把變量寫(xiě)成 $!{variable}
可以用#if("$!{varName}" == "")
來(lái)判斷變量空值购公。
Spring-boot
全局配置
Spring MVC 攔截器
Spring MVC中攔截器是實(shí)現(xiàn)了HandlerInterceptor接口的Bean
-
preHandle()
:預(yù)處理回調(diào)方法萌京,若方法返回值為true,請(qǐng)求繼續(xù)(調(diào)用下一個(gè)攔截器或處理器方法)宏浩;若方法返回值為false知残,請(qǐng)求處理流程中斷,不會(huì)繼續(xù)調(diào)用其他的攔截器或處理器方法比庄,此時(shí)需要通過(guò)response產(chǎn)生響應(yīng)求妹; -
postHandle()
:后處理回調(diào)方法,實(shí)現(xiàn)處理器的后處理(但在渲染視圖之前)佳窑,此時(shí)可以通過(guò)modelAndView對(duì)模型數(shù)據(jù)進(jìn)行處理或?qū)σ晥D進(jìn)行處理 -
afterCompletion()
:整個(gè)請(qǐng)求處理完畢回調(diào)方法制恍,即在視圖渲染完畢時(shí)調(diào)用
大部分時(shí)候可能只需要實(shí)現(xiàn)其中的preHandle()
方法。
public class Interceptor extends HandlerInterceptorAdapter {
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
System.out.println("This is interceptor.");
return true;
}
}
Spring 異常處理
- 不要在``@Controller中自己進(jìn)行異常處理邏輯神凑。即使它只是一個(gè)Controller相關(guān)的特定異常净神,在
@Controller
中添加一個(gè)@ExceptionHandler
方法處理。 - 對(duì)于自定義的異常溉委,可以考慮對(duì)其加上
@ResponseStatus
注解 - 使用
@ControllerAdvice
處理通用異常(例如資源不存在鹃唯、資源存在沖突等)
Controller部分
URL處理方法
@Controller
注解標(biāo)記這是個(gè)控制器。
@RequestMapping("/hello")
注解可以配置請(qǐng)求路由瓣喊,每一個(gè)類(lèi)中都可以包含一個(gè)或多個(gè)@RequestMapping注解的方法坡慌。可以標(biāo)記在類(lèi)上藻三,也可以標(biāo)記在方法上洪橘。
@ResponseBody
注解表示處理函數(shù)直接將函數(shù)的返回值傳回到瀏覽器端顯示絮爷。如果不標(biāo)記該注解,則默認(rèn)會(huì)根據(jù)返回的字符串去模板目錄下查詢(xún)同名的HTML模板文件梨树。
@RestController
注解:在Controller上標(biāo)注了@RestController
,這樣相當(dāng)于Controller的所有方法都標(biāo)注了@ResponseBody坑夯。Spring 4.x中支持。
URL中的變量可以用{variableName}
來(lái)表示抡四,同時(shí)在方法的參數(shù)中加上@PathVariable("variableName")
柜蜈,那么當(dāng)請(qǐng)求被轉(zhuǎn)發(fā)給該方法處理時(shí),對(duì)應(yīng)的URL中的變量會(huì)被自動(dòng)賦值給被@PathVariable
注解的參數(shù)(能夠自動(dòng)根據(jù)參數(shù)類(lèi)型賦值)指巡。
如果用@RequestParam
注解可以解析HTTP請(qǐng)求中Body中的內(nèi)容淑履。
@RequestMapping("/posts/{id}")
public String post(@PathVariable("id") int id) {
return String.format("post %d", id);
}
@RequestMapping("/test")
public String test(@RequestParam("name") String name){
return "name=" + name;
}
頁(yè)面redirect重定向
Spring MVC通過(guò)返回值中添加redirect:
前綴來(lái)完成此類(lèi)重定向,如果需要封裝參數(shù)藻雪,可以使用RedirectView秘噪。
@RequestMapping(value = "/", method = RequestMethod.POST)
public String create(@Valid Post post, BindingResult result) {
Post p = Data.add(post);
return "redirect:/posts/" + p.getId();
}
forward跳轉(zhuǎn)后給頁(yè)面?zhèn)鲄?/h4>
@RequestMapping(value = "/create")
public String create(@Valid Post post, HttpServletRequest request) {
request.setAttribute("status",1);
return "forward:/admin/index";
}
Spring boot 自定義返回JSON(不使用對(duì)象)
@RequestMapping(value = "/create")
public String create(@Valid Post post, HttpServletRequest request) {
request.setAttribute("status",1);
return "forward:/admin/index";
}
Spring boot 如果在Controller上標(biāo)記@ResponseBody
,則框架會(huì)對(duì)響應(yīng)信息默認(rèn)進(jìn)行JSON格式轉(zhuǎn)換勉耀,如果返回對(duì)象指煎,則會(huì)把對(duì)象格式化為標(biāo)準(zhǔn)JSON。
但是如果開(kāi)發(fā)者想自定義JSON時(shí)便斥,總不能每個(gè)JSON都去創(chuàng)建一個(gè)Entity類(lèi)至壤,這里建議使用返回Map的形式,也會(huì)被框架格式化為JSON枢纠。
@RequestMapping("/posts/{id}")
@ResponseBody
public String post(@PathVariable("id") int id) {
Map<String,String> ret = new HashMap<String, String>();
ret.put("success", "true");
ret.put("updateRows", String.valueOf(i));
return ret;
}
錯(cuò)誤處理
發(fā)現(xiàn)錯(cuò)誤以后像街,需要重新返回創(chuàng)建文章的頁(yè)面并把錯(cuò)誤提示給用戶(hù):
@RequestMapping(value = "/", method = RequestMethod.POST)
public String create(@Valid Post post, BindingResult result) {
if (result.hasErrors()) {
return "create";
}
Data.posts.add(post);
return "createResult";
}
模板中獲取錯(cuò)誤信息:
<form action="/posts/" method="post" th:object="${post}">
<div class="form-group">
<label for="title">標(biāo)題</label>
<input type="text" class="form-control"
id="title" name="title" th:field="*{title}"
placeholder="文章的標(biāo)題" autofocus=""/>
<p th:if="${#fields.hasErrors('title')}" th:errors="*{title}">標(biāo)題長(zhǎng)度必須在2-30之間</p>
</div>
<div class="form-group">
<label for="content">內(nèi)容</label>
<textarea class="form-control" id="content" name="content" th:field="*{content}"
placeholder="文章的內(nèi)容" rows="18"></textarea>
<p th:if="${#fields.hasErrors('content')}" th:errors="*{content}">內(nèi)容不可為空</p>
</div>
<button type="submit" class="btn pull-right btn-primary">保存</button>
</form>
具體例子參考:http://course.tianmaying.com/web-development/lesson/form-validation#
Spring數(shù)據(jù)綁定
如果某個(gè)功能提交的請(qǐng)求參數(shù)較多,Spring支持在@RequestMapping
注解的方法中使用對(duì)象來(lái)進(jìn)行參數(shù)綁定晋渺。
@RequestMapping(value = "/posts", method = RequestMethod.POST)
public String create(Post post) {
Data.posts.add(post);
return "createResult";
}
本質(zhì)上Post post參數(shù)實(shí)際上是由Spring創(chuàng)建并設(shè)置相應(yīng)的字段镰绎,所以需要保證Post類(lèi)有默認(rèn)構(gòu)造函數(shù)。
數(shù)據(jù)處理部分
Spring data JPA 使用更新操作
需要用@Modifying
來(lái)標(biāo)記這是個(gè)更新語(yǔ)句木西。
需要在Service方法上標(biāo)記@Transactional
事務(wù)注解畴栖,否則更新/刪除操作會(huì)報(bào)錯(cuò)。
@Modifying
@Transactional
@Query("update User u set u.enable = :enable where u.id = :id")
public int enableUser(@Param("id") Long id, @Param("enable") Boolean enable);
如果是對(duì)整條數(shù)據(jù)的更新户魏,也可以通過(guò)傳入對(duì)象來(lái)更新驶臊,注意對(duì)象需設(shè)置id,否則會(huì)變成add操作叼丑。
qa.setId(id);
Qa qaSave = qaService.saveQa(qa);
Spring 事務(wù)處理
直接在需要添加事務(wù)的service上標(biāo)注@Transactional 注解就OK了,非常簡(jiǎn)單扛门。