目录
[TOC]
SpringMVC
SpringMVC环境搭建
pom.xml
1 2 3 4 5 6 7 8 9 10 11
| <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.2.RELEASE</version> </dependency>
|
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
| <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.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
<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> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
|
resource目录下配置springmvc.xml文件
1 2 3 4 5 6 7 8 9 10 11 12
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> </beans>
|
1 2
| <context:component-scan base-package="cn.qingweico"/>
|
1 2 3 4 5 6
| @RequestMapping(path = "/hello") public String hello() { System.out.println("请求成功!"); return "success"; }
|
配置视图解析器
1 2 3 4 5 6 7
| <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/"/> <property name="suffix" value = ".jsp"/> </bean>
|
1 2
| <mvc:annotation-driven/>
|
DispatcherServlet 前端控制器
DispatcherServlet是整个流程控制的核心,当用户请求到达前端控制器时,由它调用其他组件来处理用户的请求,正是DispatcherServlet的存在降低了组件之间的耦合性
HandlerMapping 处理器映射器
HandlerMapping根据用户的请求找到JHandler 即处理器
Handler 处理器
它是我们开发中要编写的具体业务控制器,由DispatcherServlet把用户请求转发到Handler,由Handler对具体的用户请求进行处理
HandlerAdapter 处理器适配器
通过HandlAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行
ViewResolver 视图解析器
View Resolver负责将处理的结果生成视图。View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成具体的视图对象,最后对视图进行渲染将处理结果通过页面展示给用户
RequestMapping的属性
1 2 3 4 5 6 7 8
| @RequestMapping(path = '') //用于建立请求URL和请求方法之间的对应关系
@RequestMapping(value = '') //path和value表示相同的作用,即请求的URL地址,当只有URL时可以省略 @RequestMapping(value = '', method = RequestMethod.GET) method:表示请求的方式 (GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS,TRACE) params:表示指定限制请求参数的条件 headers:用于指定限制请求消息头的条件
|
请求参数绑定
基本数据类型和String类型
1 2 3 4 5
| @RequestMapping(path = "/hello", method = RequestMethod.GET) public String hello(String username, int password) { System.out.println("你好" + username + "!" + " 你的密码是" + password); return "success"; }
|
1 2
| <!--提交数据的键要和参数的名称要相同--> <a href="hello?username=jack&password=21">登陆</a>
|
JavaBean
1 2 3 4 5
| @RequestMapping(value = "/test", method = {RequestMethod.POST}) public String test(Account account) { System.out.println(account); return "success"; }
|
1 2 3 4 5 6 7
| <form action="test" method="post"> <!--name的值与实体类中的属性名保持一致--> <!--而且实体类中一定要有属性的set方法,这样才能把数据封装到实体类中--> 姓名:<input type="text" name="username"><br> 密码:<input type="text" name="password"> <input type="submit" value="提交"> </form>
|
实体类中含有引用类型
1 2 3 4 5 6 7 8
| <form action="test" method="post"> 姓名:<input type="text" name="username"><br> 密码:<input type="text" name="password"><br> <!--使用实体类中引用属性名称.引用实体类属性--> 学号:<input type="text" name="user.number"><br> 年龄:<input type="text" name="user.age"><br> <input type="submit" value="提交"> </form>
|
集合类型
1 2
| private List<User> list; private Map<Integer,User> map;
|
1 2 3 4 5 6 7 8 9 10 11
| <form action="test" method="post"> 姓名:<input type="text" name="username"><br> 密码:<input type="text" name="password"><br> <!--将数据封装到User对象存入List集合的第一个位置--> 学号:<input type="text" name="list[0].number"><br> 年龄:<input type="text" name="list[0].age"><br> <!--将数据封装到User对象存入键为0的位置--> 学号:<input type="text" name="map[0].number"><br> 年龄:<input type="text" name="map[0].age"><br> <input type="submit" value="提交"> </form>
|
获取原生API的方式
1 2 3 4 5 6 7 8 9
| @RequestMapping(value = "/servlet") public String servlet(HttpServletRequest request) { System.out.println(request); HttpSession session = request.getSession(); System.out.println(session); ServletContext servletContext = session.getServletContext(); System.out.println(servletContext); return "success"; }
|
注解RequestParam
1 2 3 4 5 6 7
| @RequestMapping(path = "/hello",method = RequestMethod.GET) public String hello(@RequestParam(name = "name")String username) { System.out.println("你好" + username + "!"); return "success"; }
|
1
| <a href="hello?name=helloWorld">Hello</a> <!--URL之间不要留空格-->
|
RequestBody注解
主要用来接收前端传递给后端的json字符串中的数据的,且@RequestBody最多只能有一个
1 2 3 4 5
| @RequestMapping(value = "/body") public String body(@RequestBody String body) { System.out.println(body); return "success"; }
|
RESTFUL风格(PathVariable)
1 2 3 4 5
| @RequestMapping(value = "/rest/{id}") public String rest(@PathVariable(name = "id") String id) { System.out.println(id); return "success"; }
|
1
| <a href="rest/我是id">Restful</a>
|
1 2 3 4 5 6
| @RequestMapping(value = "/header") public String head(@RequestHeader(value = "Cookie") String header) { System.out.println(header); return "success"; }
|
CookieValue注解
1 2 3 4 5 6
| @RequestMapping(value = "/Cookie") public String Cookie(@CookieValue(value = "JSESSIONID") String cookie) { System.out.println(cookie); return "success"; }
|
ModelAttribute注解
该注解既可以修饰方法也可以修饰参数
修饰方法时代表该方法会在控制器方法执行之前执行
修饰参数时可以获取指定的数据给参数赋值
1 2 3 4 5 6 7 8
| <!--当用户输入的数据不完整时,即没有输入学号和年龄时,可以通过先执行带有ModelAttribute注解的方法来获取学号和年龄,从而保证数据的完整性--> <form action="model" method="post"> 用户名:<label><input type="text" name="username"></label><br> 密码:<label><input type="text" name="password"></label><br> 学号:<input type="text" name="user.number"><br> 年龄:<input type="text" name="user.age"><br> <input type="submit" value="提交"> </form>
|
1 2 3 4 5 6 7 8 9 10
| @ModelAttribute public Account modelAttribute(String username){ Account account = new Account(); User user = findByName(username); user.setNumber("007"); user.setAge("21"); account.setUser(user); return account; }
|
1 2 3 4 5
| @RequestMapping("/model") public String model(Account account){ System.out.println(account); return "success"; }
|
1 2 3 4 5 6 7 8 9
| @ModelAttribute public void modelAttribute(Map<String, Account> map,String username) { Account account = new Account(); User user = findByName(username); user.setAge("21"); user.setNumber("007"); account.setUser(user); map.put("user", account); }
|
1 2 3 4 5
| @RequestMapping("/model") public String model(@ModelAttribute("user") Account account){ System.out.println(account); return "success"; }
|
SessionAttributes注解
1 2 3 4 5 6 7 8
| @RequestMapping("/sessionAttribute") public String session(ModelMap model){ model.addAttribute("message","SessionAttribute"); model.get("message"); return "success"; }
|
1 2
| @SessionAttributes(value = "message")
|
1 2 3 4 5 6
| @RequestMapping("/deleteSessionAttribute") public String deleteSession(SessionStatus sessionStatus){ sessionStatus.setComplete(); return "success"; }
|
ModelAndView
1 2 3 4 5 6 7 8 9 10 11 12
| @RequestMapping("/ModelAndView") public ModelAndView modelAndView(){ ModelAndView modelAndView = new ModelAndView(); User user = new User(); user.setNumber("007"); user.setAge("21"); modelAndView.addObject("user",user); modelAndView.setViewName("success"); return modelAndView; }
|
使用关键字进行重定向和请求转发
1 2 3 4 5
| @RequestMapping("/forwardAndRedirect") public String forwardAndDirect(){ return "forward:WEB-INF/pages/success.jsp"; }
|
响应JSON数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.8</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.8</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.9.8</version> </dependency>
|
在webapp下新建js文件夹导入jquery文件
1 2 3 4
| <mvc:resources mapping="/js/**" location="/js/"/>
<mvc:default-servlet-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
| <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <script src="js/JQuery.3.4.1.js"></script> <script> $(function () { $("#btn").on("click",function () { $.ajax({ type: "post", dataType: "json", url: "/testAjax", data: '{"name":"22","number":122}', contentType: "application/json;charset=utf-8", success:function (data) { console.log(data); } }); } ) }); </script> <body> <button id="btn">发送ajax请求</button> </body> </html>
|
1 2 3 4 5 6 7 8 9
| @RequestMapping("/testAjax")
public @ResponseBody Student ajax(@RequestBody Student student) { System.out.println(student); student.setName("张三"); student.setNumber(7); return student; }
|
注意:实体类中不能有有参构造方法
文件上传
1 2 3 4 5 6 7 8 9 10 11
| <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency>
|
form表单的要求 enctype属性必须是”multipart/form-data” method属性必须是post 且提供一个文件选择域<input type = "file">
传统web文件上传
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @RequestMapping("/upload") public String upload(HttpServletRequest request) throws Exception{ System.out.println("文件上传中..."); String path = request.getSession().getServletContext().getRealPath("/upload/"); DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory(); ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory); List<FileItem> items = servletFileUpload.parseRequest(request); for(FileItem item : items){ String fileName = item.getName(); item.write(new File(path,fileName)); } System.out.println("文件上传成功..."); return "success"; }
|
mvc文件上传
1 2 3 4 5
| <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="10000000"/> </bean>
|
1 2 3 4 5 6 7 8 9 10 11
| @RequestMapping("/mvcUpload") public String MvcUpload(HttpServletRequest request, MultipartFile upload) throws IOException { System.out.println("文件上传中..."); String path = request.getSession().getServletContext().getRealPath("/mvcUpload/"); String fileName = upload.getOriginalFilename(); Objects.requireNonNull(fileName); String newFileName = UUID.randomUUID() + fileName.substring(fileName.lastIndexOf(".")); upload.transferTo(new File(path, newFileName)); System.out.println("文件上传成功"); return "success"; }
|
1 2 3 4 5 6
| <form enctype="multipart/form-data" action="mvcUpload" method="post"> <label>选择文件:</label> <!--name的属性值必须和参数MultipartFile的值一样--> <input type="file" name="upload"><br> <input type="submit" value="提交"> </form>
|
spring异常处理
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class SysException extends Exception { private String errorMessage; public SysException(String errorMessage) { this.errorMessage = errorMessage; } public String getErrorMessage() { return errorMessage; } public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class SysExceptionResolver implements HandlerExceptionResolver { public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) { SysException sysException = null; if(e instanceof SysException){ sysException = (SysException) e; }else { sysException = new SysException("系统正在维护。。。"); } ModelAndView mv = new ModelAndView(); mv.addObject("errorMessage",sysException.getErrorMessage()); mv.setViewName("error"); return mv; } }
|
1 2 3
|
<bean id="exceptionResolver" class="cn.qingweico.exception.SysExceptionResolver"/>
|
spring拦截器
spirng拦截器和过滤器的区别:
- 过滤器可以在任何的java web项目下使用,属于servlet技术,可以过滤任何请求
- 拦截器只能在springmvc环境下使用,属于springmvc框架自带的技术,只能对Controller层请求有效
1 2 3 4 5 6 7 8 9 10
| <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="cn.qingweico.interceptor.MyInterceptor"/> </mvc:interceptor> </mvc:interceptors>
|
自定义实现HandlerInterceptor 接口的类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class MyInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("我是拦截器的预处理方法..."); request.getRequestDispatcher("upload.jsp").forward(request,response); return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("我是拦截器的后处理方法..."); request.getRequestDispatcher("upload.jsp").forward(request,response); } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("我是拦截器的最后处理方法..."); } }
|