Spring框架中最重要的模块
请求流程
- 用户发送请求
- 请求进入中央处理器DispatcherServlet,解析URI,调用处理器映射器
- 处理器映射器RequestMappingHandlerMapping根据uri找到一个具体的HandlerMethod,返回给DispatcherServlet
- DispatcherServlet调用HandlerAdapter处理器适配器执行HandlerMethod,返回ModelAndView对象给中央处理器
- DispatcherServlet调用视图解析器ViewResolver解析View视图,返回逻辑视图View给DispathcerSrevlet
- DispatcherServlet把ModelAndView对象中数据放在request作用域中
- jsp渲染页面,返回给前端浏览器
- spring-MVC是spring中的一个服务,web服务,对servlet进行封装了,避免了繁琐的web配置,spring-MVC是面向接口编程
核心类与接口
- DispatcherServlet前端控制器:接收请求,响应结果,相当于转发器,是spring-MVC的中央处理器
- HandlerMapping处理器映射器:解析URI,查找Handler处理器对象
- HandlerAdapter处理器适配器:找到Handler处理器对象后,由DispatcherServlet前端控制器调用HandlerAdapter来执行HandlerMethod,Handler处理器方法返回给适配器ModelAndView对象
- Handler处理器对象:自己编写,相当于Controller
- ModerAndView模型与视图对象:是springmvc框架的一个底层对象,包括 Model和View,代表数据与视图部分,Handler执行完成后,返回给Adapter的是ModelAndView对象。Adapter再把该对象返回给DispatherServlet前端控制器
- ViewResolve视图解析器对象:前端控制器请求视图解析器去进行视图解析,根据逻辑视图名解析成真正的视图(jsp),视图解析器向前端控制器返回View,DispatcherServlet负责渲染视图,将模型数据(在ModelAndView对象中)填充到request作用域,便于显示数据,最终响应用户
使用
导入jar包
配置springMVC-config.xml文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> 包扫描 <context:component-scan base-package="io.jtxyh"></context:component-scan> 识别spring-mvc的注解: 包括:RequesetMapping,PathValiable,DatatimeFormated,getMapping,PostMapping.... <mvc:annotation-driven></mvc:annotation-driven> 处理器映射器: 识别RequestMapping注解,做uri映射,也可以不配置,默认已配置过 <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean> 视图解析器,生成响应视图路径 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/view/"></property> <property name="suffix" value=".jsp"></property> </bean>
</beans>
|
配置web.xml文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> 设置字符编码 post请求乱码配置 <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 设置request编码 <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> 设置response编码 <init-param> <param-name>forceResponseEncoding</param-name> <param-value>true</param-value> </init-param> </filter> 设置范围 <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 加载springMVC-config配置文件 <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springMVC-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
|
Handler编写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| "注册一个bean到spring中" @Controller "指定处理的url请求名称" @RequestMapping("/userHandler") public class UserHandler { "接收日期参数需要使用@DateTimeFormat(pattern = "yyyy-MM-dd")格式化时间" @RequestMapping("/test1") public String test1(Model m,String uname,String upass,@DateTimeFormat(pattern = "yyyy-MM-dd") Date time) { System.out.println("test1执行了"); "Model中的数据被放在request域中" m.addAttribute("key1", "value1"); m.addAttribute("time",time); return "test1"; } "路径不同,写法不同" @RequestMapping("/test2") public String test2() { System.out.println("test2执行了"); return "/a/test2"; } "获取传入的参数,@RequestParam给参数设置一个默认值" @RequestMapping("/test3") public String test3(@RequestParam(defaultValue = "默认名")String name,String pass,Model m) { System.out.println("test3执行了"+name+"------"+pass); m.addAttribute("name",name); return "test3"; } "转发" @RequestMapping("/test4") public String test4() { System.out.println("test4执行了"); "转发到test3去,如果用重定向就是redirect" return "forward:test3"; } "返回一个ModelAndView视图" @RequestMapping("/test5") public ModelAndView test5() { System.out.println("test5执行了"); ModelAndView md = new ModelAndView(); "指定返回的视图名称" md.setViewName("test5"); "返回的数据" md.addObject("test5", "哈哈哈哈哈"); return md; } "形参可以有session,request,response,需要哪个写哪个" @RequestMapping("/test6") public String test6(HttpSession session,HttpServletRequest req,HttpServletResponse resp) { System.out.println("test6执行了"); session.setAttribute("session", "session-Value"); req.setAttribute("request", "request-Value"); return "test6"; } "因为postTest3不在WEB-INF下所以直接访问不到,需要通过Servlet" @RequestMapping("/test7") public String test7() { System.out.println("返回到postTest3页面"); return "postTest3"; } }
|
解析
@Controller
spring-core中的注解,包扫描加入bean
@RequestMapping
指定处理的url请求名称
@RequestParam
给形参设置一个默认值
格式化时间数据,@DateTimeFormat(pattern = “yyyy-MM-dd”)
形参Model
用于返回给前端数据,存储在request域中
对象ModelAndView
用于返回给前端数据,存储在request域中,需要指定返回的视图名称
@ResponseBody
在方法上设置使方法不走视图解析器,走消息转换器,返回数据(json数据或者字符串数据)
@RestController
在类上设置,让这个类中所有的方法都走消息转换器
@PathVariable
用户获取形参的数据,在写Rest接口时使用
@GetMapping
Rest中使用通过get获取数据,用在查询的接口上
@PostMapping
Rest中使用通过post获取数据,用在添加的接口上
@PutMapping
Rest中使用通过put获取数据,用在修改的接口上
@DeleteMapping
Rest中使用通过delete获取数据,用在删除的接口上
@CrossOrigin
实现跨域,即在服务器内不是同一个端口也可以访问方法
@ExceptionHandler
在类中添加这个注解,当前方法变为局部异常处理的方法
Rest风格
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| @Component @RequestMapping("/restTest") @RestController "下面所有的方法都不走视图解析器,都走消息转换器" @CrossOrigin "实现跨域,不同的端口号访问也可以" public class RestTest { "通过get请求获取,查询方法" "@PathVariable注解是为了获取到形参的数据传给Mapping" @GetMapping("{uid}") public User getUserInfo(@PathVariable("uid")String uid) { User user = new User("1001","智智","男"); return user; }
"通过post请求获取,添加方法" @PostMapping public void addUserInfo(String uid,String uname,String gender) { User u = new User(uid,uname,gender); System.out.println("新添加的User信息:"+u); } "通过put请求获取,修改方法" @PutMapping public void updateUserInfo(String uid,String uname,String gender) { User u = new User(uid,uname,gender); System.out.println("修改后的User信息:"+u); } "通过delete请求获取,删除方法" @DeleteMapping("{uid}") public void deleteUser(@PathVariable("uid")String uid) { System.out.println("需要删除的User的ID为:"+uid); } }
|
静态资源处理
在web.xml中配置Tomcat默认的DefaultServlet的servlet
1 2 3 4 5 6 7 8
| 引用Tomcat的配置,对静态资源进行处理,这样就可以通过浏览器地址栏直接访问到静态资源 不需要mapping <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.html</url-pattern> <url-pattern>*.css</url-pattern> <url-pattern>*.js</url-pattern> </servlet-mapping>
|
在springMVC-config.xml中配置
1 2 3 4 5 6 7
| 静态资源必须放在WebContent下,不能放在WEB-INF下!! 对静态资源进行处理,这里配置了之后就不需要在web.xml中配置Servlet的default了 推荐使用这种方法 <**代表不管多少层路径全部都处理> mapping相当于RequestMapping做映射名 有多个文件夹就配多个<mvc:resources></mvc:resources> <mvc:resources location="/static/" mapping="/static/**"></mvc:resources>
|
文件上传
需要jar包
在springMVC-config中配置
1 2 3 4 5 6 7 8 9 10 11
| id必须是multipartResolver <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 最大文件大小 <property name="maxUploadSize" value="30000000"></property> 临时文件域 <property name="maxInMemorySize" value="10000000"></property> 设置默认字符编码 <property name="defaultEncoding" value="UTF-8"></property> 临时文件储存路径 <property name="uploadTempDir" value="/upload"></property> </bean>
|
在页面上的写法
1 2 3 4 5
| 必须有 enctype="multipart/form-data" <form action="goMain" method="post" enctype="multipart/form-data"> <input type="file" name="img"/><br/> <input type="submit" value="提交"> </form>
|
在java中写法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| @RequestMapping("/goMain") "这里的MultipartFile形参的名字必须与上传的文件的name保持一致" public void goMain(HttpServletResponse resp,MultipartFile img) { "获取文件名称" String fileName = img.getOriginalFilename(); "获取文件大小" long fileSize = img.getSize(); System.out.println("文件名字:"+fileName+"========文件大小:"+fileSize); try { "获取文件字节数组" byte[] fileBytes = img.getBytes(); System.out.println("文件字节数组:"+fileBytes.toString()); } catch (Exception e) { e.printStackTrace(); } "设置文件响应流" resp.setContentType("text/html;charset=utf-8"); try { PrintWriter pw = resp.getWriter(); pw.write("上传成功"); pw.flush(); pw.close(); } catch (Exception e) { e.printStackTrace(); } }
|
json支持
- 使用jar包,使用jackjson或者fastjson都可以,spring默认集成了jackjson
springMVC-config.xml中配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| 识别mvc的注解 <mvc:annotation-driven> 配置JSON解析 <mvc:message-converters> json消息转换器:contentType:applicatin/json defaultCharset:UTF-8 默认字符编码是UTF-8
jackson的配置方法 <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
两种只需配一种即可
fastjson的配置方法 <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"></bean>
string消息转换器:contentType:text/plain defaultCharset:ISO-8859-1 默认字符编码是ISO-8859-1 用来返回string数据的 <bean class="org.springframework.http.converter.StringHttpMessageConverter"> 指定默认字符编码为UTF-8 <property name="defaultCharset" value="UTF-8"></property> </bean> </mvc:message-converters> </mvc:annotation-driven>
|
java中使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @RequestMapping("/getUserInfo") "让这个方法不走视图解析器,走消息转换器" @ResponseBody "实现返回json数据" public List<User> getUserInfo(){ List<User> list = new ArrayList<User>(); list.add(new User("1001","张三","11")); list.add(new User("1002","李四","12")); list.add(new User("1003","王五","13")); list.add(new User("1004","赵六","14")); return list; }
@RequestMapping("/getUname") @ResponseBody "实现返回字符串数据" public String getUname() { User u = new User(); u.setUname("智智"); return u.getUname(); }
|
拦截器设置
- 在一个类中继承HandlerInterceptor,进行重写preHandle方法
- preHandle方法:前置拦截,在执行Handler之前执行
- postHandle方法:执行Handler之后不出异常时执行
- afterCompletion方法:最后执行,无论出不出异常都执行
在springMVC-config.xml中配置
1 2 3 4 5 6 7 8 9 10 11 12
| 配置拦截器 <mvc:interceptors> <mvc:interceptor> 拦截路径 <mvc:mapping path="/**"/> 不拦截的路径 <mvc:exclude-mapping path="/localExceptionDealWith/test1"/> <mvc:exclude-mapping path="/localExceptionDealWith/test2"/> 配置自己的拦截器到bean容器中 <bean class="io.jtxyh.interceptor.MyloginInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>
|
在java中配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| "一般只需要重写preHandle方法" public class MyloginInterceptor implements HandlerInterceptor{
"Handler执行前执行" @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("=======preHandl============"); "返回true就是放行,返回false就是拦截" return true; }
"Handler执行后执行,出现异常则不执行" @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("========postHandler==========="); }
"Handler执行后执行,不管出不出现异常都执行" @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("========afterCompletion==========="); } }
|
相关文章
数据库连接池
SpringIOC
Junit和Spring
Tomcat
Servlet
Request,Response和ServletContext
Cookie和Session
JSP和EL和Jstl
Filter和Listener
Mybatis