Spring MVC
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:
-
获取请求中的数据
-
调用某一个JavaBean对请求进行处理
-
调用某一个JSP展示请求处理的结果
JavaBean:
-
处理请求
-
处理业务逻辑
-
访问数据
-
封装数据库
JSP:
1.将请求处理的结果展示给用户
MVC设计模式
MVC设计模式是一种通用的软件编程思想
在MVC设计模式中认为,任何软件都可以分为三部分组成:
1.控制程序流转的控制器(Controller)
2.封装数据处理的模型(Model)
3.负责展示数据的视图(View)
并且在MVC设计思想中要求一个符合MVC设计思想的软件应该保证上面三部分相互独立,互不干扰,每一个部分只负责自己擅长的部分.
如果某一个模块发生变化,应该尽量做到不影响其他两个模块.这样做的好处是,软件的结构会变的更加的清晰,可读性强.有利于后期的扩张和维护,并且代码可以实现复用.
JavaEE经典架构(SSM)
初识SpringMVC
1.Servlet的缺点
1.通常情况下,一个Servlet类只负责处理一个请求,若项目中有成百上千个处理,就要成百上千个Servlet类,这样会使Servlet类暴涨
2.在Servlet3.0版本之前,每一个Servlet都需要在web.xml进行配置
3.当通过客户端提交参数到服务器,通过Servlet进行接收,无论数据本身是什么格式,在Servlet中一律按照字符串进行接收,后期需要进行类型转换,复杂类型还需要特殊处理
4.Servlet具有容器依赖性,必须放在服务器中运行,不利于单元测试
2.SpringMVC简介
SpringMVC是一个spring框架的一个模块,spring和springmvc无需中间层
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:
-
如果是GET提交,并且tomcat为8.0以后的版本,tomcat底层已经处理了GET提交的中文乱码问题,所以GET提交在tomcat8.0以后的版本中没有乱码!
-
如果是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;
}
上一篇: Linux命令之sed命令使用介绍
下一篇: PV、IP、UV是什么?