Java研学-SpringMVC(二)

七 简单类型请求参数 – 基本数据类型及其包装类

1 请求参数名与方法的形参同名

// 根据请求路径接受参数
// http://localhost:8080/base/add?name=lisi&age=66
@RequestMapping("add")
    public String add(String name,int age){
        System.out.println(name+"===="+age);
        return "forward";
}

2 请求参数名与方法的形参不同名

// http://localhost:8080/base/add1?name=lisi&age=66
// required = false 表示这个参数可以传也可以不传
// 此参数不传值时默认值为2,defaultValue = "2"
// 传递的话就用value的值(路径中传递的数据66)
@RequestMapping("add1")
public String add1(@RequestParam("name") String username,
                   @RequestParam(value = "age",defaultValue = "2",required = false) int userage){
        System.out.println(username+"===="+userage);
        return "forward";
}

3 乱码处理

① GET 方式传递中文参数乱码问题
  Tomcat7 及之前手动修改配置文件,使用代码手动转;但若使用 Maven 的话,可以 pom.xml 中的 Tomcat 插件配置一行也可以解决,Tomcat8 已处理这个问题,不需要额外配置。

<uriEncoding>UTF-8</uriEncoding>

② POST 方法传递中文乱问题
  web.xml 使用 Spring MVC 内置过滤器处理。需在前端控制器之前配置。(在请求进入前端控制器之前进行拦截)

<!-- 编码过滤器,仅针对 POST 方式 -->
<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>

八 复合类型请求参数 – 数组及自定义类型

1 数组类型

// 请求路径 /del?ids=1&ids=2&ids=3
@RequestMapping("del")
    public String del(int[] ids){
        System.out.println(Arrays.toString(ids));
        return "forward";
    }

2 自定义类型

  对于保存用户的需求,请求时携带用户名和密码参数,后端期望创建一个用户对象来封装这些参数值。
① 自定义类 – 用来封装参数值

public class User {
    private Long id;
    private  String username;
    private  String password;
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date birthday;
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", birthday=" + birthday +
                '}';
    }
}

② 编写处理方法

// 传递参数名与封装对象的属性名需一致
@RequestMapping("insert")
    public String insert( User user){
        System.out.println(user);
        return "forward";
    }

③ jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/base/add1" method="post">
    姓名:<input type="text" name="name">
    <input type="submit" value="提交">
</form>
<h3>增加用户</h3>
<form action="/base/insert" method="post">
   <p> 账号:<input type="text" name="username"></p>
   <p> 密码:<input type="text" name="password"></p>
   <p> 生日:<input type="text" name="birthday"></p>
   <p> <input type="submit" value="提交"></p>
</form>
</body>
</html>

  底层 Spring MVC 根据请求地址对应调用处理方法,调用方法时发现要传递 User 类型的实参,Spring MVC 会反射创建 User 对象,之后通过请求参数名找对应的属性,为对象的属性设置对应的参数值。

九 处理日期类型请求参数

1 处理日期格式参数 – 方式1

// 在处理方法的 Date 类型的形参贴上 @DateTimeFormat 进行接收
// 形参的类型为 java.util.Date(将字符串类型转时间类型)
// 请求路径 /date1&birth=2024-01-01
@RequestMapping("date1")
    public String date1(@DateTimeFormat(pattern = "yyyy-MM-dd") Date birth){
        System.out.println(birth);
        return "forward";
    }

2 处理封装参数类字段 – 方式2

① User实体类

// 在封装参数类的 Date 类型的字段上贴 @DateTimeFormat
public class User {
	// 省略其他字段
	// 增加下面这个字段,并贴注解
	@DateTimeFormat(pattern="yyyy-MM-dd")
	private Date date;
	// 省略 setter getter toString 
}

② 对应处理方法

// 直接用即可
@RequestMapping("insert")
    public String insert( User user){
        System.out.println(user);
        return "forward";
    }

十 ModelAttribute 注解

  可贴在方法和形参上,形参前提是自定义类型,会存到模型中,可在视图中获取到。项目中常用于查询条件回显用(分页查询,条件查询回显,类似于存到作用域中)

1 处理方法

@RequestMapping("get")
    public String get(@ModelAttribute("u") User u){
    // 表示将参数u传递到作用域中,跳转页面可以获取该参数
        System.out.println(u);
        return "forward";
    }

2 跳转后的JSP

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>请求接收完成页面</title>
</head>
<body>
<%--webapp/WEB-INF/views/目录下建立jsp--%>
<h3>请求处理完毕页面</h3>
<p>
    账号:${u.username}
    密码:${u.password}
</p>
</body>
</html>

3 存入数据的JSP

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h3>增加用户</h3>
<form action="/base/get" method="post">
   <p> 账号:<input type="text" name="username"></p>
   <p> 密码:<input type="text" name="password"></p>
   <p> 生日:<input type="text" name="birthday"></p>
   <p> <input type="submit" value="提交"></p>
</form>
</body>
</html>

十一 文件上传

1 上传页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<%--新建src/main/webapp/upload.jsp,请求数据类型必须是:multipart/form-data,且请求方式是 POST--%>
    <title>Title</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
  图片:<input type="file" name="pic">
    <input type="submit" value="上传">
</form>
</body>
</html>

2 创建对应的Controller

@Controller
public class UploadController {
    @Autowired
    ServletContext servletContext;
    /*文件上传*/
    @RequestMapping("upload")
    public String upload(Part pic){
 	   // 通过Part对象获取数据
        String name = pic.getName();
        String contentType = pic.getContentType();
        System.out.println(name);
        System.out.println(contentType);
        // 只看控制台输出即可
        return "";
    }
}

3 spring-mvc中配置文件上传解析器

<!--上传文件解析器 bean 名称固定,必须为 multipartResolver,前端控制器底层根据名字进行加载-->
<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver">
</bean>

4 设置文件上传大小 – web.xml

<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:mvc.xml</param-value>
	</init-param>
	<load-on-startup>1</load-on-startup>
	<multipart-config>
		<max-file-size>52428800</max-file-size>
		<max-request-size>52428800</max-request-size>
	</multipart-config>
</servlet>
<servlet-mapping>
	<servlet-name>dispatcherServlet</servlet-name>
	<url-pattern>/</url-pattern>
</servlet-mapping>

十二 拦截器

1 作用

  过滤器(过滤用户请求,进入前端控制器之前,拦截jsp,静态资源)在拦截器(处理器执行链,进入前端控制器之后,拦截访问后台的请求,不拦截jsp,静态资源)之前,拦截器是Spring MVC 提供的,配置在 Spring MVC 配置文件中,被 Spring 容器管理,主要用于对请求访问控制器的方法进行拦截,常用于登录与权限判断。

2 自定义拦截器

// 定义一个类实现 HandlerIntercepto 接口
public class MyIntercepter implements HandlerInterceptor {
	// 处理方法之前,第一个方法有返回值
    // 返回 false,就被拦截;返回 true 就放行
    /*请求进入Controller控制器之前执行拦截*/
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("请求进入了前端控制器但是没有进入后台controller");
        return true;
    }
    /*请求从Controller控制器出来,在渲染页面之前进行执行拦截*/
    /*此时视图解析器还没有对 ModelAndView 对象进行解析*/
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("从controller返回但是还没有页面解析ModelAndView");
    }
    /*完成响应并对 ModelAndView 对象解析完毕后*/
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("请求执行完毕。。。。");
    }
}

3 配置拦截器的拦截规则 – spring-mvc.xml

<!--拦截器拦截规则:可以配置多个拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--拦截的路径,/** 表示拦截所有路径以及子路径-->
            <mvc:mapping path="/**"/>
            <!--不需要拦截的路径,如登录页面等,可写多个-->
            <mvc:exclude-mapping path="/base/add"/>
            <mvc:exclude-mapping path="/base/get"/>
            <!--自定义拦截器对象-->
            <bean class="cn.tj.intercepter.MyIntercepter"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

十三 核心组件

1 前端控制器 DispatcherServlet

  框架提供,需要在 web.xml 中配置。作用:接受请求,处理响应结果,转发器,中央处理器。

2 处理器映射器 HandlerMapping

  框架提供。作用,更具请求的 URL 找到对应的 Handler。

3 处理器适配器 HandlerAdapter

  框架提供。作用:调用处理器(Handler/Controller)的方法。

4 处理器 Handler(Controller)

  必须按照 HandlerAdapter 的规范去开发。作用:接收用户请求数据,调用业务方法处理请求。

5 视图解析器 ViewResolver

  框架或者第三方提供。作用:视图解析,把逻辑视图名称解析成真正的物理视图。支持多种视图技术 Velocity、FreeMarker、JSP 等。

6 视图

  作用:把数据展现给用户。

7 开发步骤

1.web.xml 配置前端控制器
2.mvc.xml 配置处理器映射器、处理适配器、视图解析器(默认可省略配置)
3.结合需求开发
4.先开发 Contoller,进行配置
5.开发 JSP

十四 SpringMVC执行流程分析

1 发送请求

  当用户发送一个 HTTP 请求(如 GET、POST 等)到服务器时,Servlet 容器(如 Tomcat)会捕获到这个请求。如果你的应用程序配置了 Spring MVC 的前端控制器(通常是 DispatcherServlet),Servlet 容器会将请求转发给这个前端控制器(位于web.xml文件中)。

2 请求分发

  DispatcherServlet 接收请求后,会根据请求的 URL 查找对应的 HandlerMapping(处理器映射器 主要作用为去后台验证有无访问路径,有的话进入处理器执行链(拦截器)。进行处理,之后再返回给前端控制器,它不会调用方法)。

3 控制器处理

  再返回DispatcherServlet (前端控制器),前端控制器将请求发往HandlerAdapter(处理器适配器,主要进行后台方法的调用,crud,执行Handler处理器的方法,也就是Controller,当 Controller 被选中后,它会处理请求,并可能调用 Service 层进行业务处理,再进一步可能调用 DAO 层与数据库交互。),通过springMVC的一个内置对象ModelAndView 将调用结果返回给HandlerAdapter,该对象包含了模型数据和视图名称。HandlerAdapter处理器适配器再将ModelAndView 对象返回给前端控制器

4 视图解析

   DispatcherServlet 拿到 ModelAndView 对象后,会将其传递给 ViewResolver(视图解析器)。ViewResolver 会根据 ModelAndView 中的视图名称解析出具体的 View(视图)对象与View对象,将model对象渲染到view对象上,也就是将数据渲染到jsp页面上,最终展示给客户端。视图对象通常是 JSP、Thymeleaf、FreeMarker 等模板引擎的实例。

5 视图渲染

  视图对象使用 ModelAndView 中的模型数据来渲染视图。
  渲染过程可能涉及到模板引擎将数据和模板合并成 HTML 页面。

6 响应输出

  渲染完成后,视图对象将结果(通常是 HTML 页面)作为 HTTP 响应返回给客户端。
  DispatcherServlet 将这个响应发送回 Servlet 容器,并最终由容器发送给客户端浏览器。

7 拦截器与过滤器

  在整个流程中,可能还涉及到拦截器(Interceptor)和过滤器(Filter)的处理。
  拦截器可以在请求处理之前或之后执行一些操作,如权限检查、日志记录等。
  过滤器在请求到达 DispatcherServlet 之前或响应离开 DispatcherServlet 之后执行,常用于执行一些通用的任务,如字符集设置、请求和响应的预处理等。
SpringMVC执行流程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泰勒疯狂展开

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值