文章目錄
SpringMVC
1.作用
- 接受前臺或者其他服務的數據並校驗
- 返回數據到前臺或者其他服務
- 指定跳轉的頁面或其他服務數據接口
2.搭建
2.1導入jar包
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>1.8</source> <!-- 源代碼使用jdk1.8支持的特性 -->
<target>1.8</target> <!-- 使用jvm1.8編譯目標代碼 -->
<compilerArgs> <!-- 傳遞參數 -->
<arg>-parameters</arg>
<arg>-Xlint:unchecked</arg>
<arg>-Xlint:deprecation </arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
2.2詳解配置springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置spring創建容器時要掃描的包 -->
<context:component-scan base-package="cn.cdqf.web"></context:component-scan>
<!-- 配置視圖解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".html"></property>
</bean>
<!-- 配置spring開啓註解mvc的支持-->
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
2.3配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- SpringMVC的核心控制器 -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置Servlet的初始化參數,讀取springmvc的配置文件,創建spring容器 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!-- 配置servlet啓動時加載對象 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--避免springmvc攔截以html結尾的請求-->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
</web-app>
2.4代碼執行
@Controller
public class UserController {
@RequestMapping("index")
public ModelAndView index(ModelAndView modelAndView){
System.out.println("hello");
modelAndView.setViewName("a");
return modelAndView;
}
}
3.核心流程分析
DispacthServlet:中央控制
handlerMapping:描述是url與method的對應關係
容器加載的時候會加載到springmvc.xml,在根據springmvc.xml中配置掃描路徑,就可以找到對應包,找到包以後會遍歷該包下面所有類,判斷類上面是否有@controller註解,如果有就放在IOC容器中,springmvc會從IOC容器中拿出所有被@controller註解修飾的類,遍歷這些類的方法,拿到method對象,通過反射獲得method對象上面@requestMapping註解,獲得@requestMapping註解的value,就是一個url,就會把這個url與當前方法, new HandlerMapping(url,method) 放在一個List:存儲了當前項目所有url以及url與method的對應關係
url---- DispacthServlet-----把這個給,就會拿到這個,去判斷是否有這個,如果沒有,如果有就拿到這個方法
4.ModelAndView
返回前臺:
- 包含數據,request/session.setAttribute(“user”,user對象)
- 指定跳轉頁面 request forward方法(請求轉發) response.sendRedicet(重定向)
模型視圖對象:modelAndView 就是把上面兩步封裝到一起
addObject()方法:添加數據 添加的數據 放在request作用域 viewName:視圖名稱
@RequestMapping("index")
//封裝了 ModelAndView 當返回String的時候 springmvc會去創建modelandview.setviewName("index")
public String index(){
System.out.println("來了,老弟");
return "index";
}
@RequestMapping("index2")
//直接放在這兒
public ModelAndView index2(ModelAndView modelAndView){
System.out.println("來了,老弟");
//request.setAttribute("username","張三") 數據
modelAndView.addObject("username","張三");
//指定跳轉的頁面
modelAndView.setViewName("index");
return modelAndView;
}
5.json參數返回
4.1詳解配置
jsp的前後端耦合性太強,不適用於高度解耦的前後端分離的開發。
json是作爲前後端的數據交互的重要數據載體
-
導入fastjson.jar
-
配置springmvc.xml中的json轉換器
- 編碼問題
- 配置前後端下載文件衝突
- 屬性值爲null轉換輸出配置
- 日期格式
- 循環調用問題
<!-- 配置spring開啓註解mvc的支持--> <mvc:annotation-driven></mvc:annotation-driven> <mvc:annotation-driven> <!--不使用默認消息轉換器 --> <mvc:message-converters register-defaults="false"> <!--spring消息轉換器 --> <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/> <bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/> <!--解決@Responcebody中文亂碼問題 --> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <constructor-arg value="UTF-8"/> </bean> <!--配合fastjson支持 --> <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"> <property name="defaultCharset" value="UTF-8"/> <property name="supportedMediaTypes"> <list> <!--順序保持這樣,避免IE下載出錯 配置1.注意編碼 2.注意與下載文件衝突--> <value>text/html;charset=UTF-8</value> <value>application/json</value> </list> </property> <property name="fastJsonConfig" ref="fastJsonConfig"/> </bean> </mvc:message-converters> </mvc:annotation-driven> <!--fastJsonConfig 這裏面的配置需要開發中 跟前端進行協商--> <bean id="fastJsonConfig" class="com.alibaba.fastjson.support.config.FastJsonConfig"> <!--默認編碼格式 --> <property name="charset" value="UTF-8"/> <property name="serializerFeatures"> <list> <!--3.需要指定null按照協商好的配置返回--> <!-- List字段如果爲null,輸出爲[]--> <value>WriteNullListAsEmpty</value> <!--4.日期格式 使得返回的日期類型默認爲yyyy-MM-dd hh:mm:ss --> <value>WriteDateUseDateFormat</value> <!--美化格式--> <value>PrettyFormat</value> <value>WriteMapNullValue</value> <value>WriteNullStringAsEmpty</value> <!--禁止循環引用檢測 Teacher : List<Student> Student : Teacher stackOverFlow: --> <value>DisableCircularReferenceDetect</value> </list> </property> </bean>
-
導入前端js,css等靜態資源,配置放過攔截js
<!-- 對指定目錄下的靜態資源放行(**代表當前文件夾及子文件夾所有文件) --> <mvc:resources location="/fonts/" mapping="/fonts/**"/> <mvc:resources location="/css/" mapping="/css/**"/> <mvc:resources location="/js/" mapping="/js/**"/>
4.2 基本數據類型
4.3 String類型
後端代碼:
@Controller
//namespace作用 handlerMapping: url=類上面+方法上
@RequestMapping("ajax")
//@RestController=@Controller+@ResponseBody
public class AjaxController {
//8888/ajax/ajax1
@RequestMapping("ajax1")
//如果不告訴springmvc返回json 默認返回字符串是代表路徑
@ResponseBody//就是告訴springmvc 這個方法得返回值是一個json springmvc就會調用配置json庫
// 來進行轉換爲json字符串然後通過 response.getwriter寫回去
public String ajax1(){
System.out.println("ajax1方法被請求");
return "hello ajax1";
}
}
public String index(){
System.out.println("來了,老弟");
//轉發
return "forward:index";//forward默認省略 等於return “index"
//重定向
return "redirect:/WEB-INF/pages/index.html";
}
- 請求轉發的字符串若在springmvc.xml文件中配置了viewResolver將爲其加上前綴和後綴進行請求
- 重定向的字符串路徑則需要手動拼接
前端代碼:
<link href="/css/bootstrap.min.css">
<script src="/js/jquery-3.3.1.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
</head>
<body>
<button id="ajax">點擊</button>
</body>
<script>
$(function () {
$("#ajax").click(function () {
$.ajax({
url:"/ajax/ajax1",
type:"GET",
dataType:"json",//返回數據類型
success:function (data) {
console.log(data);
}
})
})
})
</script>
4.4集合類型
4.5Map類型
4.6數組類型
4.7日期類型
4.8實體對象
@RestController
@RequestMapping("student")
public class Ajax2Controller {
@RequestMapping("ajax1")
public List<Student> ajax1(){
return Arrays.asList(new Student("張三", "力寶", new Date(), 100), new Student("李四", "力寶", new Date(), 100));
}
}
5.其他配置
5.1配置過濾器
<!-- 配置過濾器,解決中文亂碼的問題 -->
<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>
5.2日期轉換配置
-
創建日期轉換類實現Converter接口
public class DateConverter implements Converter<String, Date> { @Override public Date convert(String s) { if(s !=null){ try { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); return dateFormat.parse(s); } catch (ParseException e) { e.printStackTrace(); } } return null; } }
-
xml配置
<!--配置自己寫好的轉換器--> <bean id="dateConverter" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="com.ctbu.converter.DateConverter"/> </list> </property> </bean> <!--配置註解驅動,讓轉換器生效--> <mvc:annotation-driven conversion-service="dateConverter"/>
5.3攔截器配置
-
創建自定義攔截器,實現HandlerInterceptor接口
public class MyInterceptor implements HandlerInterceptor { /** * @param request * @param response * @param handler * @return * @throws Exception * 在controller方法之前執行 * * 1.return true就執行controller *2. return false就不會執行controller */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //用戶沒有登錄 讓用戶跳轉到登錄頁面 //response.sendRedirect("http://localhost:8888/login.html"); //response也可以寫json //拿到url 拿到參數 獲得session 獲得cookie //某些請求需要等 某些不登錄 queryAllProduct 不需要登錄 updateProduct需要登錄 //通過request獲得url 看一看是不是需要登錄的請求 從session中獲得登錄信息 就可以判斷 //不同的角色 在項目 權限不同 deleteUser //url:login----LoginController中 login方法 //HttpMethod handler1 = (HttpMethod) handler; System.out.println("攔截器執行了....."); return true; } //modelAndView :1.會有數據攜帶 2.跳轉的頁面 //html中 ${abc} 取出request.setAttribute("abc","張三") //視圖渲染:把頁面中佔位符替換爲 值 頁面html元素 與數據的整合 //1.會在視圖渲染前執行,可以去修改視圖渲染的值 //正常情況下 postHandle先執行 afterCompletion後執行 // postHandle出現異常不會執行 afterCompletion出現異常也會執行 @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle執行了"); } //2.會在視圖渲染後執行 //可以獲得當前請求出現異常 @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion執行了"); } }
-
xml攔截器配置(多個攔截器)
<mvc:interceptors> <mvc:interceptor> <!--當前攔截器 要攔截的路徑--> <mvc:mapping path="/**"/> <!--在上面的路徑中排除某些路徑--> <mvc:exclude-mapping path="/interceptor/index3"/> <bean class="cn.cdqf.web.interceptor.MyInterceptor"/> </mvc:interceptor> <mvc:interceptor> <!--當前攔截器 要攔截的路徑--> <mvc:mapping path="/**"/> <!--在上面的路徑中排除某些路徑--> <mvc:exclude-mapping path="/interceptor/index3"/> <bean class="cn.cdqf.web.interceptor.MyInterceptor2"/> </mvc:interceptor> </mvc:interceptors>
6.請求參數
6.1@RequestParam註解
-
基本類型
- 基本數據類型作爲請求方法的參數時,參數名必須一致
- 前臺傳入的數據爲空將拋出類型轉換異常,返回400錯誤(參數有誤)。若爲包裝類型則會將null作爲值傳入
- 使用@RequestParam替換參數名
-
數組/集合類型
配置@RequestParam註解
//@RequestParam中的value必須在對應的名稱後面加[]表示接受數組或者集合類型 //用@RequestParam標註表示必須傳一個名字相同的參數 public void insert(@RequestParam(value = "ids[]",required = false) String[] ids, @RequestParam("name") String username) { }
6.2@Requestbody註解
-
標註在方法上表示方法將返回json數據
@RestController=@Controller+@ResponseBody
-
標註在參數上表示參數爲接受json數據
- 前端請求參數類型爲json字符串
- 請求方法爲Post
- 請求頭中的ContentType=“application/json”,表示Http響應回來的是json數據
7.HTTP常見Code編號
編號 | 概述 |
---|---|
404 | 請求路徑錯誤 |
400 | 請求參數錯誤 |
405 | 請求方法錯誤,前後端GET/POST方法不一致 |
302 | 重定向 |
304 | 瀏覽器緩存 |
500 | 後臺服務器錯誤 |