欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring MVC

程序员文章站 2022-06-13 20:47:03
...

Spring MVC

前期的设计模式

1.模式一(Model One)

JSP:JSP的出现既解决了Servlet不适合向外输出网页的问题,也解决了HTML无法展示动态数据的问题!

​ 只有JSP开发项目

	1. 需要接收请求中的数据
	2. 需要对请求进行处理
	3. 需要处理业务逻辑
	4. 需要访问数据库
	5. 将请求处理的结果展示给用户

要在JSP中完成上面的工作,这就意味着要在JSP中写大量的Java代码,容易造成JSP页面结构的混乱,不利于后期的扩展和维护.

2.模式二(Model Two)

Servlet+JavaBean+JSP:

Bean:在计算机英语中,表示可重用的组件

JavaBean:广义:使用Java语言编写的可重用的组件

​ 狭义:实体类,用于封装数据的Java类

​ 业务Bean,专门用于处理业务逻辑的Java类

Servlet:
  1. 获取请求中的数据

  2. 调用某一个JavaBean对请求进行处理

  3. 调用某一个JSP展示请求处理的结果

JavaBean:
  1. 处理请求

  2. 处理业务逻辑

  3. 访问数据

  4. 封装数据库

JSP:

1.将请求处理的结果展示给用户

MVC设计模式

MVC设计模式是一种通用的软件编程思想

在MVC设计模式中认为,任何软件都可以分为三部分组成:

1.控制程序流转的控制器(Controller)

2.封装数据处理的模型(Model)

3.负责展示数据的视图(View)

并且在MVC设计思想中要求一个符合MVC设计思想的软件应该保证上面三部分相互独立,互不干扰,每一个部分只负责自己擅长的部分.

如果某一个模块发生变化,应该尽量做到不影响其他两个模块.这样做的好处是,软件的结构会变的更加的清晰,可读性强.有利于后期的扩张和维护,并且代码可以实现复用.

JavaEE经典架构(SSM)

Spring MVC

初识SpringMVC

1.Servlet的缺点

1.通常情况下,一个Servlet类只负责处理一个请求,若项目中有成百上千个处理,就要成百上千个Servlet类,这样会使Servlet类暴涨

2.在Servlet3.0版本之前,每一个Servlet都需要在web.xml进行配置

3.当通过客户端提交参数到服务器,通过Servlet进行接收,无论数据本身是什么格式,在Servlet中一律按照字符串进行接收,后期需要进行类型转换,复杂类型还需要特殊处理

4.Servlet具有容器依赖性,必须放在服务器中运行,不利于单元测试

2.SpringMVC简介

SpringMVC是一个spring框架的一个模块,spring和springmvc无需中间层
Spring MVC

3.快速入门

1.创建Maven web工程SpringMVCdemo

2.导入相关依赖

<!-- 集中定义依赖版本号 -->
<properties>
	<junit.version>4.10</junit.version>
	<spring.version>4.1.3.RELEASE</spring.version>
</properties>
<dependencies>
	<!-- 单元测试 -->
	<dependency>
		<groupId>junit</groupId>
		<artifactId>junit</artifactId>
		<version>${junit.version}</version>
		<scope>test</scope>
	</dependency>

	<!-- SpringMVC -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-webmvc</artifactId>
		<version>${spring.version}</version>
	</dependency>
	
	<!-- Servlet支持Request和Response -->
	<dependency>
		<groupId>javax.servlet</groupId>
		<artifactId>servlet-api</artifactId>
		<version>2.4</version>
		<scope>provided</scope>
	</dependency>
	
	<!-- java对象转换json的工具类 -->
	<dependency>
		<groupId>com.fasterxml.jackson.core</groupId>
		<artifactId>jackson-databind</artifactId>
		<version>2.5.1</version>
	</dependency>
</dependencies>

3.配置web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <display-name>SpringMVCdemo</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <!-- 配置前端控制器DispatcherServlet -->
  <servlet>
  	<servlet-name>springmvc</servlet-name>
  	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!-- 配置springmvc核心配置文件的位置,默认Springmvc的配置文件是在WEB-INF目录下,默认的名字为springmvc-servlet.xml,如果要放在其他目录,则需要指定如下配置:
		-->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springmvc-config.xml</param-value>
		</init-param>		
  </servlet>
  <!-- 配置前端控制器拦截除JSP以外的所有的请求 -->
  <servlet-mapping>
  	<servlet-name>springmvc</servlet-name>
  	<url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

4.创建WEB-INF/pages/home.jsp文件

5.在src/main/java中创建com.kingkiller.controller包,在包中创建HelloController

6.配置核心配置文件

<?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:mvc="http://www.springframework.org/schema/mvc"	xmlns:context="http://www.springframework.org/schema/context"	xsi:schemaLocation="http://www.springframework.org/schema/mvc						http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd						http://www.springframework.org/schema/beans			http://www.springframework.org/schema/beans/spring-beans-4.0.xsd						http://www.springframework.org/schema/context     		http://www.springframework.org/schema/context/spring-context-4.0.xsd">
	<!-- 1.配置前端控制器放行静态资源(html/css/js等,否则静态资源将无法访问) -->
	<mvc:default-servlet-handler/>
	<!-- 2.配置注解驱动,用于识别注解(比如@Controller) -->
	<mvc:annotation-driven></mvc:annotation-driven>
	<!-- 3.配置需要扫描的包:spring自动去扫描 base-package 下的类,
		如果扫描到的类上有 @Controller、@Service、@Component等注解,
		将会自动将类注册为bean 
	 -->
	<context:component-scan base-package="com.kingkiller.controller">
	</context:component-scan>
	<!-- 4.配置内部资源视图解析器
		prefix:配置路径前缀
		suffix:配置文件后缀
	 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/pages/"/>
		<property name="suffix" value=".jsp"/>
	</bean>
</beans>

6.编写HelloController类,完成需求,并运行测试

@Controller
//@RequestMapping("/HelloController")
public class HelloController {
    @RequestMapping("/hello")
    public String testHello() {
        System.out.println("hello springmvc");
        return "home";
    }
}

SpringMVC参数绑定

1.简单类型参数绑定

1.需求:

​ 浏览器请求:localhost:8080/SpringMVCdemo/testParam1?name=张飞&age=20&addr=中国

 	@RequestMapping("/testParam1")
    public String testParam1(String name,Integer age,String addr) {
        System.out.println("name="+name);
        return "home";//其实是一个转发的过程
    }

2.包装类型参数绑定:

​ 浏览器请求:localhost:8080/SpringMVCdemo/testParam2?name=刘备&age=18&addr=中国

在com.kingkiller.pojo包中创建User类

package com.kingkiller.pojo;
public class User {
    private String name;
    private int age;
    private String addr;
}

注意:这里需自己补全成员变量的get和set方法,以及无参构造和有参构造

编写测试类

	@RequestMapping("/testParam2")
    public String testParam2(User user) {
        System.out.println("name="+user.getName());
        System.out.println("age="+user.getAge());
        System.out.println("addr="+user.getAddr());
        return "home";
    }

3.日期类型参数绑定:

​ 浏览器请求:localhost:8080/SringMVCdemo/testParam3?date=2020/2/8 13:00:00

    @RequestMapping("/testParam3")
    public String testParam3(Date date) {
        System.out.println("data="+date);
        return "home";
    }

注意:如果在请求中用的是date=2020-2-8的形式,可能会出现400错误:请求参数类型不匹配.因为SpringMVC底层默认使用/来分割.我们可以通过更改底层代码实现的方式来解决:在Cotroller类中添加自定义日期转换格式的代码:

	/* 自定义日期转换格式 */
	@InitBinder
	public void InitBinder (ServletRequestDataBinder binder){
		binder.registerCustomEditor(java.util.Date.class, 
			new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true)
		);
	}

跳转和乱码处理

1.请求转发

其实return “home”;本身就是一个请求转发,将请求转发到home.jsp,因为请求转发是一次1请求一次响应,所以浏览器地址栏不会发生改变,显示的依然是@RequestMapping后配置的路径

我们还可以通过return "forward:**"的方式来将请求转发到其他的方法中

	@RequestMapping("/testForward")
    public String testForward() {
        System.out.println("testForward方法执行了");
        return "forward:/hello";
    }

在浏览器中输入localhost:8080/SpringMVCdemo/testForward最终会跳转到home.jsp,但浏览器地址依然是testForword,说明了请求转发只会请求一次

2.重定向

通过return "redirect:/**"的方式可以完成请求的重定向

	@RequestMapping("/testRedirect")
    public String testRedirect() {
        System.out.println("testRedirect方法执行了");
        return "redirect:/hello";
    }

在浏览器中输入localhost:8080/SpringMVCdemo/testRedirect,最终结构会跳转到home.jsp,但浏览器地址会改成/hello,因为请求重定向将地址定向到了/hello,testHello方法又发生了请求转发跳转到home.jsp

3.乱码问题:

​ Servlet:

  1. 如果是GET提交,并且tomcat为8.0以后的版本,tomcat底层已经处理了GET提交的中文乱码问题,所以GET提交在tomcat8.0以后的版本中没有乱码!

  2. 如果是POST提交,无论实哪个版本的tomcat服务器,获取中文参数时都会有乱码问题

    解决:request.setCharacterEncoding(“utf-8”)

    springmvc中提供了处理POST提交中文参数乱码方法:在web.xml文件中配置一个乱码处理过滤器.

    <filter>
    	<filter-name>encodingFilter</filter-name>
    	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    	<init-param>
    		<param-name>encoding</param-name>
    		<param-value>UTF8</param-value>
    	</init-param>
    </filter>
    <filter-mapping>
    	<filter-name>encodingFilter</filter-name>
    	<url-pattern>/*</url-pattern>
    </filter-mapping>
    

    我们创建在webapps下创建form.html进行测试(注意:不能建在WEB-INF文件里,应建在webapps文件夹内WEB-INF文件夹外)

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    	<h1>POST提交</h1>
    	<form action="http://localhost:8080/SpringMVCdemo/testParam5" method="POST">
    		用户名:<input type="text" name="user" value="username"/>
    		爱好: <input type="checkbox" name="like" value="篮球"/>篮球
    			 <input type="checkbox" name="like" value="足球"/>足球
    		<input type="submit" value="提交">
    	</form>
    </body>
    </html>
    

    在Cotroller类中编写测试方法:

        @RequestMapping("/testParam5")
        public String testParam5(String user,String[] like) {
            System.out.println("user:"+user);
            System.out.println("like:"+Arrays.toString(like));
            return "home";
        }
    

    会发现控制台中正确的输出了中文

SpringMVC响应数据

1.Model的使用

​ 从Servlet带数据到JSP:(通过request域带数据)

​ request.setAttribute(“xx”,xxx);

​ request.getRequestDispatcher(“xxx”).forward(req,res)

​ 从Controller带数据到JSP:(通过Model带数据)

​ model.addAttribute(“xx”,xxx);

第一种:以对象的方式响应数据

	@RequestMapping("/testModel")
    public String testModel(Model model) {
        //声明一个User对象,将User对象存入Model中
        User u1 = new User("张三",20,"北京");
        model.addAttribute("user",u1);
        //转发到home.jsp
        return "home";
    }

第二种:以集合的方式响应数据

	@RequestMapping("/testModel2")
    public String testModel2(Model model) {
        //声明一个User对象集合
        User u1 = new User("king",18,"china");
        User u2 = new User("queen",20,"china");
        List<User> list = new ArrayList<>();
        list.add(u2);
        list.add(u1);
        model.addAttribute("ulist",list);
        return "home";
    }

在hmoe.jsp中通过EL的方式读取数据并输出

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>springmvc...home.jsp</h1>
	${ user.name }<br/>
	${ user.age } 
	<hr/>
	${ ulist[0].name }
	${ ulist[1].name }
</body>
</html>

2.返回JSON数据

JSON是JS对象格式转换过来的一种非常流行的数据传输/交换格式

JSON中包含的数据结构是key-value格式(键值对)

1.JSON是用花括号括起来的一组内容,其中的数据是key-value结构

2.JSON中的key只能是字符串(可以加上数组)

可以通过@ResponseBody注解的方法来将返回的数据转换成JSON的格式再响应

	@RequestMapping("/testJSON")
    @ResponseBody
    public User testJSON() {
        //声明一个User对象,将User对象以JSON格式返回
        User u1 = new User("张三",20,"北京");
        return u1;
    }

t[0].name }
${ ulist[1].name }

```

2.返回JSON数据

JSON是JS对象格式转换过来的一种非常流行的数据传输/交换格式

JSON中包含的数据结构是key-value格式(键值对)

1.JSON是用花括号括起来的一组内容,其中的数据是key-value结构

2.JSON中的key只能是字符串(可以加上数组)

可以通过@ResponseBody注解的方法来将返回的数据转换成JSON的格式再响应

	@RequestMapping("/testJSON")
    @ResponseBody
    public User testJSON() {
        //声明一个User对象,将User对象以JSON格式返回
        User u1 = new User("张三",20,"北京");
        return u1;
    }