SSM整合開發(三)—Web層

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.xmlspring-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,
                    //返回HTTPresponseheader,告訴瀏覽器數據的格式
                    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前端框架的使用,提供一站式前端開發,需要的時候可以查詢使用。

 

發佈了75 篇原創文章 · 獲贊 49 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章