开发框架-SpringMVC

SpringMVC

什么是SpringMVC?

Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。

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

为什么要学SpringMVC?

  • 轻量级,简单易学。
  • 高效,基于请求响应的MVC框架。
  • 与Spring兼容性好,无缝结合。
  • 约定优于配置。
  • 功能强大:RESTful、数据验证、格式化、本地化、主题等。
  • 简洁灵活。

Spring的web框架围绕着DispatcherServlet设计,它的作用是将请求分发到不同的处理器,从Sprinng2.5开始,使用Java5以上用户都可以基于注解的controller声明方式。

SpringMVC框架像许多其他MVC框架一样,以请求为驱动,围绕着一个Servlet来分派请求以及提供其他功能,DispatcherServlet是一个实际上的Servlet类(它继承自HttpServlet基类)。

SpringMVC的原理:

当发起请求时,被前置的控制器拦截到请求,根据请求参数的生成代理,找到请求对应的实际控制器,控制器处理请求,创建数据模型,访问数据库,将模型响应给中心控制器,控制器使用模型和视图来渲染视图结果,并将结果返回给中心控制器,再将结果返回给请求者。

image-20220308133852231

1 回顾MVC框架

经典MVC模式中,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。其中,View的定义比较清晰,就是用户界面。

  • MVC是一种软件设计规范。
  • 是将业务逻辑、数据、显示分离的方法来组织代码。
  • 主要作用是降低了视图和业务逻辑之间的双向耦合。
  • MVC不是一种设计模式,而是一种架构模式,不同的MVC会存在一定差异!

V即View视图是指用户看到并与之交互的界面(JSP)。比如由html元素组成的网页界面,或者软件的客户端界面。MVC的好处之一在于它能为应用程序处理很多不同的视图。在视图中其实没有真正的处理发生,它只是作为一种输出数据并允许用户操作的方式。

M即model模型是指模型表示业务规则(dao、service)。在MVC的三个部件中,模型拥有最多的处理任务。被模型返回的数据是中立的,模型与数据格式无关,这样一个模型能为多个视图提供数据,由于应用于模型的代码只需写一次就可以被多个视图重用,所以减少了代码的重复性。

C即controller控制器是指控制器接受用户的输入并调用模型和视图去完成用户的需求,控制器本身不输出任何东西和做任何处理(Servlet)。它只是接收请求并决定调用哪个模型构件去处理请求,然后再确定用哪个视图来显示返回的数据。

最经典的MVC就是JSP+Servlet+JavaBean的模式:

image-20220307212726760

MVC需要做的事:

  • 将url映射到Java类或者Java类的方法!
  • 封装用户提交的数据!
  • 执行步骤一般为:处理请求->调用相关的业务处理->封装响应数据
  • 将响应的数据进行渲染 .jsp/html等表示层数据!

现在常见的服务器端MVC框架有:Struts、SpringMVC、ASP.NET MVC等。

常见前端MVC框架有:vue、angularjs、react、backbone等。

2 回顾Servlet

Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。

在新项目开始之前,同样需要在父类pom.xml导入Servelet所需的公共包:

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.16</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
        <scope>provided</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>javax.servlet.jsp-api</artifactId>
        <version>2.3.3</version>
        <scope>provided</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl -->
    <dependency>
        <groupId>javax.servlet.jsp.jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>

</dependencies>

在导入好项目所需要的包之后,新建一个纯净的maven项目,并在父maven项目下创建子项目(module)。

创建完成之后,可以对着该子项目右键,弹出的可选项菜单中,会有一个添加架构支持的选项,点击选取之后,会自动帮该项目创建一个web文件夹,也就是创建了一个web项目!

image-20220307215254275

image-20220307215327385

Servlet测试:

以下实例的运行环境为:

  • Tomcat9.0.54
  • Tomcat路径:/springmvc

1、创建一个Servlet类:

public class HelloServlet extends HttpServlet {
   
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   
        // 1、获取前端参数
        String method = req.getParameter("method");
        switch (method){
   
            case "add":
                req.getSession().setAttribute("msg", "执行了add方法");
                break;
            case "delete":
                req.getSession().setAttribute("msg", "执行了delete方法");
                break;
        }

        // 2、调用业务层

        // 3、视图转发或者重定向
        req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   
        super.doGet(req, resp);
    }
}

2、在web.xml中注册Servlet类:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>helloServlet</servlet-name>
        <servlet-class>com.atayin.web.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>helloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
<!--    配置超时时间-->
<!--    <session-config>-->
<!--        <session-timeout>15</session-timeout>-->
<!--    </session-config>-->
    
<!--        配置欢迎页面-->
<!--    <welcome-file-list>-->
<!--        <welcome-file>/index.jsp</welcome-file>-->
<!--    </welcome-file-list>-->
</web-app>

3、配置响应页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>回顾servlet</title>
</head>
<body>
    ${msg}
</body>
</html>

以上实例的具体实现流程为:

  • 启用Tomcat服务器,在链接栏中输入http://localhost:8080/springmvc/hello?method=add
  • 当链接识别为hello时,req响应会拿到请求并进入Servlet类中对链接中的参数(method=add)进行判断,并将判断结果放入到jsp的request域中!并转发页面至test.jsp!
  • test.jsp页面会拿到request域中存放的数据,并展示在页面中!

注意:

  • Servlet程序中进行转发、重定向时,程序默认的根目录为项目中的/web!
  • 在后续实例中,页面中的form标签,具有一个action属性,这个属性的值一般填跳转路径,路径一般为Tomcat服务器设置中配置的路径!
  • Tomcat10会报Servlet程序无法正常实例化的错误!问题可能是由导包错误造成的!

3 HelloSpringMVC

1、新建一个Web项目,在web.xml配置文件中,注册DispatcherServlet

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
<!--    注册DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--    关联一个springmvc配置文件-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
<!--        启动级别: 1-->
        <load-on-startup>1</load-on-startup>
    </servlet>
<!--    /   匹配不包括.jsp的所有的请求
        /*  匹配包括.jsp的所有的请求-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

2、编写对应的springmvc-servlet.xml配置文件(这里的文件命名是按照官方规范来的,也就是[servletName-servlet.xml]):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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">

</beans>

3、添加处理映射器:

<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

4、添加处理适配器:

<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

5、添加视图解析器:

<!--    视图解析器:DispatcherServlet给予的Model和View-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
    <!--前缀-->
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <!--后缀-->
    <property name="suffix" value=".jsp"/>
</bean>

6、编写操作业务controller类(实现Controller接口),该类需要返回一个ModelAndView对象(也就是模型和视图):

public class HelloController implements Controller {
   
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
   
//        模型和视图
        ModelAndView mv = new ModelAndView();
//        封装对象,放入模型和视图中
        mv.addObject("msg","HelloSpringMVC");
//        封装要跳转的视图,并放入模型和视图中
        mv.setViewName("hello"); // /WEB-INF/jsp/hello.jsp
        return mv;
    }
}

7、将controller类交给SpringIOC注册为bean:

<!--Handler-->
<bean id="/hello" class="com.atayin.controller.HelloController"/>

8、编写跳转页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${msg}
</body>
</html>

可能会遇到的问题:

  • 404问题

    • 缺少jar包。

    • 如果jar包存在但无法显示输出,需要在IDEA的项目发布中,添加lib依赖。

    • 重启Tomcat。

  • 5xx问题

    • 将Tomcat中的Deployment中的server startup界面中,仅保留当前子模块的artifact。

    • 将Tomcat版本降为9。

4 SpringMVC执行原理

img

图为SpringMVC的一个较完整的流程图,实线表示SpringMVC框架提供的技术,不需要开发者实现,虚线表示需要开发者实现。

简要分析执行流程

1、DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。

假设请求的url为 : http://localhost:8080/SpringMVC/hello,如上url拆分成三部分:

  • http://localhost:8080服务器域名

  • SpringMVC部署在服务器上的web站点

  • hello表示控制器

通过分析,如上url表示为:请求位于服务器localhost:8080上的SpringMVC站点的hello控制器。

2、HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。

3、HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器,如上url被查找控制器为:hello。

4、HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。

5、HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。

6、Handler让具体的Controller执行。

7、Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。

8、HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。

9、DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。

10、视图解析器将解析的逻辑视图名传给DispatcherServlet。

11、DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图。

12、最终视图呈现给用户。

注意:配置文件中配置的映射器和适配器在创建了继承Controller接口的控制器类后,是可以忽略的(某些情况下会进行报错),这里的代码实例配置它们是为了便于理解底层原理!

5 使用注解开发SpringMVC

1、新建一个子模块,并检查该模块下所需的jar包是否已导入齐全!

2、老生常谈的问题: 由于Maven是约定大于配置的,也就是说,在测试过程中有可能会遇到配置文件无法正确导出的问题,并在控制台报”无法找到配置文件“的错误,解决方案便是在pom.xml配置文件中加入build标签。

<!--在build中配置resource,来防止我们资源导出失败的问题-->
<build>
  <resources>
    <resource>
      <directory>src/main/resource</directory>
      <includes>
        <include>**/*.properties</include>
        <include>**/*.xml</include>
      </includes>
    </resource>
    <resource>
      <directory>src/main/java</directory>
      <includes>
        <include>**/*.properties</include>
        <include>**/*.xml</include>
      </includes>
      <filtering>true</filtering>
    </resource>
  </resources>
</build>

3、配置web.xml

  • 注册DispatcherServlet。
  • 关联Spring配置文件。
  • 启动级别设置为1。
  • 映射路径为 / 。
<!--    注册DispatcherServlet-->
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--    关联一个springmvc配置文件-->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc-servlet.xml</param-value>
    </init-param>
    <!--        启动级别: 1-->
    <load-on-startup>1</load-on-startup>
</servlet>
<!--    /   匹配不包括.jsp的所有的请求
        /*  匹配包括.jsp的所有的请求-->
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

这一步的代码几乎可以说是写死的,建议放在一个记事本中存放,后续学习需要用到的时候可以直接进行一个复制粘贴的操作!

4、添加SpringMVC的配置文件

  • 导入所需依赖。

  • 扫描指定包下的注解,使得包下的注解生效,并交由IOC进行管理。

  • 静态资源过滤,MVC的注解驱动。

  • 配置视图解析器。

<?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
        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/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd
        ">
        <!--自动扫描包,让指定包下的注解生效,交由IOC容器统一管理-->
        <context:component-scan base-package="com.atayin.controller"/>
        <!--对文件进行过滤:让SpringMVC不处理静态资源(.css .js .html .mp3等)-->
        <mvc:default-servlet-handler/>
        <!--支持mvc注解驱动
                    在spring中一般采用@RequestMapping注解来完成映射关系
                    要想使得该注解生效,必须向上下文注册
                    BeanNameUrlHandlerMapping和SimpleControllerHandlerAdapter
                    这两个实例,也就是处理映射器和处理适配器,这两个类分别在类级别和方法级别处理
                    而annotation-driven配置帮助我们自动完成上述两个实例的注入-->
        <mvc:annotation-driven/>
        <!--视图解析器-->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <!--前缀-->
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <!--后缀-->
            <property name="suffix" value=".jsp"/>
        </bean>
</beans>

5、创建Controller

编写一个Java控制类:

@Controller
public class HelloController {
   
    @RequestMapping("/hello")
    public String hello(Model model) {
   
        // 封装数据
        model.addAttribute("msg", "使用注解方式开发SpringMVC");
        return "hello"; // 返回值将会被视图解析器处理,也就是会被拿去进行链接的拼接
    }
}
  • @Controller是为了让SpringIOC容器初始化时自动扫描到。
  • @RequestMapping是为了映射请求路径,当类与方法上都有映射时,访问的路径应该是先类后方法。
  • 方法中声明的Model类型的参数是为了把数据带回到视图中。
  • 方法返回的结果是视图的名称hello,加上配置文件中的视图解析器的前后缀便会拼接成一个完整的链接。
  • 返回的字符串尽量与@RequestMapping("/hello")所映射的请求路径一致!

注意:

无论使用的是继承Controller接口还是注解@Controller来编写Controller控制器,甚至使用两种方法分别编写一个控制类(封装在模型中的数据不一致),都会发现,请求会指向同一个视图,但是页面的结果是不一样的,从这里可以看出视图是被复用的,而控制器与视图之间是弱耦合关系。

6、创建视图层

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${msg}
</body>
</html>

7、启动Tomcat并测试

配置完成Tomcat之后,启动,并在链接栏中输入以下链接:http://localhost:8080/hello,当正常返回一个显示“使用注解方式开发SpringMVC”字段的页面而且还没有出现任何错误时,测试成功!

小结:

  • Spring必须配置的三大件:处理映射器、处理适配器、视图解析器。
  • 通常来说,程序员只需手动配置视图解析器,而处理映射器和处理适配器只需要开启注解驱动即可,可以省去大段的xml配置!

RestFul 风格

概念

Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

功能

资源:互联网所有的事物都可以被抽象为资源

资源操作:使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作。

分别对应 添加、 删除、修改、查询。

传统方式操作资源 :通过不同的参数来实现不同的效果!方法单一,post 和 get

​ http://127.0.0.1/item/queryItem.action?id=1 查询,GET

​ http://127.0.0.1/item/saveItem.action 新增,POST

​ http://127.0.0.1/item/updateItem.action 更新,POST

​ http://127.0.0.1/item/deleteItem.action?id=1 删除,GET或POST

使用RESTful操作资源 :可以通过不同的请求方式来实现不同的效果!如下:请求地址一样,但是功能可以不同!

​ http://127.0.0.1/item/1 查询,GET

​ http://127.0.0.1/item 新增,POST

​ http://127.0.0.1/item 更新,PUT

​ http://127.0.0.1/item/1 删除,DELETE

1、在新建一个类 RestFulController

@Controller
public class RestFulController {
   
}

2、在Spring MVC中可以使用 @PathVariable 注解,让方法参数的值对应绑定到一个URI模板变量上。

@Controller
public class RestFulController {
   

   //映射访问路径
   @RequestMapping("/commit/{p1}/{p2}")
   public String index(@PathVariable int p1, @PathVariable int p2, Model model){
   
       
       int result = p1+p2;
       //Spring MVC会自动实例化一个Model对象用于向视图中传值
       model.addAttribute("msg", "结果:"+result);
       //返回视图位置
       return "test";
       
  }
   
}

3、测试结果:losthost:8080/commit/1/2,返回结果为3

思考:使用路径变量的好处?

  • 使路径变得更加简洁;

  • 获得参数更加方便,框架会自动进行类型转换。

  • 通过路径变量的类型可以约束访问参数,如果类型不一样,则访问不到对应的请求方法,如这里访问是的路径是/commit/1/a,则路径与方法不匹配,而不会是参数转换失败。

image-20220311210814149

修改下对应的参数类型,再次测试:

//映射访问路径
@RequestMapping("/commit/{p1}/{p2}")
public String index(@PathVariable int p1, @PathVariable String p2, Model model){
   

   String result = p1+p2;
   //Spring MVC会自动实例化一个Model对象用于向视图中传值
   model.addAttribute("msg", "结果:"+result);
   //返回视图位置
   return "test";

}

image-20220311210847469

使用method属性指定请求类型

用于约束请求的类型,可以收窄请求范围。指定请求谓词的类型如GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE等

来测试一下:

  • 增加一个方法

    //映射访问路径,必须是POST请求
    @RequestMapping(value = "/hello",method = {
         RequestMethod.POST})
    public String index2(Model model){
         
       model.addAttribute("msg", "hello!");
       return "test";
    }
    
  • 使用浏览器地址栏进行访问默认是Get请求,会报错405:

  • 如果将POST修改为GET则正常了;

    //映射访问路径,必须是Get请求
    @RequestMapping(value = "/hello",method = {
         RequestMethod.GET})
    public String index2(Model model){
         
       model.addAttribute("msg", "hello!");
       return "test";
    }
    

小结:

Spring MVC 的 @RequestMapping 注解能够处理 HTTP 请求的方法, 比如 GET, PUT, POST, DELETE 以及 PATCH。

所有的地址栏请求默认都会是 HTTP GET 类型的。

方法级别的注解变体有如下几个:组合注解

@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping

@GetMapping 是一个组合注解,平时使用的会比较多!

它所扮演的是 @RequestMapping(method =RequestMethod.GET) 的一个快捷方式。

转发与重定向

转发: 简单而言就是客户端A想要访问web资源C,于是先访问了web资源B,然后B再访问C,C接受到请求后,将资源通过B返回给A!

重定向: 意思就是A(客户端)向B(web资源)发送请求,B收到请求后,让A(客户端)去访问C(另一个web资源),这就好比你将一个物品给予一个人,而这个人把物品还给你并让你去将物品给予另一个人。

转发和重定向的区别

相同点:

  • 页面都会实现跳转

不同点:

  • 请求转发的时候,页面进行了跳转,但是页面的路径(url)并不会被改变
  • 重定向后,页面进行了跳转,页面的路径(url)也随之改变
  • 请求转发的状态码是307,而重定向的状态码是302

通过SpringMVC来实现转发和重定向 - 无需视图解析器;

注意:测试前,需要将视图解析器注释掉!

@Controller
public class ResultSpringMVC {
   
   @RequestMapping("/rsm/t1")
   public String test1(){
   
       //转发
       return "/index.jsp";
  }

   @RequestMapping("/rsm/t2")
   public String test2(){
   
       //转发二
       return "forward:/index.jsp";
  }

   @RequestMapping("/rsm/t3")
   public String test3(){
   
       //重定向
       return "redirect:/index.jsp";
  }
}

通过SpringMVC来实现转发和重定向 - 有视图解析器;

重定向 , 不需要视图解析器 , 本质就是重新请求一个新地方 , 所以注意路径问题,可以重定向到另外一个请求实现。

@Controller
public class ResultSpringMVC2 {
   
   @RequestMapping("/rsm2/t1")
   public String test1(){
   
       //转发
       return "test";
  }

   @RequestMapping("/rsm2/t2")
   public String test2(){
   
       //重定向
       return "redirect:/index.jsp";
       //return "redirect:hello.do"; //hello.do为另一个请求/
  }

}

数据处理

1 处理提交数据

1、提交的域名称和处理方法的参数名一致

提交数据 : http://localhost:8080/hello?name=kuangshen

处理方法 :

@RequestMapping("/hello")
public String hello(String name){
   System.out.println(name);
   return "hello";
}

后台输出 : kuangshen

2、提交的域名称和处理方法的参数名不一致

提交数据 : http://localhost:8080/hello?username=kuangshen

处理方法 :

//@RequestParam("username") : username提交的域的名称 .
@RequestMapping("/hello")
public String hello(@RequestParam("username") String name){
   
   System.out.println(name);
   return "hello";
}

后台输出 : kuangshen

3、提交的是一个对象

要求提交的表单域和对象的属性名一致 , 参数使用对象即可

1、实体类

public class User {
   
   private int id;
   private String name;
   private int age;
   //构造
   //get/set
   //tostring()
}

2、提交数据 : http://localhost:8080/mvc04/user?name=kuangshen&id=1&age=15

3、处理方法 :

@RequestMapping("/user")
public String user(User user){
   
   System.out.println(user);
   return "hello";
}

后台输出 : User { id=1, name=‘kuangshen’, age=15 }

说明:如果使用对象的话,前端传递的参数名和对象名必须一致,否则就是null。

2 数据显示到前端

第一种 : 通过ModelAndView

前面一直都是如此 . 就不过多解释。

public class ControllerTest1 implements Controller {
   

   public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
   
       //返回一个模型视图对象
       ModelAndView mv = new ModelAndView();
       mv.addObject("msg","ControllerTest1");
       mv.setViewName("test");
       return mv;
  }
}

第二种 : 通过ModelMap

@RequestMapping("/hello")
public String hello(@RequestParam("username") String name, ModelMap model){
   
   //封装要显示到视图中的数据
   //相当于req.setAttribute("name",name);
   model.addAttribute("name",name);
   System.out.println(name);
   return "hello";
}

第三种 : 通过Model

@RequestMapping("/ct2/hello")
public String hello(@RequestParam("username") String name, Model model){
   
   //封装要显示到视图中的数据
   //相当于req.setAttribute("name",name);
   model.addAttribute("msg",name);
   System.out.println(name);
   return "test";
}

对比

就对于新手而言简单来说使用区别就是:

  • Model 只有寥寥几个方法只适合用于储存数据,简化了新手对于Model对象的操作和理解;

  • ModelMap 继承了 LinkedMap ,除了实现了自身的一些方法,同样的继承 LinkedMap 的方法和特性;

  • ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。

当然更多的以后开发考虑的更多的是性能和优化,就不能单单仅限于此的了解。

请使用80%的时间打好扎实的基础,剩下18%的时间研究框架,2%的时间去学点英文,框架的官方文档永远是最好的教程。

3 乱码问题

测试步骤:

1、在首页编写一个提交的表单

<form action="/e/t" method="post">
 <input type="text" name="name">
 <input type="submit">
</form>

2、后台编写对应的处理类

@Controller
public class Encoding {
   
   @RequestMapping("/e/t")
   public String test(Model model,String name){
   
       model.addAttribute("msg",name); //获取表单提交的值
       return "test"; //跳转到test页面显示输入的值
  }
}

3、输入中文测试,发现乱码

image-20220311221722661

不得不说,乱码问题是在开发中十分常见的问题,也是让我们程序猿比较头大的问题!

以前乱码问题通过过滤器解决 , 而SpringMVC提供了一个过滤器 , 可以在web.xml中配置。

注意:修改了xml文件需要重启服务器!

<!--SpringMVC提供的乱码过滤器-->
<filter>
   <filter-name>encoding</
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值