Spring MVC 学习记录

3 篇文章 0 订阅

Spring MVC

image-20220728104757459

  • 官网文档 https://docs.spring.io/spring-framework/docs/4.2.4.RELEASE/spring-framework-reference/html/mvc.html

回顾Servlt

  • 新建Maven工程,导入pom依赖

     <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.12</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>5.1.9.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>servlet-api</artifactId>
          <version>2.5</version>
        </dependency>
        <dependency>
          <groupId>javax.servlet.jsp</groupId>
          <artifactId>jsp-api</artifactId>
          <version>2.2</version>
        </dependency>
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>jstl</artifactId>
          <version>1.2</version>
        </dependency>
    
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>servlet-api</artifactId>
          <version>2.5</version>
        </dependency>
        <dependency>
          <groupId>javax.servlet.jsp</groupId>
          <artifactId>jsp-api</artifactId>
          <version>2.2</version>
        </dependency>
      </dependencies>
    
  • Servlet层

    public class HelloServlet extends HttpServlet {
        //实现Servlet接口
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //获取参数,获取页面网站返回得method变量中的参数
            String method=req.getParameter("method");
            if(method.equals("add")){
                //将参数变量msg返回
                req.getSession().setAttribute("msg","执行了add方法");
            }
            if(method.equals("del")){
                req.getSession().setAttribute("msg","执行了del方法");
            }
            //业务逻辑
            //视图跳转
            req.getRequestDispatcher("WEB-INF/jsp/hello.jsp").forward(req,resp);
        }
    
        @Override
        protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            super.doPut(req, resp);
        }
    
    }
    
  • web.xml配置

    <?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>
         <!-- 注册HelloServlet --> 
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.peggy.servlet.HelloServlet</servlet-class>
      </servlet>
      <servlet-mapping>
          <!--请求响应的user-->
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/user</url-pattern>
      </servlet-mapping>
    </web-app>
    
  • 静态资源

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
        ${msg}
    </body>
    </html>
    
    • localhost:8080/user?method=add
    • localhost:8080/user?method=delete

Spring MVC

配置版

  • web.xml

    <?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>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--关联一个Spring的配置文件:【servlet-name】-servlet.xml-->
        <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>
    
    
  • SpringMVC 的 配置文件 springmvc-servlet 官方名

<?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 https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
    <context:component-scan base-package="com.peggy.controller"/>
    <!--让Spring MVC不处理静态资源-->
    <mvc:default-servlet-handler/>
    <!--
        支持mvc注解驱动
        在spring中一般采用@RequestMapping注解来完成映射关系
        要想使@RequestMapping注解生效
        必须向上下文中注册DefaultAnnotationHandlerMapping
        和一个AnnotationMethodHandlerAdapter实例
        这两个实例分别在类级别和方法级别处理。
        而annotation-driven配置帮助我们自动完成上述两个实例的注入。
    -->
    <mvc:annotation-driven/>
    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--前缀-->
        <property name="prefix" value="WEB-INF/jsp/"/>
        <!--后端-->
        <property name="suffix" value=".jsp"/>
    </bean>

    <bean name="/t1" class="com.peggy.controller.ControllerTest"/>

</beans>
  • 操作业务Controller
  • @Controller注解类型用于声明Spring类的实例是一个控制器(在讲IOC时还提到了另外3个注
    解);
public class ControllerTest implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //返回一个视图对象 ModelAndView模型和视图
        ModelAndView modelAndView = new ModelAndView();
        //封装对象,放在ModelAndView中
        modelAndView.addObject("msg","<h1>ControllerTest<h1>");
        //封装要跳转的视图,放在ModelAndView中
        modelAndView.setViewName("hello"); // 跳转访问的地址:WEB-INF/jsp/hello.jsp
        return modelAndView;
    }
}
  • 将自己的类交给SpringIOC容器,注册bean
<!--将自己的类交给SpringIOC容器,注册Bean-->
<bean name="/t1" class="com.peggy.controller.ControllerTest"/>
  • 跳转的jsp hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    ${msg}
</body>
</html>
  • http://localhost:8080/hello

注解版

  • 编写一个HelloController类

    @Controller
    public class HelloController {
        //真实访问的地址: 项目名/HelloController/Hello
        @RequestMapping("/hello")
        public String sqyHello(Model model){
            model.addAttribute("msg","<h1>hello,SpringMVC<h1>");
            return "hello";
        }
    
        //真实访问的地址: 项目名/HelloController/Hello
        @RequestMapping("/hello1")
        public String sqyHello1(Model model){
            model.addAttribute("msg","<h1>Hello,SpringMVC<h1>");
            return "hello1";
        }
    }
    
    
  • 测试访问:https://localhost/hello / https://localhost/hello1

使用RestFul风格

public class RestFulController {
    @RequestMapping("/commit/{p1}/{p2}")
    //@PathVariable (value=)这里如果不写value默认就是变量的属性名
    public String index(@PathVariable int p1, @PathVariable int p2, Model model){
        int result=p1+p2;
        //SpringMVC会自动实例化一个Model对象用于向视图中传值
        model.addAttribute("msg","返回结果:"+result);
        //返回视图位置
        return "hello";
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9oFdCGBG-1658976511447)(http://peggy-m.oss-cn-hangzhou.aliyuncs.com/img/image-20220727161924316.png)]

  • 关于RestFul,如果在请求时属于与响应对象的属性不一致就会出现400错误

image-20220727162113363

使用method属性指定请求类型

指定请求谓词的类型如GET, POST, HEAD, OPTIONS, PUT,PATCH, DELETE, TRACE等

//请求方式为POST
@RequestMapping(value = "/hello2",method = {RequestMethod.POST})
public String sqyHello2(Model model){
    model.addAttribute("msg","<h1>Hello,SpringMVC<h1>");
    return "hello";
}

image-20220727163913724

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

ServletAP

设置ServletAPl,不需要视图解析器

  1. 通过HttpServletResponse进行输出
  2. 通过HttpServletResponse实现重定向
  3. 通过HttpServletResponse实现转发
@Controller
public class ResultGo {
    @RequestMapping("/request/t1")
    public void test1(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
        rsp.getWriter().println("Hello,Spring By Servlet API");
    }
    @RequestMapping("/request/t2")
    public void test2(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
        rsp.sendRedirect("/index.jsp");
    }
    @RequestMapping("/result/t3")
    public void test3(HttpServletRequest req, HttpServletResponse rsp) throws Exception {
        //转发
        req.setAttribute("msg","/result/t3");
        req.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(req,rsp);
    }

}

通过设置ServletAPl不用通过视图解析器直接就可以实现转发

image-20220727170632600

Spring MVC

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

  • 重定向,不需要视图解析器,本质就是一个重新请求一个新的地方,所以这里需要对路径注意,可以重定向到另一个请求实现。
@Controller
public class ResultSpringMVC2 {
    @RequestMapping("/rsm2/t1")
    public String test1(){
        //转发
        //转发请求的时候需要开启我们的视图解析器
        return "hello";
    }
    //重定向请求时的url的地址会发生改变
    @RequestMapping("/rsm2/t2")
    public String test2(){
        //重定向
        return "redirect:/index.jsp";
        //return "redirect:hello.do"; //hello.do为另一个请求
    }
}

处理提交数据

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

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

处理数据的方法:

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

前台:无数据输出

后台:获取url请求携带的参数

image-20220727194306766

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

提交数据:

处理数据的方法:

@RequestMapping("/hellos")
//@RequestParam() 注解可以为提交接收对象匿名为url中提交的参数名称
public String hello(@RequestParam("username")String name){
    System.out.println(name);
    return "hello";
}

image-20220727194816461

如果使用了RequestParam()注解,那么请求的URL地址中的参数必须使用匿名后的参数名

image-20220727194944834

image-20220727194957110

  1. 提交的是一个对象
  • 实体类
public class Student {
    private String name ;
    private Integer age;
    private String site;
       有参|无参构造方法
    	set|get
       toString方法        
}
  • 提交数据

    ​ http://localhost:8080/user?name=kakarote&age=10&site=globe

  • 处理方法

    @Controller
    public class ObjectResultControllerTest {
        @RequestMapping("/user")
        public String student(Student stu){
            System.out.println(stu);
            return "hello";
        }
    }
    
  • 前台后台结果

image-20220727201305256

image-20220727201328579

如果传递的是对象,前台的传递的参数名必须与对象名一致,否则接收到的就时Null

数据显示到前端

第一种 ModelAndView

  • 实现Controller重写handleRequest方法实现
  • 所以对于注解Controller相当于该类实现了该接口
public class ControllerTest implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //返回一个视图对象
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("msg","<h1>ControllerTest<h1>");
        modelAndView.setViewName("hello");
        return modelAndView;
    }
}

第二种 ModeMap

@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 只适用存储数据,所提供的方法比较少

ModelMap 继承了LinkedMap,除了实现了自身的一些方法以为,同样的继承了LinkedMap的方法与特性

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

中文乱码的一般处理方式

跳转页面代码

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

控制跳转层代码

@Controller
public class Encoding {
    @RequestMapping("/e/t")
    public String test(Model model, String name){
        model.addAttribute("msg","<h1>"+name+"<h1>");
        return "test";
    }
}

输出结果

image-20220728102911297

对于中文乱码,在以前都是通过过滤器进行处理,但SpringMVC给我们提供一个过滤器,可以在web.xml中进行配置

<filter>
  <filter-name>encoding</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>encoding</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

这样基本可以解决大多数的请求中文乱码问题

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值