若看到一个项目啥都没配置,那么它一定有默认值
组件说明
springmvc执行流程百度有,百年老面试题,都泛滥了
1.*Handler:处理器(我们写)
Handler 是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet的控制下Handler对具体的用户请求进行处理,由于Handler涉及到具体的用户业务请求,所以一般情况需要程序员根据业务需求开发Handler。
这玩意就是你写的controller,@RequestMapping下标注的方法。别把他想成啥高级玩意,你也能写个处理器。
2.*View:视图(我们写)
一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面。我们最常用的视图就是jsp。
这玩意就是我们写的jsp,牛逼不
3.*DispatcherServlet:中央控制器(只有他和servlet相关)
用户请求到达前端控制器,它就相当于mvc模式中的c,dispatcherServlet是整个流程控制的中心,
由它调用其它组件处理用户的请求,dispatcherServlet的存在降低了组件之间的耦合性。
这玩意是核心,就是门卫传达室,一个请求进来先来传达室,然后一步步来处理问题。就是个servlet。
4.*HandlerMapping:处理器映射器
HandlerMapping负责根据用户请求url找到Handler即处理器,springmvc提供了不同的映射器实现不同的映射方式,如配置文件方式,实现接口方式,注解方式等。
这玩意就是个map,放了一堆数据,key是url,value是你对应的处理器。一个请求来了,调用一下mao.get(url)就知道哪个类的哪个方法处理这个请求了。当然实际上会将这个url多对应的拦截器(马上学),处理器都拿到。
5.*HandlAdapter:处理器适配器
通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
这货会调用相应的方法,生成最终能够的modelAndView。
6.*ViewResolver:视图解析器
View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。
这货就是解析modelAndView的。有个常用最简单的功能就是拼接字符串,给你加个前缀后缀,让你方便了很多,当然他们解析很多类型的视图。
统一字符处理:
请求响应经过过滤器,过滤器统一的把他们字符集改了
粘贴到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>
视图模型拆分:
视图和模型是两个东西,耦合在一起当然不好了,比如有时候我只是跳转视图,有时候压根不需要跳转视图;ajax发送请求只要数据,不要视图。是不是有更好的解决方案?
既然存在ModelAndView就应该存到Model和View。
springMvc的解决方案是:
Model会在调用时通过★参数形式传入。
View可以简化为★字符串形式返回。
@RequestMapping("/test1")
public String testAnnotation(Model model,HttpServletRequest request,
HttpServletResponse Response){ //需要啥就往参数列表上写啥
model.addAttribute("hello","hello annotationMvc as string");
return "annotation";
}
如果只需要处理model,则返回null,当然一般都会有数据传入;
如果只处理view,则不用传入参数model。
@RequsetMapping:
RequestMapping注解有六个属性。
1、value
, method
;
-
value: 指定请求的实际地址,指定的地址可以是URI Template 模式(后面将会说明);
-
method: 指定请求的method类型, GET、POST、PUT、DELETE等;
2、consumes
,produces
;
-
consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
-
produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回,可以处理乱码
@GetMapping(value = "{id}",produces = {"content-type:application/json;charset=utf-8"})
3、params
,headers
;
-
params: 指定request中必须包含某些参数值时,才让该方法处理。
-
headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。
这个注解很关键,可以方法类上也可以放在方法上。
如果放在类上,会给每个方法默认都加上,相当于本类全局前缀。
@Controller
@RequestMapping("/user/") //一定要用requestmapping,因为方法内不止仅有get请求或post请求
public class UserCotroller {
@GetMapping("/showUser")
public String showUser(Model model, HttpServletRequest request, HttpServletResponse Response) {
//request才能跨多个controller,model不行!!!
request.setAttribute("user",new User("haha","123"));
return "forward:/user/addUser"; //转发正确方式
}
@GetMapping("addUser")
public String addUser(Model model,@RequestAttribute User user) {
model.addAttribute("user",user);
return "user";
}
}
@RequsetMapping中的属性:
@RequestMapping(value = "addUser",method = RequestMethod.GET,
params = {"username=zs","password=123"},
headers = {"a=1","b=2"})
@ResponseBody
public User addUser(Model model, HttpServletRequest request) {
return new User("zha","123");
}
更多的传参方式参考spring官方文档,spring web mvc下MethodArguments下的有关session,cookie,model,request的注解。用不着记忆。
默认的传参方式@requsetParam
若不满足传参约定,就@requestParam()中修改参数名。它会自动绑定到password2.
若参数是对象,它会查对象中的字段的setter(),就会把前台传过来的key主动传给复杂对象。
controller
@PostMapping("addUser")
public String addUser(Model model, String username,@RequestParam("password") String password2) {
model.addAttribute("user",new User(username,password2));
return "user";
}
jsp前台页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<html>
<head>
<title>Moral</title>
<base href="<%=basePath%>">
</head>
<body>
<!--不要在开头加"/",你jsp已经写basePath了,so只需写相对于basePath的路径。
"/"默认站点根目录,加了就把真正的站点根目录干掉了-->
<form action="user/addUser" method="post">
<input name="username" type="text">
<input name="password" type="password">
<input type="submit" value="submit">
</form>
</body>
</html>