概念:是 Spring 内置的一个框架,解决了 WEB 开发中的常见问题(参数接收,文件上传,表单验证),支持 Restful 风格的 URL 请求,采用了松散耦合可插拔组件结构,比其他 MVC 框架更具扩展性和灵活性。
优势:

  • 基于 MVC 架构,功能分工明确。解决页面代码和后台代码的分离。
  • 简单易用。SpringMVC 也是轻量级的,jar 很小。不依赖的特定的接口和类就可以开发一个注解的 SpringMVC 项目。
  • 作 为 Spring 框架一部分 , 能够使用 Spring 的 IoC 和 AOP 。 方便整合 MyBatis,Hiberate,JPA 等其他框架。
  • SpringMVC 的注解强大易用。

1. MVC 模式回顾

MVC 框架.png


2. SpringMVC 工作流程

SpringMVC 工作流程.png
配置视图解析器

  1. <!-- 配置视图解析器 -->
  2. <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  3. <property name="prefix" value="/"/>
  4. <property name="suffix" value=".jsp"/>
  5. </bean>

3. @RequestMapping 注解解析

3.1 出现的位置

在类的级别上的注解 会将一个特定请求或者请求模式映射到一个控制器之上。
之后你还可以另外添加方法级别的注解来进一 步指定到处理方法的映射关系。

3.2 指定请求提交方式

@RequestMapping(value = “hello.do”, method = RequestMethod.GET) 只能处理 get 方式提交的请求
@RequestMapping(value = “hello.do”) 都可以

地址栏请求 get 请求
超链接请求 get 请求
表单请求 默认 get,可以指定 post
AJAX请求 默认 get,可以指定 post

3.3 url-pattern

3.3.1 解析

在web.xml配置SpringMVC的前端控制器时有这个节点。这个节点中的值一般有两种写法:

  1. 1. *.do
  2. 在没有特殊要求的情况下,SpringMVC 的前端控制器 DispatcherServlet 的常使用后辍匹配方式,可以写为
  3. *.do 或者 *.action, *.mvc 等。
  4. 2. /
  5. 可以写为/,但是 DispatcherServlet 会将向静态内容--例如.css、.js、图片等资源的获取请求时,也会当
  6. 作是一个普通的 Controller 请求。前端控制器会调用处理器映射器为其查找相应的处理器。肯定找不到啊,所以
  7. 所有的静态资源获取请求也均会报 404 错误。

3.3.2 静态资源访问

如果的值配置为/后,静态资源可以通过以下两种方法解决。

  1. 使用< mvc:default-servlet-handler/ >

在 SpringMVC 的配置文件下配置以下内容

  1. <mvc:default-servlet-handler/>
  2. <!--声 明 了 <mvc:default-servlet-handler /> 后 ,springmvc框架会在容器中创建
  3. DefaultServletHttpRequestHandler处理器对象。该对象会对所有进入 DispatcherServlet的URL
  4. 进行检查。如果发现是静态资源的请求,就将该请求转由Web应用服务器默认的Servlet 处理。
  5. 一般的服务器都有默认的 Servlet。例如咱们使用的Tomcat服务器中,有一个专门用于处理静态资源
  6. 访问的 Servlet 名叫 DefaultServlet。其<servlet-name/>为default。可以处理各种静态资源访问
  7. 请求。该Servlet注册在 Tomcat 服务器的 web.xml 中。在 Tomcat安装目录/conf/web.xml。-->
  1. 使用 < mvc:resources/ >

在 SpringMVC 的配置文件下配置以下内容

  1. <mvc:resources location="/images/" mapping="/images/**" />
  2. <!--
  3. location: 表示静态资源所在目录。当然,目录不要使用/WEB-INF/及其子目录。
  4. mapping: 表示对该资源的请求。注意,后面是两个星号**。-->

4. 处理器方法的参数

处理器方法可以包含以下四类参数,这些参数会在系统调用时由系统自动赋值.所以我们可以在方法内直 接使用。以下是这四类参数:

  • HttpServletRequest
  • HttpServletResponse
  • HttpSession
  • 请求中所携带的请求参数

4.1 直接使用方法的参数直接接收

好处:传递参数的格式不会改变

  1. @RequestMapping(value = "test01.do", method= RequestMethod.POST)
  2. public ModelAndView test01(Integer id, String name, String address){
  3. System.out.println("test01.do---------");
  4. System.out.println(id);
  5. System.out.println(name);
  6. System.out.println(address);
  7. return new ModelAndView("ok");
  8. }
  1. <h1> 直接使用方法的参数直接接收 </h1>
  2. <form action="test01.do" method="post">
  3. <input name="id" type="text" placeholder="id"/><br>
  4. <input name="name" type="text" placeholder="name"/><br>
  5. <input name="address" type="text" placeholder="address"/><br>
  6. <button type="submit">提交</button>
  7. </form>

4.2 使用对象接收多个参数

注意:要求用户请求中携带的参数名称必须与实体类中的属性保持一致,否则获取不到

  1. @RequestMapping(value = "test02.do", method= RequestMethod.POST)
  2. public ModelAndView test02(Team team){
  3. System.out.println("test02.do---------");
  4. System.out.println(team);
  5. return new ModelAndView("ok");
  6. }
  1. <h1> 2. 直接使用对象直接接收 </h1>
  2. <form action="/param/test02.do" method="post">
  3. <input name="id" type="text" placeholder="id"/><br>
  4. <input name="name" type="text" placeholder="name"/><br>
  5. <input name="address" type="text" placeholder="address"/><br>
  6. <button type="submit">提交</button>
  7. </form>

4.3 请求参数和方法参数不一致

使用 @RequestParam 注解

  • value:表单中的参数名
  • required true:必须赋值,否则报400错误;false:可以不赋值,结果是 null。
    1. @RequestMapping(value = "test03.do", method= RequestMethod.POST)
    2. public ModelAndView test03(@RequestParam("id") Integer a,
    3. @RequestParam("name") String b,
    4. @RequestParam("address") String c){
    5. System.out.println("test03.do---------");
    6. System.out.println(a);
    7. System.out.println(b);
    8. System.out.println(c);
    9. return new ModelAndView("ok");
    10. }
    1. <h1> 3. 请求参数和方法参数不一致 </h1>
    2. <form action="/param/test03.do" method="post">
    3. <input name="id" type="text" placeholder="id"/><br>
    4. <input name="name" type="text" placeholder="name"/><br>
    5. <input name="address" type="text" placeholder="address"/><br>
    6. <button type="submit">提交</button>
    7. </form>

4.4 使用HttpServletRequest 对象获取参数

与 java web 当中一样

4.5 直接使用URL地址传参: 借助@PathVariable 注解

4.6 获取日期类型的参数

4.7 获取数组类型的参数

4.8 获取集合类型的参数

简单类型的可以通过@RequestParam注解实现;对象集合不支持直接获 取,必须封装在类中,作为一个属性操作


5. 请求参数中文乱码

web.xml 中进行如下配置

  1. <filter>
  2. <filter-name>characterEncodingFilter</filter-name>
  3. <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  4. <init-param>
  5. <param-name>encoding</param-name>
  6. <param-value>UTF-8</param-value>
  7. </init-param>
  8. <init-param>
  9. <param-name>forceRequestEncoding</param-name>
  10. <param-value>true</param-value>
  11. </init-param>
  12. <init-param>
  13. <param-name>forceResponseEncoding</param-name>
  14. <param-value>true</param-value>
  15. </init-param>
  16. </filter>
  17. <filter-mapping>
  18. <filter-name>characterEncodingFilter</filter-name>
  19. <url-pattern>/*</url-pattern>
  20. </filter-mapping>

6. 处理器方法的返回值

6.1 返回 ModelAndView

数据模型+视图
当处理器方法处理完后,需要跳转到其它资源的同时传递数据,选择返回 ModelAndView 比较好,但是 如果只是需要传递数据或者跳转之一,这个时候ModelAndView 就不是最优选择。

  1. //1、返回值是ModelAndView: 这种方式既有数据的携带还有资源的跳转,可以选择该种方式
  2. @RequestMapping("test01")
  3. public ModelAndView test01(){
  4. ModelAndView mv=new ModelAndView();//模型与视图
  5. //携带数据
  6. mv.addObject("teamName","湖人队");//相当于request。
  7. setAttribute("teamName","湖人队“);
  8. mv.setViewName("result");
  9. // 经过视图解析器InternalResourceViewResolver的处理,
  10. 将逻辑视图名称加上前后缀变为物理资源路径 /jsp/result.jsp
  11. return mv;
  12. }

6.2 返回 String

  1. //2、返回字符串
  2. @RequestMapping("test02")
  3. public String test02(HttpServletRequest request){
  4. Team team=new Team();
  5. team.setLocation("迈阿密");
  6. team.setTeamId(1002);
  7. team.setTeamName("热火");
  8. //携带数据
  9. request.setAttribute("team",team);
  10. request.getSession().setAttribute("team",team);
  11. //资源的跳转
  12. return "result";// 经过视图解析器InternalResourceViewResolver的处理,将逻辑视
  13. 图名称加上前后缀变为物理资源路径 /jsp/result.jsp
  14. }
  1. <h3>test02---request作用域获取:---${requestScope.team.teamName}--
  2. -${requestScope.team.teamId}---${requestScope.team.location}</h3>
  3. <h3>test02---session作用域获取:---${sessionScope.team.teamName}--
  4. -${sessionScope.team.teamId}---${sessionScope.team.location}</h3>

6.3 返回对象类型

6.3.1 返回基础类型

6.3.2 返回自定义对象类型

6.3.3 返回 List

6.3.4 返回 Map

6.4 无返回值 void


7. 页面导航的方式

7.1 转发

7.1.1 String

  1. @RequestMapping("d1.do")
  2. public String demo01(){
  3. return "ok";// 默认方式,由视图解析器处理
  4. return "forward:/ok.jsp";// 添加forward之后,视图解析器失效,需要添加绝对路径
  5. }

7.1.2 ModelAndView

  1. @RequestMapping("d2.do")
  2. public ModelAndView demo02(){
  3. ModelAndView mav = new ModelAndView();
  4. //mav.setViewName("ok");
  5. mav.setViewName("forward:/ok.jsp");
  6. return mav;
  7. }

7.2 重定向

7.2.1 String

  1. @RequestMapping("d3.do")
  2. public String demo03(){
  3. //return "ok";// 默认方式,由视图解析器处理
  4. return "redirect:/ok.jsp";// 添加 redirect 之后,视图解析器失效,需要添加绝对路径
  5. }

7.2.2 ModelAndView

  1. @RequestMapping("d4.do")
  2. public ModelAndView demo04(){
  3. ModelAndView mav = new ModelAndView();
  4. // 使用 ModelAndView 返回解决了重定向数据丢失的问题
  5. // 数据显示在地址栏中
  6. mav.addObject("teamName", "Real Madrid");
  7. mav.addObject("teamRank", "63");
  8. // <h3>teamName:${param.teamName}</h3> 可以获取到!
  9. // mav.setViewName("ok");
  10. mav.setViewName("redirect:/ok.jsp");
  11. return mav;
  12. }

7.3 转发或重定向到控制器

  1. @RequestMapping("d5.do")
  2. public ModelAndView demo05(){
  3. System.out.println("转发~~~~~~~~~~~");
  4. ModelAndView mav = new ModelAndView();
  5. //mav.setViewName("ok");
  6. mav.setViewName("forward:/n/d1.do");
  7. return mav;
  8. }
  9. @RequestMapping("d6.do")
  10. public ModelAndView demo06(){
  11. System.out.println("重定向~~~~~~~~~~~");
  12. ModelAndView mav = new ModelAndView();
  13. //mav.setViewName("ok");
  14. mav.setViewName("redirect:/n/d1.do");
  15. return mav;
  16. }

8. 异常处理

8.1 @ExceptionHandler

@ExceptionHandler 可以将一个方法指定为异常处理方法。
被注解的方法,其返回值可以是 ModelAndView、String,或 void,方法名随意,方法参数可以是 Exception 及其子类对象、HttpServletRequest、HttpServletResponse 等。系统会自动为这些方法参 数赋值。
对于异常处理注解的用法,也可以直接将异常处理方法注解于 Controller 之中.


  1. @Controller
  2. @RequestMapping("e")
  3. public class ExceptionController {
  4. @RequestMapping("d1.do")
  5. public ModelAndView test01(Integer teamId, String teamName) throws TeamIdException, TeamNameException {
  6. ModelAndView mav = new ModelAndView();
  7. if (teamId<1000){
  8. throw new TeamIdException("teamId 不可以小于 1000!");
  9. }
  10. if ("test".equals(teamName)){
  11. throw new TeamNameException("teamName不可以是 test!");
  12. }
  13. mav.setViewName("ok");
  14. return mav;
  15. }
  16. @ExceptionHandler(value = {TeamIdException.class, TeamNameException.class, Exception.class})
  17. public ModelAndView handler(Exception e){
  18. ModelAndView mav = new ModelAndView();
  19. mav.addObject("message", e.getMessage());
  20. if (e instanceof TeamIdException){
  21. mav.setViewName("idError");
  22. }else if (e instanceof TeamNameException){
  23. mav.setViewName("nameError");
  24. }else{
  25. mav.setViewName("error");
  26. }
  27. return mav;
  28. }
  29. }

8.2 优化

将异常处理方法集中到一个类中,更简洁,方便维护。

  1. @ControllerAdvice
  2. public class GlobalExceptionHandler {
  3. @ExceptionHandler(value = TeamIdException.class)
  4. public ModelAndView idHandler(Exception e){
  5. ModelAndView mav = new ModelAndView();
  6. mav.addObject("message", e.getMessage());
  7. mav.setViewName("idError");
  8. return mav;
  9. }
  10. @ExceptionHandler(value = TeamNameException.class)
  11. public ModelAndView nameHandler(Exception e){
  12. ModelAndView mav = new ModelAndView();
  13. mav.addObject("message", e.getMessage());
  14. mav.setViewName("nameError");
  15. return mav;
  16. }
  17. @ExceptionHandler(value = Exception.class)
  18. public ModelAndView Handler(Exception e){
  19. ModelAndView mav = new ModelAndView();
  20. mav.addObject("message", e.getMessage());
  21. mav.setViewName("error");
  22. return mav;
  23. }
  24. }

9. 拦截器

拦截的时间点在“处理器映射器HandlerMapping根据用户提交的请求映射出了所要执行的处理器类,并 且也找到了要执行该处理器类的处理器适配器,在处理器适配器HandlerAdaptor执行处理器之前”。

在处理器映射器映射出所要执行的处理器类时,已经将拦截器与处理器组合为了一个处理器执行链 HandlerExecutionChain,并返回给了前端控制器。

preHandle(request,response, Object handler):
该方法在处理器方法执行之前执行。其返回值为boolean,若为true,则紧接着会执行处理器方法,且 会将afterCompletion()方法放入到一个专门的方法栈中等待执行。
postHandle(request,response, Object handler,modelAndView):
该方法在处理器方法执行之后执行。处理器方法若最终未被执行,则该方法不会执行。由于该方法是在处 理器方法执行完后执行,且该方法参数中包含 ModelAndView,所以该方法可以修改处理器方法的处理结果 数据,且可以修改跳转方向。
afterCompletion(request,response, Object handler, Exception ex):
preHandle()方法返回true时,会将该方法放到专门的方法栈中,等到对请求进行响应的所工作完
成之后才执行该方法。即该方法是在前端控制器渲染(数据填充)了响应页面之后执行的,此时对
ModelAndView再操作也对响应无济于事。
afterCompletion最后执行的方法,清除资源,例如在Controller方法中加入数据


9.1 自定义拦截器

  1. public class MyInterceptor implements HandlerInterceptor {
  2. @Override
  3. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  4. System.out.println("preHandle ~~~~~~");
  5. return true;
  6. }
  7. @Override
  8. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  9. System.out.println("postHandle ~~~~~~");
  10. }
  11. @Override
  12. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
  13. System.out.println("afterCompletion ~~~~~~");
  14. }
  15. }

9.2 配置拦截器

  1. <mvc:interceptors>
  2. <mvc:interceptor>
  3. <mvc:mapping path="/**"/>
  4. <bean class="com.zmh.interceptor.MyInterceptor" id="interceptor"/>
  5. </mvc:interceptor>
  6. <mvc:interceptor>
  7. <mvc:mapping path="/**"/>
  8. <bean class="com.zmh.interceptor.MyInterceptor1" id="interceptor1"/>
  9. </mvc:interceptor>
  10. </mvc:interceptors>

10. 文件上传和下载

10.1 上传

  1. pom.xml 中添加相关依赖

    1. <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
    2. <dependency>
    3. <groupId>commons-fileupload</groupId>
    4. <artifactId>commons-fileupload</artifactId>
    5. <version>1.3.1</version>
    6. </dependency>
  2. SpingMVC.xml 中手动添加 bean

    1. <bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver"/>
  3. 创建表单

    1. <body>
    2. <h1>文件上传</h1>
    3. <form action="/file/upload.do" method="post" enctype="multipart/form-data">
    4. 请选择文件
    5. <input type="file" name="myFile"><br>
    6. <button type="submit">上传文件</button>
    7. </form>
    8. </body>
  4. 代码

    1. @Controller
    2. @RequestMapping("file")
    3. public class FileController {
    4. @RequestMapping("hello.do")
    5. public String hello(){
    6. return "upload";
    7. }
    8. @RequestMapping("upload.do")
    9. public String upload(@RequestParam("myFile") MultipartFile myFile, HttpServletRequest req) throws IOException {
    10. // 1. 获取文件的原始名称
    11. String originalFilename = myFile.getOriginalFilename();
    12. System.out.println("文件原始名称:"+originalFilename);
    13. // 2. 文件重命名 之后存储
    14. String end = originalFilename.substring(originalFilename.lastIndexOf("."));
    15. System.out.println("文件名称后缀:"+end);
    16. String fileName = UUID.randomUUID().toString().replace("-", " ")+end;
    17. System.out.println("文件重命名后名称:"+fileName);
    18. // 3. 文件存储路径
    19. String realPath = req.getServletContext().getRealPath("/upload")+"/";
    20. // 4. 上传
    21. myFile.transferTo(new File(realPath+fileName));
    22. System.out.println("上传成功 位置是 "+realPath+fileName);
    23. return "ok";
    24. }
    25. }
  5. 优化(限制)

  • 限制文件大小(异常处理)

    1. <bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
    2. <property name="maxUploadSize" value="368640"/>
    3. <property name="defaultEncoding" value="utf-8"/>
    4. </bean>
    1. @ExceptionHandler(value = MaxUploadSizeExceededException.class)
    2. public ModelAndView Handler(Exception e){
    3. ModelAndView mav = new ModelAndView();
    4. mav.addObject("message", "别给我整这么大的,俺受不了!");
    5. mav.setViewName("error");
    6. return mav;
    7. }
  • 限制文件类型(拦截器)

    1. public class FileInterceptor implements HandlerInterceptor {
    2. /**
    3. * 在文件上传之前判断是否合乎规则
    4. * @param request
    5. * @param response
    6. * @param handler
    7. * @return
    8. * @throws Exception
    9. */
    10. @Override
    11. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    12. boolean flag = true;
    13. // 1. 首先判断请求是否是文件上传的请求
    14. if (request instanceof MultipartHttpServletRequest){
    15. // 2. request 强制类型转换
    16. MultipartHttpServletRequest multipartReq = (MultipartHttpServletRequest) request;
    17. // 3. 取出文件集
    18. Map<String, MultipartFile> fileMap = multipartReq.getFileMap();
    19. System.out.println("map!!! "+fileMap);
    20. // 4. 循环遍历 map 中方法
    21. Iterator<String> iterator = fileMap.keySet().iterator();
    22. while(iterator.hasNext()){
    23. String key = iterator.next();
    24. MultipartFile file = fileMap.get(key);
    25. String originalFilename = file.getOriginalFilename();
    26. String substring = originalFilename.substring(originalFilename.lastIndexOf("."));
    27. System.out.println("后缀:"+substring);
    28. if (! ".png".equals(substring.toLowerCase()) && ! substring.toLowerCase().equals(".jpg")){
    29. multipartReq.getRequestDispatcher("/fileError.jsp").forward(request, response);
    30. flag = false;
    31. }
    32. }
    33. }
    34. return flag;
    35. }
    36. }

    之后在 SpringMVC.xml 中配置拦截器

10.2 下载

  1. @RequestMapping("download.do")
  2. public ResponseEntity<byte[]> download(HttpServletRequest req) throws IOException {
  3. // 1. 指定文件路径
  4. String path = req.getServletContext().getRealPath("/upload")+"/cc1b8fc4 5eb5 451d 80b5 6c1870f85b76.md";
  5. // 2. 创建响应头信息对象
  6. HttpHeaders headers = new HttpHeaders();
  7. // 3. 标记以流的方式作出相应
  8. headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
  9. // 4. 以附件的形式响应给用户
  10. headers.setContentDispositionFormData("attachment",
  11. URLEncoder.encode("cc1b8fc4 5eb5 451d 80b5 6c1870f85b76.md", "utf-8"));
  12. File file = new File(path);
  13. ResponseEntity<byte[]> resp = new ResponseEntity<>(FileUtils.readFileToByteArray(file), headers, HttpStatus.CREATED);
  14. return resp;
  15. }

11. RESTful

11.1 概念

REST(英文:Representational State Transfer,简称REST,意思:表述性状态转换,描述了一个架构 样式的网络系统,比如web应用)。


REST指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是RESTful。
特性:

  • 资源
  • 表现层
  • 状态转换

GET用来获取资源,POST用来新建资源,PUT用来更新资源,DELETE用来删除资源。

使用RESTful操作资源:
GET /expresses #查询所有的快递信息列表
GET /express/1006 #查询一个快递信息
POST /express #新建一个快递信息
PUT /express/1006 #更新一个快递信息(全部更新)
PATCH /express/1006 #更新一个快递信息(部分更新)
DELETE /express/1006 #删除一个快递信息


11.2 API 设计

  1. 动词+宾语

    • 动词大写
    • 一些代理只支持POST和GET方法, 为了使用这些有限方法支持RESTful API,需要一种办法覆盖 http原来的方法。使用订制的HTTP头 X-HTTP-Method-Override 来覆盖POST 方法.
  2. 宾语必须是名词

  3. 避免多级 URL

11.3 HTTP 状态码

五类状态码分别如下:

  • 1xx:相关信息
  • 2xx:操作成功
  • 3xx:重定向
  • 4xx:客户端错误
  • 5xx:服务器错误
  • PS:API 不需要1xx状态码,所以这个类别直接忽略。


11.4 服务器响应

服务器返回的信息一般不推荐纯文本,而是建议大家选择JSON 对象,因为这样才能返回标准的结构化数 据。

11.5 案例

11.5.1 查询

jsp页面

  1. <form action="" id="myForm" method="post">
  2. 球队ID:<input name="id" type="text" id="teamId"/><br>
  3. 球队名称:<input name="name" type="text"/><br>
  4. 球队address:<input name="location" type="text"/><br>
  5. <button type="button" id="getAll">查询所有 GET</button>
  6. <button type="button" id="getOne">查询单个 GET</button>
  7. <button type="button" id="post">添加 POST</button>
  8. <button type="button" id="put">更新 PUT</button>
  9. <button type="button" id="delete">删除 DELETE</button>
  10. </form>
  11. <p id="result"></p>
  12. <script>
  13. $(function(){
  14. $("#getAll").click(function(){
  15. $.ajax({
  16. type: "GET",
  17. url: "/teams",
  18. data: "",
  19. dataType: "json",
  20. success:function(data){
  21. alert("Data Is Found !");
  22. var str = "";
  23. for (var i=0; i<data.length; i++){
  24. var o = data[i];
  25. str +=o.id+"---"+o.name+"---"+o.address+"<br>";
  26. }
  27. $("#result").html(str);
  28. }
  29. });
  30. });
  31. $("#getOne").click(function(){
  32. $.ajax({
  33. type: "GET",
  34. url: "/team/"+$("#teamId").val(),
  35. data: "",
  36. dataType: "json",
  37. success:function(data){
  38. alert("Data Is Found !");
  39. var str = "";
  40. if (data==null){
  41. str="没找到..."
  42. }else{
  43. str +=data.id+"---"+data.name+"---"+data.address+"<br>";
  44. }
  45. $("#result").html(str);
  46. }
  47. });
  48. });
  49. });
  50. </script>
  1. @RequestMapping(value = "teams", method = RequestMethod.GET)
  2. @ResponseBody
  3. public List<Team> get1(){
  4. System.out.println("getAll ~~~~~~");
  5. return teamList;
  6. }
  7. @RequestMapping(value = "team/{teamId}", method = RequestMethod.GET)
  8. @ResponseBody
  9. public Team get2(@PathVariable("teamId") int id){
  10. System.out.println("getOne ~~~~~~");
  11. for (Team team : teamList) {
  12. if(team.getId()==id){
  13. return team;
  14. }
  15. }
  16. return null;
  17. }

11.5.2 添加

11.5.3 更新

  1. @RequestMapping(value = "team/{id}", method = RequestMethod.PUT)
  2. @ResponseBody
  3. public int update(@PathVariable("id") int id, Team team){
  4. System.out.println("update ~~~~~~");
  5. for (Team team1 : teamList) {
  6. if(team1.getId()==id){
  7. team1.setName(team.getName());
  8. team1.setAddress(team.getAddress());
  9. return 1;
  10. }
  11. }
  12. return 0;
  13. }
  1. $("#put").click(function(){
  2. $.ajax({
  3. type: "POST",
  4. url: "/team/"+$("#teamId").val(),
  5. data: $("#myForm").serialize()+"&_method=PUT",
  6. dataType: "json",
  7. success:function(data){
  8. $("#result").html(data==1?"修改成功":"修改失败");
  9. }
  10. });
  11. });

11.5.4 删除

  1. @RequestMapping(value = "team/{id}", method = RequestMethod.DELETE)
  2. @ResponseBody
  3. public int delete(@PathVariable("id") int id) {
  4. System.out.println("delete ~~~~~~");
  5. for (Team team1 : teamList) {
  6. if (team1.getId() == id) {
  7. teamList.remove(team1);
  8. return 1;
  9. }
  10. }
  11. return 0;
  12. }
  1. $("#delete").click(function(){
  2. $.ajax({
  3. type: "POST",
  4. url: "/team/"+$("#teamId").val(),
  5. data: "&_method=DELETE",
  6. dataType: "json",
  7. success:function(data){
  8. $("#result").html(data==1?"删除成功":"修改失败");
  9. }
  10. });
  11. });

11.5.5 注意

对于更新和删除 PUTDELETE, 需要在请求的 url 中加上 &_method=PUT 或者 &_method=DELETE

然后在 web.xml 中进行相应过滤器的配置

  1. <filter>
  2. <filter-name>hiddenHttpMethodFilter</filter-name>
  3. <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
  4. </filter>
  5. <filter-mapping>
  6. <filter-name>hiddenHttpMethodFilter</filter-name>
  7. <url-pattern>/*</url-pattern>
  8. </filter-mapping>

11.6 封装相应结果