日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

20分钟教你手写Sping MVC

發(fā)布時(shí)間:2024/10/8 c/c++ 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 20分钟教你手写Sping MVC 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

注意:前方高能

徹底理解Spring MVC看這一篇就夠了

三層架構(gòu)

我們的開發(fā)架構(gòu)一般都是基于兩種形式,一種是C/S架構(gòu),也就是客戶端/服務(wù)器,另一種是B/S架構(gòu),也就 是瀏覽器服務(wù)器。在 JavaEE 開發(fā)中,幾乎全都是基于B/S架構(gòu)的開發(fā).

那么在B/S架構(gòu)中,系統(tǒng)標(biāo)準(zhǔn)的三層架構(gòu)包括:表現(xiàn)層、業(yè)務(wù)層、持久層。三層架構(gòu)在我們的實(shí)際開發(fā)中使用的非常多,所以我們課程中的案例也都是基于三層架構(gòu)設(shè)計(jì)的。 三層架構(gòu)中,每一層各司其職,接下來我們就說說每層都負(fù)責(zé)哪些方面:

  • 表現(xiàn)層: 也就是我們常說的web層。它負(fù)責(zé)接收客戶端請求,向客戶端響應(yīng)結(jié)果,通常客戶端使用http協(xié)議請求 web 層,web需要接收http請求,完成http 響應(yīng)。 表現(xiàn)層包括展示層控制層:控制層負(fù)責(zé)接收請求,展示層負(fù)責(zé)結(jié)果的展示。 表現(xiàn)層依賴業(yè)務(wù)層,接收到客戶端請求一般會調(diào)用業(yè)務(wù)層進(jìn)行業(yè)務(wù)處理,并將處理結(jié)果響應(yīng)給客戶端。 表現(xiàn)層的設(shè)計(jì)一般都使用 MVC 模型。(MVC 是表現(xiàn)層的設(shè)計(jì)模型,和其他層沒有關(guān)系)
  • 業(yè)務(wù)層: 也就是我們常說的service層。它負(fù)責(zé)業(yè)務(wù)邏輯處理,和我們開發(fā)項(xiàng)目的需求息息相關(guān)。web 層依賴業(yè)務(wù)層,但是業(yè)務(wù)層不依賴 web 層。 業(yè)務(wù)層在業(yè)務(wù)處理時(shí)可能會依賴持久層,如果要對數(shù)據(jù)持久化需要保證事務(wù)一致性。(也就是我們說的, 事務(wù)應(yīng)該放到業(yè)務(wù)層來控制)
  • 持久層: 也就是我們是常說的dao層。負(fù)責(zé)數(shù)據(jù)持久化,包括數(shù)據(jù)層即數(shù)據(jù)庫和數(shù)據(jù)訪問層,數(shù)據(jù)庫是對數(shù)據(jù)進(jìn)行持久化的載體,數(shù)據(jù)訪問層是業(yè)務(wù)層和持久層交互的接口,業(yè)務(wù)層需要通過數(shù)據(jù)訪問層將數(shù)據(jù)持久化到數(shù)據(jù)庫中。通俗的講,持久層就是和數(shù)據(jù)庫交互,對數(shù)據(jù)庫表進(jìn)行曾刪改查的。

MVC 模型

MVC 全名是Model View Controller,是模型(model)-視圖(view)-控制器(controller)的縮寫,是一種用于設(shè)計(jì)創(chuàng)建 Web 應(yīng)用程序表現(xiàn)層的模式。MVC 中每個(gè)部分各司其職:

  • Model(模型):通常指的就是我們的數(shù)據(jù)模型。作用一般情況下用于封裝數(shù)據(jù)。
  • View(視圖):通常指的就是我們的jsp或者h(yuǎn)tml。作用一般就是展示數(shù)據(jù)的, 通常視圖是依據(jù)模型數(shù)據(jù)創(chuàng)建的。
  • Controller(控制器):是應(yīng)用程序中處理用戶交互的部分。作用一般就是處理程序邏輯的。它相對于前兩個(gè)不是很好理解,這里舉個(gè)例子:

例如:我們要保存一個(gè)用戶的信息,該用戶信息中包含了姓名,性別,年齡等等。
這時(shí)候表單輸入要求年齡必須是 1~100 之間的整數(shù)。姓名和性別不能為空。并且把數(shù)據(jù)填充到模型之中。此時(shí)除了 js 的校驗(yàn)之外,服務(wù)器端也應(yīng)該有數(shù)據(jù)準(zhǔn)確性的校驗(yàn),那么校驗(yàn)就是控制器的該做的。當(dāng)校驗(yàn)失敗后,由控制器負(fù)責(zé)把錯(cuò)誤頁面展示給使用者。如果校驗(yàn)成功,也是控制器負(fù)責(zé)把數(shù)據(jù)填充到模型,并且調(diào)用業(yè)務(wù)層實(shí)現(xiàn)完整的業(yè)務(wù)需求。


SpringMVC 是什么

SpringMVC 是一種基于 Java 的實(shí)現(xiàn) MVC 設(shè)計(jì)模型的請求驅(qū)動(dòng)類型的輕量級 Web 框架,屬于 Spring FrameWork的后續(xù)產(chǎn)品,已經(jīng)融合在Spring Web Flow里面。Spring 框架提供了構(gòu)建 Web 應(yīng)用程序的全功能 MVC 模塊。使用 Spring 可插入的 MVC 架構(gòu),從而在使用 Spring 進(jìn)行 WEB 開發(fā)時(shí),可以選擇使用 Spring的Spring MVC框架或集成其他 MVC開發(fā)框架,如 Struts1(現(xiàn)在一般不用),Struts2 等。SpringMVC 已經(jīng)成為目前最主流的 MVC 框架之一,并且隨著 Spring3.0 的發(fā)布,全面超越 Struts2,成為最優(yōu)秀的 MVC 框架。它通過一套注解,讓一個(gè)簡單的 Java 類成為處理請求的控制器,而無須實(shí)現(xiàn)任何接口。同時(shí)它還支持RESTful 編程風(fēng)格的請求。

SpringMVC 的優(yōu)勢

1、清晰的角色劃分:

  • 前端控制器(DispatcherServlet)
  • 請求到處理器映射(HandlerMapping)
  • 處理器適配器(HandlerAdapter)
  • 視圖解析器(ViewResolver)
  • 處理器或頁面控制器(Controller)
  • 驗(yàn)證器( Validator)
  • 命令對象(Command 請求參數(shù)綁定到的對象就叫命令對象)
  • 表單對象(Form Object提供給表單展示和提交到的對象就叫表單對象)。

2、分工明確,而且擴(kuò)展點(diǎn)相當(dāng)靈活,可以很容易擴(kuò)展,雖然幾乎不需要。
3、由于命令對象就是一個(gè)POJO,無需繼承框架特定 API,可以使用命令對象直接作為業(yè)務(wù)對象。
4、和 Spring 其他框架無縫集成,是其它 Web 框架所不具備的。
5、可適配,通過 HandlerAdapter 可以支持任意的類作為處理器。
6、可定制性,HandlerMapping、ViewResolver 等能夠非常簡單的定制。
7、功能強(qiáng)大的數(shù)據(jù)驗(yàn)證、格式化、綁定機(jī)制。
8、利用 Spring 提供的 Mock 對象能夠非常簡單的進(jìn)行 Web 層單元測試。
9、本地化、主題的解析的支持,使我們更容易進(jìn)行國際化和主題的切換。
10、強(qiáng)大的 JSP 標(biāo)簽庫,使 JSP 編寫更容易。
還有比如RESTful風(fēng)格的支持、簡單的文件上傳、約定大于配置的契約式編程支持、基于注解的零配置支持等等。


SpringMVC 和 Struts2 的優(yōu)略分析

共同點(diǎn):

  • 它們都是表現(xiàn)層框架,都是基于 MVC 模型編寫的。
  • 它們的底層都離不開原始 ServletAPI。
  • 它們處理請求的機(jī)制都是一個(gè)核心控制器。

區(qū)別:

  • Spring MVC 的入口是 Servlet, 而 Struts2 是 Filter
  • Spring MVC 是基于方法設(shè)計(jì)的,而 Struts2 是基于類,Struts2 每次執(zhí)行都會創(chuàng)建一個(gè)動(dòng)作類。所以 Spring MVC 會稍微比 Struts2 快些。
  • Spring MVC 使用更加簡潔,同時(shí)還支持JSR303, 處理 ajax 的請求更方便
    (JSR303 是一套JavaBean參數(shù)校驗(yàn)的標(biāo)準(zhǔn),它定義了很多常用的校驗(yàn)注解,我們可以直接將這些注解加在我們JavaBean的屬性上面,就可以在需要校驗(yàn)的時(shí)候進(jìn)行校驗(yàn)了。)
  • Struts2 的OGNL表達(dá)式使頁面的開發(fā)效率相比Spring MVC更高些,但執(zhí)行效率并沒有比JSTL提升,尤其是struts2的表單標(biāo)簽,遠(yuǎn)沒有 html 執(zhí)行效率高。

手寫Spring MVC

Servlet的常規(guī)寫法

為了減少Servlet的數(shù)量,現(xiàn)在是一個(gè)功能一個(gè)Servlet,將其優(yōu)化為一個(gè)模塊一個(gè)Servlet,相當(dāng)于在數(shù)據(jù)庫中一張表對應(yīng)一個(gè)Servlet,在Servlet中提供不同的方法,完成用戶的請求。

BaseServlet編寫

import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper;import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;public class BaseServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {/***方法分發(fā)*///1.獲取請求路徑String uri = request.getRequestURI();//2.獲取方法名稱String methodName = uri.substring(uri.lastIndexOf('/') + 1);System.out.println("methodName=" + methodName);try {//3.獲取方法對象Method method = this.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);//4.執(zhí)行方法//暴力反射:修改方法修飾符為public//method.setAccessible(true);//4.執(zhí)行方法method.invoke(this, request, response);} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {e.printStackTrace();}}/*** 直接將傳入的對象序列化為Json返回客戶端** @param response* @param obj*/public void writeValue(HttpServletResponse response, Object obj) throws IOException {response.setContentType("Application/json;charset=utf-8");ObjectMapper mapper = new ObjectMapper();mapper.writeValue(response.getOutputStream(), obj);}public String writeValueAsString(Object obj) throws JsonProcessingException {ObjectMapper mapper = new ObjectMapper();String json = mapper.writeValueAsString(obj);return json;} }

UserServlet改寫

將之前的Servlet實(shí)現(xiàn)的功能,抽取到UserServlet中的不同方法中實(shí)現(xiàn),并且將UserService創(chuàng)建抽取到成員變量位置

@WebServlet("/user/*") // /user/add, /user/find public class UserServlet extends BaseServlet {//聲明UserService業(yè)務(wù)對象private UserService service = new UserServiceImpl();/*** 注冊功能* @param request* @param response* @throws ServletException* @throws IOException*/public void regist(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//驗(yàn)證校驗(yàn)String check = request.getParameter("check");//從sesion中獲取驗(yàn)證碼HttpSession session = request.getSession();String checkcode_server = (String) session.getAttribute("CHECKCODE_SERVER");session.removeAttribute("CHECKCODE_SERVER");//為了保證驗(yàn)證碼只能使用一次//比較if(checkcode_server == null || !checkcode_server.equalsIgnoreCase(check)){//驗(yàn)證碼錯(cuò)誤ResultInfo info = new ResultInfo();//注冊失敗info.setFlag(false);info.setErrorMsg("驗(yàn)證碼錯(cuò)誤");//將info對象序列化為jsonObjectMapper mapper = new ObjectMapper();String json = mapper.writeValueAsString(info);response.setContentType("application/json;charset=utf-8");response.getWriter().write(json);return;}//1.獲取數(shù)據(jù)Map<String, String[]> map = request.getParameterMap();//2.封裝對象User user = new User();try {BeanUtils.populate(user,map);} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}//3.調(diào)用service完成注冊//UserService service = new UserServiceImpl();boolean flag = service.regist(user);ResultInfo info = new ResultInfo();//4.響應(yīng)結(jié)果if(flag){//注冊成功info.setFlag(true);}else{//注冊失敗info.setFlag(false);info.setErrorMsg("注冊失敗!");}//將info對象序列化為jsonObjectMapper mapper = new ObjectMapper();String json = mapper.writeValueAsString(info);//將json數(shù)據(jù)寫回客戶端//設(shè)置content-typeresponse.setContentType("application/json;charset=utf-8");response.getWriter().write(json);}/*** 登錄功能* @param request* @param response* @throws ServletException* @throws IOException*/public void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.獲取用戶名和密碼數(shù)據(jù)Map<String, String[]> map = request.getParameterMap();//2.封裝User對象User user = new User();try {BeanUtils.populate(user,map);} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}//3.調(diào)用Service查詢// UserService service = new UserServiceImpl();User u = service.login(user);ResultInfo info = new ResultInfo();//4.判斷用戶對象是否為nullif(u == null){//用戶名密碼或錯(cuò)誤info.setFlag(false);info.setErrorMsg("用戶名密碼或錯(cuò)誤");}//5.判斷用戶是否激活if(u != null && !"Y".equals(u.getStatus())){//用戶尚未激活info.setFlag(false);info.setErrorMsg("您尚未激活,請激活");}//6.判斷登錄成功if(u != null && "Y".equals(u.getStatus())){request.getSession().setAttribute("user",u);//登錄成功標(biāo)記//登錄成功info.setFlag(true);}//響應(yīng)數(shù)據(jù)ObjectMapper mapper = new ObjectMapper();response.setContentType("application/json;charset=utf-8");mapper.writeValue(response.getOutputStream(),info);}/*** 查詢單個(gè)對象* @param request* @param response* @throws ServletException* @throws IOException*/public void findOne(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//從session中獲取登錄用戶Object user = request.getSession().getAttribute("user");//將user寫回客戶端ObjectMapper mapper = new ObjectMapper();response.setContentType("application/json;charset=utf-8");mapper.writeValue(response.getOutputStream(),user);}/*** 退出功能* @param request* @param response* @throws ServletException* @throws IOException*/public void exit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.銷毀sessionrequest.getSession().invalidate();//2.跳轉(zhuǎn)登錄頁面response.sendRedirect(request.getContextPath()+"/login.html");}/*** 激活功能* @param request* @param response* @throws ServletException* @throws IOException*/public void active(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.獲取激活碼String code = request.getParameter("code");if(code != null){//2.調(diào)用service完成激活//UserService service = new UserServiceImpl();boolean flag = service.active(code);//3.判斷標(biāo)記String msg = null;if(flag){//激活成功msg = "激活成功,請<a href='login.html'>登錄</a>";}else{//激活失敗msg = "激活失敗,請聯(lián)系管理員!";}response.setContentType("text/html;charset=utf-8");response.getWriter().write(msg);}} }

總結(jié)

以上是生活随笔為你收集整理的20分钟教你手写Sping MVC的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。