SpringMVC学习笔记(全)

本文案例

SpringMVC案例01–入门

SpringMVC案例02–RequestBody响应json数据

SpringMVC案例03–传统文件上传方式

SpringMVC案例04–利用SpringMVC框架提供的组件实现文件上传

SpringMVC案例05–SpringMVC跨服务器文件上传

SpringMVC案例06–异常处理

SpringMVC案例07–自定义拦截器

三层架构介绍与MVC模型

开发架构一般有两种形式,一种是B/S,一种是C/S。在JavaEE开发中几乎全部使用B/S架构,在B/S架构中,系统标准的三层架构包括:表现层,业务层,持久层。

三层架构介绍

表现层

也称为web层,负责接收客户端请求,向客户端响应结果,表现层包括展示层和控制层。展示层负责展示结果,控制层负责接收请求。

表现层依赖业务层,表现层接受完请求后调用业务层对数据进行处理,并将处理结果响应给客户端。

表现层一般使用基于MVC模型的框架例如struct2,SpringMVC等。

业务层

也是service层,负责业务逻辑处理,业务层可能会依赖持久层(要求对数据持久化需要保持事务的一致性)。

持久层

也是dao层,负责数据持久化,通俗来讲,持久层是和数据库进行交互,对数据进行CRUD的一层。

MVC模型

MVC,全称 Model View Controller,是一种用于创建web应用程序表现层的模式。

Model

模型,即数据模型,用于封装数据。

View

视图,常见的JSP,Html,用于展示数据,视图通常依靠模型建立。

Controller

控制器,是应用程序和用户交互的部分,处理程序逻辑。

SpringMVC概述

SpringMVC概念

Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的Spring MVC框架或集成其他MVC开发框架,如Struts1(现在一般不用),Struts 2(一般老项目使用)等等。

SpringMVC在三层架构中的位置

在这里插入图片描述

SpringMVC 的优势

  • 清晰的角色划分:
    • 前端控制器(DispatcherServlet)
    • 请求到处理器映射(HandlerMapping)
    • 处理器适配器(HandlerAdapter)
    • 视图解析器(ViewResolver)
    • 处理器或页面控制器(Controller)
    • 验证器( Validator)
    • 命令对象(Command 请求参数绑定到的对象就叫命令对象)
    • 表单对象(Form Object 提供给表单展示和提交到的对象就叫表单对象)。
  • 分工明确,而且扩展点相当灵活,可以==很容易扩展==,虽然几乎不需要。
  • 由于命令对象就是一个 POJO,无需继承框架特定 API,可以使用命令对象直接作为业务对象。
  • 和 Spring 其他框架无缝集成,是其它 Web 框架所不具备的。
  • 可适配,通过 HandlerAdapter 可以支持任意的类作为处理器。
  • 可定制性,HandlerMapping、ViewResolver 等能够非常简单的定制。
  • 功能强大的数据验证、格式化、绑定机制。
  • 利用 Spring 提供的 Mock 对象能够非常简单的进行 Web 层单元测试。
  • 本地化、主题的解析的支持,使我们更容易进行国际化和主题的切换。
  • 强大的 JSP 标签库,使 JSP 编写更容易。
  • ………………还有比如RESTful风格的支持、简单的文件上传、约定大于配置的契约式编程支持、基于注解的零配置支持等等。

SpringMVC 和 Struts2 的优略分析

共同点

  • 它们都是表现层框架,都是基于 MVC 模型编写的。
  • 它们的底层都离不开原始 ServletAPI。
  • 它们处理请求的机制都是一个核心控制器。

区别

  • Spring MVC 的入口是 Servlet, 而 Struts2 是 Filter

  • Spring MVC 是基于方法设计的而 Struts2 是基于类,Struts2 每次执行都会创建一个动作类。所以 Spring MVC 会稍微比 Struts2 快些

  • Spring MVC 使用更加简洁,同时还支持 JSR303, 处理 ajax 的请求更方便

  • Struts2 的 OGNL 表达式使页面的开发效率相比 Spring MVC 更高些,但执行效率并没有比 JSTL 提升,尤其是 struts2 的表单标签,远没有 html 执行效率

    高。

  • (JSR303 是一套 JavaBean 参数校验的标准,它定义了很多常用的校验注解,我们可以直接将这些注解加在我们 JavaBean 的属性上面,就可以在需要校验的时

  • 候进行校验了。)

SpringMVC入门案例

案例01:SpringMVC案例01–入门

常用标签

  • @Controller

  • 作用:标识当前类是一个控制器

  • @RequestMapping(path = “/hello”)

    • 作用:指定被访问路径

    • 属性

      • value(path),指定请求的URL,path和value作用一样

      • method,指定请求的方式

      • params,指定限制请求参数的条件,要求请求参数的 key 和 value 必须和配置的一模一样

        eg1:表示请求参数必须有 accountName

        params = {"accountName"}
        

        eg2:表示请求参数中 money 不能是 100

        params = {"moeny!100"}
        

        eg3:请求参数必须有参数name,且值必须是zhangsan

        @RequestMapping(path = "/hello",method = {RequestMethod.POST},params = {"name=zhangsan"})
        

        eg4:请求类型必须为POST

        @RequestMapping(path = "/hello",method = {RequestMethod.POST})
        
    • 扩展

      • 使用二级访问目录

        • 作用:url指向更明确

        • eg:访问url的为: account/hello

          @Controller /*将HelloController交给spring管理*/
          @RequestMapping("/account")
          public class HelloController {
              @RequestMapping(path = "/hello",method = {RequestMethod.POST},params = {"name=zhangsan"})
              public String hello(){
                  System.out.println("hello springmvc");
                  return "success";
              }
          }
          

SpringMVC中组件介绍

DispatcherServlet

用户请求到达前端控制器,它就相当于 mvc 模式中的 c,dispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet 的存在降低了组件之间的耦合性。

HandlerMapping

HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。

HandlAdapter

通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。

View Resolver

View Resolver 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。

Handler

它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到 Handler。由Handler 对具体的用户请求进行处理。

View

SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView等。我们最常用的视图就是 jsp。
一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面。

SpringMVC执行原理

参考博客:SpringMVC执行原理

请求参数的绑定

绑定的机制

SpringMVC 绑定请求参数的过程是通过把表单提交的请求参数,作为控制器中方法参数进行绑定的,如下所示。

jsp代码a标签中的username

<a href="params/basicParam?username=zhangsan">基本类型</a><br>

controller中方法中的username参数

@RequestMapping("/basicParam")
    public String BasicParam(String username) {
        System.out.println("用户名:" + username);
        return "success";
    }

绑定支持的数据类型

请求参数绑定基本数据类型

8种基本类型(四种整数类型:byte、short、int、long;两种浮点数类型:float、double;一种字符类型:char;一种布尔类型:boolean)

如果有多个参数,使用,隔开即可

jsp:

<a href="params/basicParam?username=zhangsan">基本类型</a><br>

controller:

@RequestMapping("/basicParam")
    public String BasicParam(String username) {
        System.out.println("用户名:" + username);
        return "success";
    }

请求参数绑定实体类(不关联其他实体)

只要表单中name能够和实体类属性名匹配即可实现封装

jsp:

<h1>2、引用数据类型</h1>
<form action="params/accountParam" method="post">
    账户名:<input type="text" name="username"><br>
    密码:<input type="text" name="password"><br>
    存款:<input type="text" name="money"><br>
    <input type="submit" value="提交">
</form>

controller:

 @RequestMapping("/accountParam")
    public String AccountParam(Account account) {
        System.out.println(account);
        return "success";
    }

请求参数绑定实体类(关联实体类)

Account类关联User类

domain:

public class Account  implements Serializable {
    private String username;
    private String password;
    private Double money;
    private User user;
    .....
}

jsp:

<h1>3、Account类中存在一个引用变量</h1>
<form action="params/accountParam2" method="post">
    账户名:<input type="text" name="username"><br>
    密码:<input type="text" name="password"><br>
    存款:<input type="text" name="money"><br>
    用户名:<input type="text" name="user.uname"><br>
    年龄:<input type="text" name="user.age"><br>
    <input type="submit" value="提交">
</form>

controller:

    @RequestMapping("/accountParam2")
    public String AccountParam2(Account account) {
        System.out.println(account);
        return "success";
    }

请求参数绑定list和map集合

实体类包含数组和集合类型的属性

domain:

public class Account  implements Serializable {
    private String username;
    private String password;
    private Double money;
    private List<User> list;
    private Map<String,User> map;
    .....
}

jsp:

<h1>4、Account类存在list和map集合</h1>
<form action="params/accountParam3" method="post">
    账户名:<input type="text" name="username"><br>
    密码:<input type="text" name="password"><br>
    存款:<input type="text" name="money"><br>
    用户名:<input type="text" name="list[0].uname"><br>
    年龄:<input type="text" name="list[0].age"><br>
    用户名:<input type="text" name="map['one'].uname"><br>
    年龄:<input type="text" name="map['one'].age"><br>
    <input type="submit" value="提交">
</form>

controller:

   @RequestMapping("/accountParam3")
    public String AccountParam3(Account account) {
        System.out.println(account);
        return "success";
    }

请求参数乱码问题

使用post请求类型传递中文参数时,如果不进行处理,会造成后台获取的数据发生乱码。

servlet解决请求参数中文乱码

request.setCharacterEncoding("UTF-8");

springMVC中解决办法,在web.xml中添加过滤器

CharacterEncodingFilter类是spring提供的一个类,可以在其中找到相关的属性,例如encodingforceEncoding,通过自行配置,实现需求。

    <!--配置解决中文乱码的过滤器-->
    <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原生API

只需要在控制的方法参数定义需要的对象

@RequestMapping("/servletAPI")
    public String servletAPI(HttpSession httpSession, HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
        System.out.println(httpResponse);
        System.out.println(httpSession);
        System.out.println(httpRequest);
        System.out.println(httpSession.getServletContext());
        return "success";
    }

自定义类型转换器

应用场景举例

字符串转日期默认可以识别的格式是:2009/10/10,如果用户输入的格式为2009-10-10,后台没有这种类型的转换器,这个时候就需要用到自定义类型转换器了。

使用步骤

新建类型转换器类StringToDateConverter

public class StringToDateConverter implements Converter<String, Date> {
    @Override
    public Date convert(String source) {
        System.out.println("converter 执行了。。。");
        //创建一个格式转换器
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        try {
            if (source == null) {
                throw new RuntimeException("输入的日期为空");
            }
            return format.parse(source);
        } catch (Exception e) {
            throw new RuntimeException("输入的格式错误");
        }
    }
}

在springmvc.xml中配置自定义转换器

<!--    配置自定义类型转换器-->
    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="com.cncs.utils.StringToDateConverter"></bean>
            </set>
        </property>
    </bean>

开启自定义转换器的服务

<!--    开启spring对注解mvc的支持-->
    <mvc:annotation-driven conversion-service="conversionService"/>

常用注解

@RequestParam

  • 作用

  • 把请求中指定名称的参数给控制器中的形参赋值

  • 属性

    • value,为形参改的别名,与jsp中参数名对应
    • required,是否必须
  • 举例

    jsp:

     <form action="anno/testRequestParam" method="post" >
                姓名:<input type="text" name="name"><br>
                年龄:<input type="text" name="age"><br>
                <input type="submit" value="提交"><br>
            </form>
    

    controller:

    @RequestMapping(value = "/testRequestParam")
        public String useRequestParam(@RequestParam(name = "name") String username, @RequestParam(name = "age", required = false) Integer age) {
            System.out.println("testRequestParam执行了。。。");
            System.out.println("用户名:" + username + "\t年龄:" + age);
            return "success";
        }
    

@RequestBody

注意:get 请求方式不适用

  • 作用

  • 用于获取请求体内容。直接使用得到是 key=value&key=value…结构的数据

  • 属性

  • value、required

  • 举例

    jsp:

    <form action="anno/testRequestBody" method="post" >
                姓名:<input type="text" name="name"><br>
                年龄:<input type="text" name="age"><br>
                <input type="submit" value="提交"><br>
            </form>
    

    controller:

     @RequestMapping(value = "/testRequestBody")
        public String testRequestBody(@RequestBody(required = false) String body) {
            System.out.println("testRequestBody。。。");
            System.out.println("body:" + body);
            return "success";
        }
    

@pathVariable

  • 作用

  • 用于绑定 url 中的占位符1

  • 属性

    • value,用于指定 url 中占位符名称
    • required
  • 举例

    jsp:

     <a href="anno/testPathVariable/200">testPathVaribale</a>
    

    controller:

      @RequestMapping(value = "/testPathVariable/{id}")
        public String testPathVariable(@PathVariable(name = "id") Integer nowId) {
            System.out.println("testPathVariable。。。");
            System.out.println("id:" + nowId);
            return "success";
        }
    

@RequestHeader

  • 作用

    • 用于获取请求消息头
  • 属性

    • value,提供消息头名称
    • required
  • 举例

    jsp:

    <a href="anno/testRequestHeader">testRequestHeader</a>
    

    controller:

     @RequestMapping(value = "/testRequestHeader")
        public String testRequestHeader(@RequestHeader(name = "Connection") String header) {
            System.out.println("testRequestHeader。。。");
            System.out.println(header);
            return "success";
        }
    

@CookieValue

  • 作用

    • 用于把指定 cookie 名称的值传入控制器方法参数
  • 属性

    • value,指定 cookie 的名称
    • required
  • 举例

    jsp:

    <a href="anno/testCookieValue">testCookieValue</a>
    

    controller:

    @RequestMapping(value = "/testCookieValue")
        public String testCookieValue(@CookieValue(name = "JSESSIONID") String cookieValue) {
            System.out.println("testCookieValue。。。");
            System.out.println(cookieValue);
            return "success";
        }
    

@ModelAttribute

  • 作用

    • 出现在方法上,表示当前方法会在控制器的方法执行之前先执行
    • 出现在参数上,获取指定的数据,给参数赋值
  • 属性

    • value,出现在方法上,可以不写;出现在参数上,必须写value的值
    • required
  • 应用场景

    • 它可以用于修饰方法和参数,在对数据进行操作时,如果表单提交的数据不够完整,可以先从数据库查询数据,然后自动注入表单中存在的数据,不存在的数据使用数据库中的数据。
  • 例一

    jsp代码:

    <form action="anno/testModelAttribute" method="post" >
                姓名:<input type="text" name="uname"><br>
                年龄:<input type="text" name="age"><br>
                <input type="submit" value="提交"><br>
            </form>
    

    controller代码:

    showUser()会先于testModelAttribute()方法执行,showUser()返回的User对象会被testModelAttribute()的参数拿到。

    @RequestMapping(value = "/testModelAttribute")
        public String testModelAttribute(User user) {
            System.out.println("testModelAttribute。。。");
            System.out.println(user);
            return "success";
        }
    
    @ModelAttribute
        public User showUser(String uname) {
            //模拟从数据库查询数据
            User user = new User();
            user.setUname(uname);
            user.setAge(19);
            user.setBirthday(new Date());
            return user;
        }
    
  • 例二

    jsp代码和例一相同。

    controller代码:

    showUser()方法必须有Map参数,testModelAttribute()方法参数必须使用注解@ModelAttribute拿到User对象。

    @RequestMapping(value = "/testModelAttribute")
        public String testModelAttribute(@ModelAttribute("user") User user) {
            System.out.println("testModelAttribute。。。");
            System.out.println(user);
            return "success";
        }
    
      @ModelAttribute
        public void showUser(String uname, Map<String,User> map) {
            //模拟从数据库查询数据
            User user = new User();
            user.setUname(uname);
            user.setAge(19);
            user.setBirthday(new Date());
            map.put("user",user);
        }
    

@SessionAttribute

  • 作用

    • 用于多次执行控制器方法间的参数共享,例如可以将request域中数据共享到session域中。
  • 属性

    • values,用于指定存入的属性名称
    • types,用于指定存入的数据类型
  • 例一

    jsp代码:

       <a href="springmvc/testPut">testPut</a><br>
       <a href="springmvc/testGet">testPut</a><br>
       <a href="springmvc/testClean">testPut</a><br>
    

    跳转后(controller中的方法的返回值为String类型时,采用转发)的jsp页面,需要设置允许EL表达式。

    ${requestScope.uname}
    ${sessionScope}
    

    controller代码:

    • 使用@SessionAttributes注解后,可以在success.jsp页面中获取存入session域对象中的属性
    • Model接口的实现类的addAttribute()方法可以将属性键值对添加到request域对象,在跳转后的jsp页面通过${requestScope.uname}可以获取属性值
  • ModelMap类是Model接口的一个实现类,可以获取Session域里面的属性

    • SessionStatus类可以设置session域的状态
    @Controller
    @RequestMapping("/springmvc")
    @SessionAttributes(names = {"uname", "age"}, types = {String.class, Integer.class})
    //@SessionAttributes(value={"uname","age"}) //把数据存入session域对象中(作用和上面一样)
    public class SessionAttributeController {
    
        @RequestMapping("/testPut")
        public String testPut(Model model) {
            model.addAttribute("uname", "zhangsan");
            model.addAttribute("age", 18);
            return "success";
        }
    
        @RequestMapping("/testGet")
        public String testGet(ModelMap modelMap) {
            System.out.println("uname:" + modelMap.get("uname") + ",age:" + modelMap.get("age"));
            return "success";
        }
    
        @RequestMapping("/testClean")
        public String testClean(SessionStatus sessionStatus) {
            sessionStatus.setComplete();
            return "success";
        }
    }
    

响应数据和结果视图

返回值分类

返回值是字符串

jsp代码:

 <a href="user/testString">testString</a><br>

controller代码:

    @RequestMapping(path = "/testString")
    public String testString(){
        System.out.println("testString executed...");
        return "success";
    }

返回值是void

jsp代码:

<a href="user/testVoid">请求转发</a><br>
<a href="user/testVoid2">重定向</a><br>

controller代码:

    @RequestMapping(path = "/testVoid")
    public void testVoid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("testVoid executed...");
        //使用请求转发
        request.getRequestDispatcher("/index.jsp").forward(request,response);
    }

    @RequestMapping(path = "/testVoid2")
    public void testVoid2HttpServletRequest request, HttpServletResponse response
        System.out.println("testVoid2 executed...");
        //使用重定向
        response.sendRedirect(request.getContextPath()+"/index.jsp");
    }

	//直接向html页面输出
	@RequestMapping(path = "/testVoid2")
	public void testVoid3(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//设置中文乱码
         response.setCharacterEncoding("UTF-8");
         response.setContentType("text/html;charset=UTF-8");
		respose.getWriter().println("你好");
    }

返回值是ModelAndView

  • 作用

    • 可以用作controller中方法的返回值,通过ModelAndView提供的方法可以分别设置属性和视图。
  • 例一

    jsp代码:

    <a href="user/testModelAndView">testModelAndView</a><br>
    

    controller代码:

        @RequestMapping(path = "/testModelAndView")
        public ModelAndView testModelAndView(){
            System.out.println("testModelAndView executed...");
            ModelAndView mv = new ModelAndView();
            User user = new User();
            user.setUsername("lisisi");
            user.setAge(19);
            mv.addObject("user",user);
            mv.setViewName("success");
            return mv;
        }
    

转发和重定向

转发

  • controller 方法在提供了String 类型的返回值之后,默认就是请求转发。

  • 使用forward:这种写法,可以不用写项目名

例一

jsp代码:

<a href="user/testForward">testForward</a><br>

controller代码:

@RequestMapping("/testForward")
public String testForward() {
    System.out.println("testForward executed...");
    return "forward:/WEB-INF/pages/success.jsp";
}

重定向

例一

jsp代码:

<a href="user/testRedirect">testRedirect</a><br>

controller代码:

@RequestMapping("/testRedirect")
public String testRedirect() {
    System.out.println("testRedirect executed...");
    return "redirect:/WEB-INF/pages/success.jsp";
}

RequestBody响应json数据

案例02:SpringMVC案例02–RequestBody响应json数据

文件上传

原生servlet实现文件上传

文件上传前提要求

  • form表单的enctype值必须是multipart/form-data,默认是application/x-www-form-urlencoded
  • method属性取值必须是POST,get无法携带大量数据
  • 提供一个文件选择域标签 <input type="file" />

文件上传的原理分析

form表单的enctype值是multipart/form-data时,form表单将每个表单每个项分成文件项和普通项,通过分界符分成多部份,手动解析步骤繁琐,借助第三方组件实现文件上传会帮忙节省很多功夫。

第三方组件Commons-fileupload 是appache提供的一个文件上传的组件,需要手动导入依赖。

上传代码示例

案例03:SpringMVC案例03–传统文件上传方式

SpringMVC传统方式文件上传

传统方式的文件上传,指的是我们上传的文件和访问的应用存在于同一台服务器上,并且上传完成之后,浏览器可能跳转。

SpringMVC框架文件上传原理

在这里插入图片描述
案例04: SpringMVC案例04–利用SpringMVC框架提供的组件实现文件上传

SpringMVC跨服务器上传

服务器分类

  • 应用服务器:负责部署我们的应用
  • 数据库服务器:运行我们的数据库
  • 缓存和消息服务器:负责处理大并发访问的缓存和消息
  • 文件服务器:负责存储用户上传文件的服务器

分服务器的目的

让服务器各司其职,从而提高我们项目的运行效率
在这里插入图片描述

SpringMVC中的异常处理

SpringMVC异常处理原理(通过异常处理组件进行)

在这里插入图片描述

应用场景

对系统运行时出现的异常进行统一处理,将错误信息展示到特定的错误页面,如果没有这一步处理,应用只会将原生的错误上传,不方便查看和维护。

案例06: SpringMVC案例06–异常处理

SpringMVC中的拦截器

SpringMVC中的处理器拦截器和Servlet中的过滤器类似,主要对处理器进行预处理和后处理。

拦截器与过滤器区别

拦截器:它是SpringMVC框架的一部分。

过滤器:它是Servlet规范中的一部分,任何Java Web工程都可以使用。

拦截器:只能作用在访问控制器方法的请求,如果访问html,css,js等资源无法拦截。

过滤器:在url-pattern中配置了/*之后,可以拦截所有要访问的资源。

拦截器的应用场景

预处理:判断用户是否登录…

后处理:用户注销时,清除数据,清除cookie…

拦截器链

和过滤器类似,就是一组按顺序配置的拦截器。

案例07: SpringMVC案例07–自定义拦截器


PS1:POJO概念

POJO(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBeans,是为了避免和EJB混淆所创造的简称。

使用POJO名称是为了避免和EJB混淆起来, 而且简称比较直接. 其中有一些属性及其getter setter方法的类,没有业务逻辑,有时可以作为VO(value -object)或dto(Data Transform Object)来使用.当然,如果你有一个简单的运算属性也是可以的,但不允许有业务方法,也不能携带有connection之类的方法。


学习地址

SpringMVC教程IDEA版-3天-2018黑马SSM-03


  1. 占位符:请求 url 中 /delete/{id},这个{id}就是 url 占位符 ↩︎

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值