1. 什么是SpringMVC?
- SpringMVC是一種基于 Java 的實(shí)現(xiàn)MVC設(shè)計(jì)模型的請(qǐng)求驅(qū)動(dòng)類型的輕量級(jí)Web框架,屬于Spring框架的一個(gè)模塊它褪。
- 它通過一套注解饵骨,讓一個(gè)簡單的Java類成為處理請(qǐng)求的控制器,而無須實(shí)現(xiàn)任何接口茫打。同時(shí)它還支持RESTful編程風(fēng)格的請(qǐng)求居触。
2.什么是MVC模式?
- MVC的全名是Model View Controller老赤,是模型(model)-視圖(view)-控制器(controller)的縮寫轮洋,是一種軟件設(shè)計(jì)典范。它是用一種業(yè)務(wù)邏輯抬旺、數(shù)據(jù)與界面顯示分離的方法來組織代碼弊予,將眾多的業(yè)務(wù)邏輯聚集到一個(gè)部件里面,在需要改進(jìn)和個(gè)性化定制界面及用戶交互的同時(shí)开财,不需要重新編寫業(yè)務(wù)邏輯汉柒,達(dá)到減少編碼的時(shí)間。
- V即View視圖是指用戶看到并與之交互的界面责鳍。比如由html元素組成的網(wǎng)頁界面碾褂,或者軟件的客戶端界面。MVC的好處之一在于它能為應(yīng)用程序處理很多不同的視圖薇搁。在視圖中其實(shí)沒有真正的處理發(fā)生斋扰,它只是作為一種輸出數(shù)據(jù)并允許用戶操縱的方式。
- M即model模型是指模型表示業(yè)務(wù)規(guī)則啃洋。在MVC的三個(gè)部件中,模型擁有最多的處理任務(wù)屎鳍。被模型返回的數(shù)據(jù)是中立的宏娄,模型與數(shù)據(jù)格式無關(guān),這樣一個(gè)模型能為多個(gè)視圖提供數(shù)據(jù)逮壁,由于應(yīng)用于模型的代碼只需寫一次就可以被多個(gè)視圖重用孵坚,所以減少了代碼的重復(fù)性。
- C即controller控制器是指控制器接受用戶的輸入并調(diào)用模型和視圖去完成用戶的需求窥淆,控制器本身不輸出任何東西和做任何處理卖宠。它只是接收請(qǐng)求并決定調(diào)用哪個(gè)模型構(gòu)件去處理請(qǐng)求,然后再確定用哪個(gè)視圖來顯示返回的數(shù)據(jù)忧饭。
3.SpringMVC的執(zhí)行流程扛伍?
- 用戶點(diǎn)擊某個(gè)請(qǐng)求路徑,發(fā)起一個(gè)request請(qǐng)求词裤,此請(qǐng)求會(huì)被前端控制器處理刺洒。
- 前端控制器請(qǐng)求處理器映射器去查找Handler鳖宾。可以依據(jù)注解或者XML配置去查找逆航。
- 處理器映射器根據(jù)配置找到相應(yīng)的Handler(可能包含若干個(gè)Interceptor攔截器)鼎文,返回給前端控制器。
- 前端控制器請(qǐng)求處理器適配器去執(zhí)行相應(yīng)的Handler處理器(常稱為Controller)因俐。
- 處理器適配器執(zhí)行Handler處理器拇惋。
- Handler處理器執(zhí)行完畢之后會(huì)返回給處理器適配器一個(gè)ModelAndView對(duì)象(SpringMVC底層對(duì)象,包括Model數(shù)據(jù)模型和View視圖信息)抹剩。
- 處理器適配器接收到Handler處理器返回的ModelAndView后撑帖,將其返回給前端控制器。
- 前端控制器接收到ModelAndView后吧兔,會(huì)請(qǐng)求視圖解析器(ViewResolver)對(duì)視圖進(jìn)行解析磷仰。
- 視圖解析器根據(jù)View信息匹配到相應(yīng)的視圖結(jié)果,反饋給前端控制器境蔼。
- 前端控制器收到View具體視圖后灶平,進(jìn)行視圖渲染,將Model中的模型數(shù)據(jù)填充到View視圖中的request域箍土,生成最終的視圖(View)逢享。
- 前端控制器向用戶返回請(qǐng)求結(jié)果。
4.SpringMVC有哪些優(yōu)點(diǎn)吴藻?
- SpringMVC本身是與Spring框架結(jié)合而成的瞒爬,它同時(shí)擁有Spring的優(yōu)點(diǎn)(例如依賴注入DI和切面編程AOP等)。
- SpringMVc提供強(qiáng)大的約定大于配置的契約式編程支持沟堡,即提供一種軟件設(shè)計(jì)范式侧但,減少軟件開發(fā)人員做決定的次數(shù),開發(fā)人員僅需規(guī)定應(yīng)用中不符合約定的部分航罗。
- 支持靈活的URL到頁面控制器的映射禀横。
- 可以方便地與其他視圖技術(shù)(JSP、FreeMarker等)進(jìn)行整合粥血。由于SpringMVC的模型數(shù)據(jù)往往是放置在Map數(shù)據(jù)結(jié)構(gòu)中的柏锄,因此其可以很方便地被其他框架引用。
- 擁有十分簡潔的異常處理機(jī)制复亏。
- 可以十分靈活地實(shí)現(xiàn)數(shù)據(jù)驗(yàn)證趾娃、格式化和數(shù)據(jù)綁定機(jī)制,可以使用任意對(duì)象進(jìn)行數(shù)據(jù)綁定操作缔御。
- 支持RestFul風(fēng)格抬闷。
5.Spring MVC的主要組件?
- 前端控制器:其作用是接收用戶請(qǐng)求刹淌,然后給用戶反饋結(jié)果饶氏。它的作用相當(dāng)于一個(gè)轉(zhuǎn)發(fā)器或中央處理器讥耗,控制整個(gè)流程的執(zhí)行,對(duì)各個(gè)組件進(jìn)行統(tǒng)一調(diào)度疹启,以降低組件之間的耦合性古程,有利于組件之間的拓展。
- 處理器映射器:其作用是根據(jù)請(qǐng)求的URL路徑喊崖,通過注解或者XML配置挣磨,尋找匹配的處理器信息。
- 處理器適配器:其作用是根據(jù)映射器處理器找到的處理器信息荤懂,按照特定規(guī)則執(zhí)行相關(guān)的處理器(Handler)茁裙。
- 處理器:其作用是執(zhí)行相關(guān)的請(qǐng)求處理邏輯,并返回相應(yīng)的數(shù)據(jù)和視圖信息节仿,將其封裝至ModelAndView對(duì)象中晤锥。
- 視圖解析器:其作用是進(jìn)行解析操作,通過ModelAndView對(duì)象中的View信息將邏輯視圖名解析成真正的視圖View(如通過一個(gè)JSP路徑返回一個(gè)真正的JSP頁面)廊宪。
- 視圖:View是一個(gè)接口矾瘾,實(shí)現(xiàn)類支持不同的View類型(JSP、FreeMarker箭启、Excel等)壕翩。
6.SpringMVC和Struts2的區(qū)別有哪些?
- SpringMVC的入口是一個(gè)Servlet,也就是前端控制器(DispatcherServlet)傅寡,而Struts2的入口是一個(gè)Filter (StrutsPrepareAndExecuteFilter)放妈。
- SpringMVC是基于方法開發(fā)(一個(gè)url對(duì)應(yīng)一個(gè)方法),請(qǐng)求參數(shù)傳遞到方法的形參荐操,可以設(shè)計(jì)為單例或多例(建議單例)芜抒。struts2是基于類開發(fā),請(qǐng)求參數(shù)傳遞到類的成員屬性托启,只能設(shè)計(jì)為多例挽绩。
- SpringMVC通過參數(shù)解析器將request請(qǐng)求內(nèi)容解析,并給方法形參賦值驾中,將數(shù)據(jù)和視圖封裝成ModelAndView對(duì)象,最后又將ModelAndView中的模型數(shù)據(jù)通過reques域傳輸?shù)巾撁婺Asp視圖解析器默認(rèn)使用JSTL肩民。Struts2采用值棧存儲(chǔ)請(qǐng)求和響應(yīng)的數(shù)據(jù),通過OGNL存取數(shù)據(jù)链方。
7.SpringMVC怎么樣設(shè)定重定向和請(qǐng)求轉(zhuǎn)發(fā)持痰?
我們先說說請(qǐng)求轉(zhuǎn)發(fā)與重定向的區(qū)別:
請(qǐng)求轉(zhuǎn)發(fā)與重定向的區(qū)別
- 請(qǐng)求轉(zhuǎn)發(fā)在服務(wù)器端完成的;重定向是在客戶端完成的祟蚀。
- 請(qǐng)求轉(zhuǎn)發(fā)的速度快工窍;重定向速度慢割卖。
- 請(qǐng)求轉(zhuǎn)發(fā)的是同一次請(qǐng)求;重定向是兩次不同請(qǐng)求患雏。
- 請(qǐng)求轉(zhuǎn)發(fā)不會(huì)執(zhí)行轉(zhuǎn)發(fā)后的代碼鹏溯;重定向會(huì)執(zhí)行重定向之后的代碼。
- 請(qǐng)求轉(zhuǎn)發(fā)地址欄沒有變化淹仑;重定向地址欄有變化丙挽。
- 請(qǐng)求轉(zhuǎn)發(fā)必須是在同一臺(tái)服務(wù)器下完成;重定向可以在不同的服務(wù)器下完成匀借。
SpringMVC設(shè)定請(qǐng)求轉(zhuǎn)發(fā)
在返回值前面加"forward:"颜阐。
@RequestParam("/login")
public String redirect(User user){
if{
//登錄成功...
}else{
//登錄失敗,轉(zhuǎn)發(fā)到登錄頁面
return "forward:tologin";
}
}
SpringMVC設(shè)定重定向
在返回值前面加"redirect:"吓肋。例如我們?cè)诘卿浀臅r(shí)候凳怨,登錄失敗會(huì)重定向到登錄頁面。
@RequestParam("/login")
public String redirect(User user){
if{
//登錄成功...
}else{
//登錄失敗是鬼,重定向到登錄頁面
return "redirect:tologin";
}
}
8.當(dāng)一個(gè)方法向AJAX返回特殊對(duì)象,譬如Object,List等,需要做什么處理肤舞?
- 在方法上加@ResponseBody注解,表示該方法的返回值不管是什么類型屑咳,都會(huì)返回JSON格式的數(shù)據(jù)萨赁。
- 把原來Controller類上的@Controller注解替換為@RestController注解。@RestController = @Controller + @ResponseBody兆龙,表明該Controller類所有的方法都返回JSON格式的數(shù)據(jù)(沒有加@RequestMapping注解的方法除外)杖爽。
-
加入@ResponseBody注解就能返回JSON格式數(shù)據(jù)的原因是
:SpringMVC提供的HttpMessageConverter自動(dòng)轉(zhuǎn)為JSON ,如果使用了Jackson或者Gson紫皇,不需要額外配置就可以自動(dòng)返回JSON了慰安,因?yàn)榭蚣軒臀覀兲峁┝藢?duì)應(yīng)的HttpMessageConverter ,如果使用了Alibaba的Fastjson的話聪铺,則需要自己手動(dòng)提供一個(gè)相應(yīng)的 HttpMessageConverter的實(shí)例化焕。
9.如何解決POST請(qǐng)求中文亂碼問題,GET的又如何處理呢铃剔?
JavaWeb亂碼問題一般是客戶端(瀏覽器)與服務(wù)器端字符集不一致產(chǎn)生的撒桨,如果兩者字符集一致就不會(huì)出現(xiàn)亂碼問題。
解決post請(qǐng)求亂碼
SpringMVC默認(rèn)提供一個(gè)解決post請(qǐng)求亂碼的過濾器键兜,在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>
解決get請(qǐng)求亂碼
- 修改tomcat配置文件添加編碼與工程編碼一致凤类。
<ConnectorURIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
- 對(duì)請(qǐng)求參數(shù)進(jìn)行重新編碼,
ISO8859-1
是tomcat默認(rèn)編碼普气,需要將tomcat編碼后的內(nèi)容按utf-8
編碼谜疤。
String userName = new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8");
10.Spring MVC的異常處理?
為了減少文章篇幅,單獨(dú)把這這個(gè)問題的答案寫成一篇博客夷磕。
項(xiàng)目中出現(xiàn)異常怎么辦履肃?是時(shí)候了解SpringBoot全局異常處理機(jī)制
11.SpringMvc的控制器是不是單例模式,如果是,有什么問題,怎么解決?
- Controller是單例模式坐桩,在多線程訪問的時(shí)候可能產(chǎn)生線程安全問題尺棋,不要使用同步,會(huì)影響程序性能撕攒。
- 解決方案是在控制器里面不能編寫成員屬性陡鹃。
12.SpringMVC常用的注解有哪些?
@Controller
@Controller
用于標(biāo)記在一個(gè)類上抖坪,使用它標(biāo)記的類就是一個(gè)SpringMVC Controller對(duì)象萍鲸。處理器適配器將會(huì)掃描使用了該注解的類的方法,并檢測(cè)該方法是否使用了@RequestMapping
注解擦俐。@Controller 只是定義了一個(gè)控制器類脊阴,而使用@RequestMapping 注解的方法才是真正處理請(qǐng)求的處理器。
@RequsestMapping
@RequestMapping是一個(gè)用來處理請(qǐng)求地址映射的注解蚯瞧,可用于類或方法上嘿期。用于類上,表示類中的所有響應(yīng)請(qǐng)求的方法都是以該地址作為父路徑埋合。返回值會(huì)通過視圖解析器解析為實(shí)際的物理視圖备徐,對(duì)于 InternalResourceViewResolver 視圖解析器,通過 prefix + returnValue + suffix 這樣的方式得到實(shí)際的物理視圖甚颂,然后做轉(zhuǎn)發(fā)操作蜜猾。
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
@RequsestMapping有如下6個(gè)屬性
- value:指定請(qǐng)求的實(shí)際地址。
- method:指定請(qǐng)求的method類型振诬, GET蹭睡、POST、PUT赶么、DELETE等肩豁。
- consumes:指定處理請(qǐng)求的提交內(nèi)容類型(Content-Type)辫呻,例如application/json, text/html清钥。
- produces:指定返回的內(nèi)容類型,僅當(dāng)request請(qǐng)求頭中的(Accept)類型中包含該指定類型才返回放闺;
- params:指定request中必須包含某些參數(shù)值是,才讓該方法處理。
- headers:指定request中必須包含某些指定的header值,才能讓該方法處理請(qǐng)求踩萎。
@ResponseBody
@ResponseBody把Java對(duì)象轉(zhuǎn)化為json對(duì)象很钓,這種方式用于Ajax異步請(qǐng)求码倦,返回的不是一個(gè)頁面而是JSON格式的數(shù)據(jù)企孩。
@Valid
標(biāo)志參數(shù)被Hibernate-Validator校驗(yàn)框架
校驗(yàn)。
@PathVariable
- @PathVariable用于接收uri地址傳過來的參數(shù)袁稽,Url中可以通過一個(gè)或多個(gè){Xxx}占位符映射勿璃,通過@PathVariable可以綁定占位符參數(shù)到方法參數(shù)中,在RestFul接口風(fēng)格中經(jīng)常使用推汽。
- 例如:請(qǐng)求URL:http://localhost/user/21/張三/query
(Long類型可以根據(jù)需求改變?yōu)镾tring或int补疑,SpringMVC會(huì)自動(dòng)做轉(zhuǎn)換)
@RequestMapping("/user/{userId}/{userName}/query")
public User query(@PathVariable("userId") Long userId, @PathVariable("userName") String userName){
}
@RequestParam
@RequestParam用于將請(qǐng)求參數(shù)映射到控制器方法的形參上,有如下三個(gè)屬性
- value:參數(shù)名歹撒。
- required:是否必需莲组,默認(rèn)為true,表示請(qǐng)求參數(shù)中必須包含該參數(shù)暖夭,如果不包含拋出異常锹杈。
- defaultValue:默認(rèn)參數(shù)值,如果設(shè)置了該值自動(dòng)將required設(shè)置為false鳞尔,如果參數(shù)中沒有包含該參數(shù)則使用默認(rèn)值嬉橙。
- 示例:@RequestParam(value = "pageNum", required = false, defaultValue = "1")
@ControllerAdvice
@ControllerAdvice標(biāo)識(shí)一個(gè)類是全局異常處理類。
@ControllerAdvice
public class ControllerTest {
//全局異常處理類
}
@ExceptionHandler
@ExceptionHandler標(biāo)識(shí)一個(gè)方法為全局異常處理的方法寥假。
@ExceptionHandler
public void ExceptionHandler(){
//全局異常處理邏輯...
}
13.SpingMvc中的控制器的注解一般用那個(gè),有沒有別的注解可以替代市框?
- 一般使用@Controller注解標(biāo)識(shí)控制器。
- 也可以使用@RestController注解替代@Controller注解糕韧,@RestController相當(dāng)于@ResponseBody+@Controller枫振,表示控制器中所有的方法都返回JSON格式數(shù)據(jù),一般不使用其他注解標(biāo)識(shí)控制器萤彩。
14.如果在攔截請(qǐng)求中玖姑,想攔截get方式提交的方法,怎么配置?
- 可以在@RequestMapping注解里面加上method=RequestMethod.GET删咱。
@RequestMapping(value="/toLogin",method = RequestMethod.GET)
public ModelAndView toLogin(){}
- 可以使用@GetMapping注解荒叶。
@GetMapping(value="/toLogin")
public ModelAndView toLogin(){}
15.怎樣在控制器方法里面得到request或者session肆汹?
直接在控制器方法的形參中聲明request,session予权,SpringMvc就會(huì)自動(dòng)把它們注入昂勉。
@RequestMapping("/login")
public ModelAndView login(HttpServletRequest request, HttpSession session){}
16.如果想在攔截的方法里面得到從前臺(tái)傳入的參數(shù),怎么得到?
直接在控制器方法的形參里面聲明這個(gè)參數(shù)就可以扫腺,但名字必須和傳過來的參數(shù)名稱一樣岗照,否則參數(shù)映射失敗。
下面方法形參中的userId笆环,就會(huì)接收從前端傳來參數(shù)名稱為userId的值攒至。
@RequestMapping("/deleteUser")
public void deleteUser(Long userId){
//刪除用戶操作...
}
17.前臺(tái)傳入多個(gè)參數(shù),并且這些參數(shù)都是一個(gè)對(duì)象的屬性,怎么進(jìn)行參數(shù)綁定?
直接在控制器方法的形參里面聲明這個(gè)參數(shù)就可以躁劣,SpringMvc就會(huì)自動(dòng)會(huì)請(qǐng)求參數(shù)賦值到這個(gè)對(duì)象的屬性中迫吐。
下面方法形參中的user用來接收從前端傳來的多個(gè)參數(shù),參數(shù)名稱需要和User實(shí)體類屬性名稱一致习绢。
@RequestMapping("/saveUser")
public void saveUser(User user){
//保存用戶操作...
}
@Data
public class User {
private Long userId;
private String username;
private String password;
//...
}
18.SpringMVC中函數(shù)的返回值是什么渠抹?
為了減少文章篇幅,單獨(dú)把這這個(gè)問題的答案寫成一篇博客闪萄。
SpringMVC四種返回值類型總結(jié)
19.SpringMVC用什么對(duì)象從后臺(tái)向前臺(tái)傳遞數(shù)據(jù)的梧却?
- 使用Map、Model和ModelMap的方式败去,這種方式存儲(chǔ)的數(shù)據(jù)是在request域中
@RequestMapping("/getUser")
public String getUser(Map<String,Object> map,Model model,ModelMap modelMap){
//1.放在map里
map.put("name", "xq");
//2.放在model里放航,一般是使用這個(gè)
model.addAttribute("habbit", "Play");
//3.放在modelMap中
modelMap.addAttribute("city", "gd");
modelMap.put("gender", "male");
return "userDetail";
}
- 使用request的方式
@RequestMapping("/getUser")
public String getUser(Map<String,Object> map,Model model,ModelMap modelMap,HttpServletRequest request){
//放在request里
request.setAttribute("user", userService.getUser());
return "userDetail";
}
- 使用ModelAndView
@RequestMapping("/getUser")
public ModelAndView getUser(ModelAndView modelAndView) {
mav.addObject("user", userService.getUser());
mav.setViewName("userDetail");
return modelAndView;
}
20.怎么樣把ModelMap里面的數(shù)據(jù)放入session里面?
在類上添加@SessionAttributes
注解將指定的Model數(shù)據(jù)存儲(chǔ)到session中圆裕。
@SessionAttributes
- 默認(rèn)情況下Spring MVC將模型中的數(shù)據(jù)存儲(chǔ)到request域中广鳍。當(dāng)一個(gè)請(qǐng)求結(jié)束后,數(shù)據(jù)就失效了吓妆。如果要跨頁面使用赊时。那么需要使用到session。而@SessionAttributes注解就可以使得模型中的數(shù)據(jù)存儲(chǔ)一份到session域中行拢。
- @SessionAttributes只能定義在Class,interface enum上祖秒,作用是將指定的Model中的鍵值對(duì)添加至session中,方便在一個(gè)會(huì)話中使用舟奠。
@SessionAttributes參數(shù)
- names:這是一個(gè)字符串?dāng)?shù)組竭缝。里面應(yīng)寫需要存儲(chǔ)到session中數(shù)據(jù)的名稱。
- types:根據(jù)指定參數(shù)的類型沼瘫,將模型中對(duì)應(yīng)類型的參數(shù)存儲(chǔ)到session中抬纸。
- value:其實(shí)和上面的names是一樣的。
@SessionAttributes(value={"names"},types={Integer.class})
@Controller
public class session{
@RequestMapping("/session")
public String session(Model model){
model.addAttributes("names", Arrays.asList("caoyc","zhh","cjx"));
model.addAttributes("age", 22);
return "/session";
}
}
在上面代碼中耿戚,在類上添加@SessionAttributes注解湿故,并指定將names名稱的Model數(shù)據(jù)存儲(chǔ)到session域中阿趁,以及將Integer類型的Model數(shù)據(jù)存儲(chǔ)到session域中。
21.SpringMvc里面攔截器是怎么寫的晓锻?
為了減少文章篇幅歌焦,單獨(dú)把這這個(gè)問題的答案寫成一篇博客。
SpringMVC攔截器實(shí)現(xiàn)原理以及登錄攔截器實(shí)現(xiàn)(圖文講解)
22.SpringMMV中有個(gè)類把視圖和數(shù)據(jù)都合并的一起的,叫什么砚哆?
它就是ModelAndView。
- 使用ModelAndView類存儲(chǔ)處理完后的結(jié)果數(shù)據(jù)屑墨,以及顯示該數(shù)據(jù)的視圖躁锁。從名字上看ModelAndView中的Model代表模型,View代表視圖卵史,從名字看就很好地解釋了該類的作用战转。Controller處理器調(diào)用模型層處理完用戶請(qǐng)求后,把結(jié)果數(shù)據(jù)存儲(chǔ)在該類的model屬性中以躯,把要返回的視圖信息存儲(chǔ)在該類的view屬性中槐秧,然后把ModelAndView返回給前端控制器。前端控制器通過調(diào)用配置文件中定義的視圖解析器忧设,對(duì)該對(duì)象進(jìn)行解析刁标,最后把結(jié)果數(shù)據(jù)顯示在指定的頁面上。
- 返回指定頁面
ModelAndView構(gòu)造方法可以指定返回的頁面名稱址晕。
也可以通過setViewName()方法跳轉(zhuǎn)到指定的頁面 膀懈。 - 返回所需數(shù)值
使用addObject()設(shè)置需要返回的值,addObject()有幾個(gè)不同參數(shù)的方法谨垃,可以默認(rèn)和指定返回對(duì)象的名字启搂。
這里再鏈接MyBatis最新面試題,大家覺得不錯(cuò)的話刘陶,可以??或者關(guān)注一下我胳赌。
2020年最新MyBatis面試題,看這篇就足夠了