Springweb詳解
一.springweb介紹
1.1 SpringWEB 特點
? SpringWEB 是 spring 家族原生產品,與 IOC 容器等基礎設施無縫對接.
? 基于原生的 Servlet,提供了一個前端控制器 DispatcherServlet ,開發者 無須額外開發控制器對象.
? 可以自動綁定用戶輸入,并正確地轉換數據類型.
? 代碼清新簡潔,大幅度提升開發效率.
? 內部組件化程度高,可插拔式組件即插即用.
? 性能卓著,尤其適合現代大型、超大型互聯網項目要求.
1.2 springweb組件
前端控制器:DispatcherServlet(不需要程序員開發)由框架提供,在 web.xml 中配置。 作用:統一處理請求和響應,整個流程控制的中心,由它調用其它組件處理 用戶的請求.
處理器映射器:HandlerMapping(不需要程序員開發),由框架提供。 作用:根據請求的 url 查找 Handler(處理器/Controller)
處理器適配器:HandlerAdapter(不需要程序員開發),由框架提供。 作用:按照特定規則(HandlerAdapter 要求的規則)去執行 Handler。
處理器:Handler(也稱之為 Controller,需要工程師開發)。 注意:編寫 Handler 時按照 HandlerAdapter 的要求去做,這樣適配器才可 以去正確執行 Handler。 作用:接受用戶請求信息,調用業務方法處理請求,也稱之為后端控制器
二.springweb搭建
2.1 導包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
2.2 配置DispatcherServlet
在 web.xml 文件中配置 DispatcherServlet
配置 spring 核心請求分發器
<servlet>
<servlet-name>application</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<!-- 請求映射 -->
<servlet-mapping>
<servlet-name>application</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
2.3 開啟Springweb注解
<mvc:annotation-driven></mvc:annotation-driven>
2.4 處理器類搭建
@RestController 用于標記在一個類上,使用它標記的類就是一個 SpringWEB 控制器類。用@RequestMapping標記一個類或方法,spring會掃描包中用了@RM的類,方法然后加入到IOC容器中,注入依賴
//@RequestMapping 用來為類和方法定義訪問地址,類上面的地址不能重復
@RequestMapping(path = "/loginCtl")
public class LoginController {@RequestMapping(path = "/login")public String login(){......}
}
三. 接受請求
3.1 @RequestMapping
@RequestMapping 是一個用來為處理器地址映射的注解,可用于類或方法上. 作用在類上,在整個項目中不能重復,作用在方法上,整個類中不能重復. 常用屬性 path,value,method. path 和 value 用來定義地址 method 用來定義請求方式 @RequestMapping(value = “/hello”,method = RequestMethod.GET) @RequestMapping(path= “/hello”,method = RequestMethod.POST)
// path和value都表示定義一個此類或方法的地址
// method=RequestMethod.POST 指定允許哪些請求方式訪問此方法@RequestMapping(path = "/login",method = RequestMethod.POST)public String login(Admin admin){......}
ok我們來總結一下:
springweb好處:對web層進行封裝,讓我們可以快速搭建自己的后端處理程序(LoginController):
@RestController //表示此類由spring創建管理
@RequestMapping(path = "/loginCtl") //為類定義一個映射地址
public class LoginController {@AutowiredLoginService loginService; //方便的注入其他對象//為方法定義映射地址,設置該方法允許哪些請求方式訪問,可以方便接收請求中的參數@RequestMapping(path = "/login",method = RequestMethod.POST)public String login(Admin admin){Admin admin1=loginService.login(admin);System.out.println(admin1);//可以直接將返回的對象,自動轉為json字符串return "success"; }
}
四.springweb請求的運行流程(截至目前)
一次請求到后端,先進入DispatcherServlet,統一進行攔截,再調用其他程序進行處理,調用HandlerMapping(處理器映射器) 解析請求中處理器的地址和方法地址。判斷地址是否存在,不存在返回404,如果存在,判斷該地址有沒有攔截器。如果有攔截器,進入攔截器。
然后會回到DispatcherServlet,再調用HandlerAdapter(處理器適配器),最終由處理器適配器調用我們自己的處理器(LoginController),由我們自己的處理器進行接受請求,處理請求,響應。
五.獲取請求數據
5.1 spring自動封裝
spring會自定進行數據封裝,這里需要注意的是,處理器接收參數的形參名稱必須和表單的name屬性保持一致
@RequestMapping(path = "/login",method = RequestMethod.POST) public String login(Admin admin,String mark){......return "success";}
5.2 當請求參數名和形參名不一致
5.2.1 可以使用@RequestParam(“”)進行參數綁定
@RequestMapping(path = "/login",method = RequestMethod.POST) public String login(Admin admin,@RequestParam("m") String mark){......return "success";}
5.2.2 可以使用@RequestHeader(“”)接收請求頭中的數據
@RequestMapping(path = "/login",method = RequestMethod.POST) //因為請求頭中的User-Agent傳回來發現java中沒有-命名的變量,所以需要用到這個public String login(Admin admin,@RequestHeader("User-Agent") String userAgent){......return "success";}
5.3 使用實體類對象接收
@RequestBody 可以接收前端提交的json格式數據,將json格式封裝到對象中
@RequestMapping(path = "/login",method = RequestMethod.POST) public String login(@RequestBody Admin admin){......return "success";}
5.4 日期類型轉換
屬性類型為Date類型需要指定轉換格式,在聲明屬性上方添加:
@DateTimeFormat(pattern = "yyyy-MM-dd")private Date birthday;
@DateTimeFormat():前端提交到后端的數據日期指定轉換格式
@JsonFormat():后端把對象轉為json時,指定的日期格式
六.中文亂碼處理
SpringWEB 中已經為我們提供了過濾器,只需要在 web.xml 中配置即可:
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
七.跨域訪問處理:
添加依賴:
<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>cors-filter</artifactId>
<version>2.5</version>
</dependency>
web.xml中配置:
<filter>
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CORS</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
八.返回JSON
我們在后端返回的對象springweb會自動幫我們返回成json格式,只需要導入json組件即可:
<!--jackson-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
九.攔截器
springweb中的攔截器類似于servlet中的過濾器,主要用于攔截用戶請求并作相應的處理
spring中的攔截器與過濾器有本質的區別,過濾器是servlet規范中定義并實現的,在進入到servlet之前截獲請求,而攔截器時spring中定義的攔截機制,是對進入到處理器的請求進行攔截
配置攔截器:
<!--配置攔截器--><mvc:interceptors><mvc:interceptor><mvc:mapping path="/**"/> <!--定義哪些地址可以進入到攔截器中--><mvc:exclude-mapping path="/loginCtl/login"/> <!--定義哪些地址不進入攔截器--><mvc:exclude-mapping path="/loginCtl/login"/> <!--可以配多個--><bean id="admin" class="com.ffyc.ssm.interceptor.AdminTokenInterceptor"></bean> <!--配置攔截器的實現類--></mvc:interceptor></mvc:interceptors>
定義一個攔截器:
當請求進入攔截器時判斷token,符合則true然后繼續執行處理器,不符合false則不往后執行可以在此給用戶做出相應
//定義一個攔截器
public class AdminTokenInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("進入到攔截器");//獲得tokenString token = request.getHeader("token");if (token.equals("123456")) {return true; //攔截器中返回true,請求就會離開攔截器,繼續向后執行,到達處理器}else{response.setContentType("text/html;charset=utf-8");PrintWriter writer=response.getWriter();writer.write("token驗證失敗");return false; //攔截器中返回false,不會繼續向后執行,可以在攔截器中向用戶做出響應}}
}