SSM整合開發(三)—Web層
首先感謝慕課網的老師,講的真的很棒,學習很多書本上學不到的實用知識。
學習課程的地址:https://www.imooc.com/learn/630
老師的GitHub地址:https://github.com/geekyijun/seckill
概要
主要介紹前端交互設計、Restful:url滿足Restful設計規範、Spring MVC、bootstrap+jquery這四個方面的開發。
關於Restful
什麼是Restful?它就是一種優雅的URI表述方式,用來設計我們資源的訪問URL。通過這個URL的設計,我們就可以很自然的感知到這個URL代表的是哪種業務場景或者什麼樣的數據或資源。爲什麼要設計URL?對於初學者和不嚴格的系統來說,URL基本上不用理會。基本上不會根據業務需求從系統角度出發去設計URL。基於Restful設計的URL,對於我們接口的使用者、前端、web系統或者搜索引擎甚至是我們的用戶,都是非常友好的。詳細內容這裏不再贅述。
關於MVC運行流程
使用SpringMVC始終是圍繞Handler進行開發,Handler最終產生Model和View。
如圖展示了MVC運行流程,這裏稍微回顧一下,DispatcherServlet作爲中央控制器的Servlet,攔截用戶的所有請求。使用默認的DefaultAnnotationHandlerMapping,用來映射我們的URL——>Handler。使用默認的DefaultAnnotationHandlerAdapter進行Handler適配,能夠銜接我們開發的controller部分,若有攔截器,也會綁定當流程當中。最終的產出是ModelAndView。InternalResourceViewResolver默認的jsp的view。將Model和xxx.jsp頁面相結合返回給用戶。
我們開發只要開發藍色的Controller部分就可以了,其他部分可以使用默認註解的形式方便的進行開發。
RequestMapping註解映射技巧
1. 支持標準的URL。
2. 支持Ant風格URL(即?、*、**等字符)
3. 帶{xxx}佔位符URL,可以支持傳入參數。
例如:/user/*/creation匹配/user/aaa/creation
/user/**/creation匹配/user/creation、/user/aaa/bbb/creation等
/user/{userId}匹配/user/123、user/abc等。
Web層
配置SpringMVC框架
web.xml
配置DispatcherServlet、Spring需要加載的一些文件寫到contextConfigLocation中。
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0" metadata-complete="true"> <!--用maven創建的web-app需要修改servlet的版本爲3.1--> <!--配置DispatcherServlet--> <servlet> <servlet-name>seckill-dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 配置SpringMVC 需要配置的文件 spring-dao.xml,spring-service.xml,spring-web.xml Mybites -> spring -> springMvc --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/spring-*.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>seckill-dispatcher</servlet-name> <!--默認匹配所有請求--> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
spring-web.xml
在spring容器中進行web層相關bean(即Controller)的配置,其他相關說明寫在註釋當中。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--配置spring mvc--> <!--1,開啓springmvc註解模式 a.自動註冊DefaultAnnotationHandlerMapping,AnnotationMethodHandlerAdapter b.默認提供一系列的功能:數據綁定,數字和日期的format@NumberFormat,@DateTimeFormat c:xml,json的默認讀寫支持--> <mvc:annotation-driven/> <!--2.靜態資源默認servlet配置--> <!-- 1).加入對靜態資源處理:js,gif,png 2).允許使用 "/" 做整體映射 --> <mvc:default-servlet-handler/> <!--3:配置JSP 顯示ViewResolver--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <!--4:掃描web相關的controller--> <context:component-scan base-package="com.seu.web"/> </beans>
SeckillController.java
@Component @RequestMapping("/seckill")//url:模塊/資源/{}/細分 public class SeckillController { @Autowired private SeckillService seckillService; @RequestMapping(value = "/list",method = RequestMethod.GET) public String list(Model model) { //list.jsp+mode=ModelAndView //獲取列表頁 List<Seckill> list=seckillService.getSeckillList(); model.addAttribute("list",list); return "list"; } @RequestMapping(value = "/{seckillId}/detail",method = RequestMethod.GET) public String detail(@PathVariable("seckillId") Long seckillId, Model model) { if (seckillId == null) { return "redirect:/seckill/list"; } Seckill seckill=seckillService.getById(seckillId); if (seckill==null) { return "forward:/seckill/list"; } model.addAttribute("seckill",seckill); return "detail"; } //ajax ,json暴露秒殺接口的方法 @RequestMapping(value = "/{seckillId}/exposer", method = RequestMethod.GET, //返回HTTP的response的header,告訴瀏覽器數據的格式 produces = {"application/json;charset=UTF-8"}) @ResponseBody//返回json的數據 public SeckillResult<Exposer> exposer(@PathVariable("seckillId") Long seckillId) { SeckillResult<Exposer> result; try{ Exposer exposer=seckillService.exportSeckillUrl(seckillId); result=new SeckillResult<Exposer>(true,exposer); }catch (Exception e) { e.printStackTrace(); result=new SeckillResult<Exposer>(false,e.getMessage()); } return result; } @RequestMapping(value = "/{seckillId}/{md5}/execution", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"}) @ResponseBody public SeckillResult<SeckillExecution> execute(@PathVariable("seckillId") Long seckillId, @PathVariable("md5") String md5, //request中這個cookie不是必須的,驗證邏輯放在方法體中執行 @CookieValue(value = "userPhone",required = false) Long userPhone) { if (userPhone==null) { return new SeckillResult<SeckillExecution>(false,"未註冊"); } SeckillResult<SeckillExecution> result; try { SeckillExecution execution = seckillService.executeSeckill(seckillId, userPhone, md5); return new SeckillResult<SeckillExecution>(true, execution); }catch (RepeatKillException e1) { SeckillExecution execution=new SeckillExecution(seckillId, SeckillStatEnum.REPEAT_KILL); return new SeckillResult<SeckillExecution>(true,execution); }catch (SeckillCloseException e2) { SeckillExecution execution=new SeckillExecution(seckillId, SeckillStatEnum.END); return new SeckillResult<SeckillExecution>(true,execution); } catch (Exception e) { SeckillExecution execution=new SeckillExecution(seckillId, SeckillStatEnum.INNER_ERROR); return new SeckillResult<SeckillExecution>(true,execution); } } //獲取系統時間 @RequestMapping(value = "/time/now",method = RequestMethod.GET) @ResponseBody public SeckillResult<Long> time() { Date now=new Date(); return new SeckillResult<Long>(true,now.getTime()); } }
下面包括暴露秒殺接口返回的數據寫在dto包中,用於封裝成json數據。
SeckillResult.java(省略getter、setter和構造函數)
//將所有的ajax請求返回類型,全部封裝成json數據 public class SeckillResult<T> { //請求是否成功 private boolean success; private T data; private String error; }
前端代碼,由於本人精力有限,暫時沒考慮學習前端內容。所以這裏就不貼出來了,可在GitHub上查看(https://github.com/geekyijun/seckill),不過通過這門課程學習到了Bootstrap前端框架的使用,提供一站式前端開發,需要的時候可以查詢使用。