简介
三层架构是什么
三层架构分别是表现层、业务层和持久层。
表现层也就是我们常说的web层,负责接收客户端的请求,向客户端相应数据。业务层也就是service层,负责业务逻辑处理。持久层也就是dao层,负责数据持久化,与数据库打交道,对数据库表进行增删改查等操作。
MVC是什么
MVC是Model View Controller的缩写,Model就是数据模型,用于封装数据,也可以理解为就是JavaBean; View是视图,一般用来展示数据,通常指jsp或html等;Controller是控制器,处理程序逻辑。
SpringMVC是什么
1.表现层框架,负责接收客户端请求,并向客户端相应结果。
2.它通过一套注解,让一个简单的Java类成为可以处理请求的控制器,并且还支持RESTful编程风格。
3.与Spring无缝集成,这点是其他框架不可比的。
入门案例
创建一个web项目
创建一个web项目项目目录结构
添加依赖
<dependencies>
<!--springmvc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
<!--spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
<!--servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<!--jsp-->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
</dependency>
</dependencies>
配置
在web.xml中配置前置控制器
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!--前置控制器-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--可以不配置, 默认会找WEB-INF/*-servlet.xml-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!--
1. 是否在启动的时候就加载这个servlet(实例化并调用其init()方法)
2. 它的值必须是一个整数,表示servlet应该被载入的顺序
3. 当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet
4. 当值小于0或者没有指定时,则表示容器在该servlet被选择时才会去加载
5. 正数的值越小,该servlet的优先级越高,应用启动时就越先加载
-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
创建src/main/resources/springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解扫描 -->
<context:component-scan base-package="com._54programer"/>
<!-- 视图解析器对象 -->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 开启SpringMVC框架注解的支持 -->
<mvc:annotation-driven/>
</beans>
创建控制器
package com.sn511.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
@RequestMapping(path = "/hello")
public String hello(){
System.out.println("hello springmvc");
return "hello";
}
}
创建jsp
/webapp/WEB-INF/pages/hello.jsp
<%--
Created by IntelliJ IDEA.
User: SN
Date: 2019/9/21
Time: 10:33
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Helo</title>
</head>
<body>
<h3>Hello SpringMVC</h3>
</body>
</html>
访问: http://localhost:8080/springmvc_war/hello
执行流程分析
第一阶段
Tomcat启动,加载web.xml文件,实例并初始化DispatchServlet,DispatchServlet加载springmvc.xml并创建Spring容器,根据配置初始化对象。
流程图第二阶段
客户端访问,发送hello请求,请求先到达前端控制器DispatchServlet,然后DispatchServlet根据请求动作名称转发请求到HelloController,然后HelloController根据方法返回值通过InternalResourceViewResolver找到相应的结果视图并响应给客户端。
DispatcherServlet,前端控制器,dispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet 的存在降低了组件之间的耦合性。
常用注解
RequestMapping
用于建立请求URL和处理请求方法之间的对应关系
位置: 类、方法上
属性:
value: 用于指定请求的 URL
method: 用于指定请求的 方式
params: 用于指定限制请求参数的条件,要求请求参数的 key 和 value 必须和配置的一模一样
headers: 用于指定限制请求消息头的条件
//get请求, 必须有name参数, 否则报错
@RequestMapping(value = "/hello", method = RequestMethod.GET, params = {"name"})
public String hello(){
System.out.println("hello springmvc");
return "hello";
}
参数绑定
把请求参数和控制器方法参数进行绑定
支持基本类型、实体类和集合类型。
基本类型
要求参数名称必须和控制器方法的名称保持一致,严格区分大小写
http://localhost:8080/springmvc_war/hello?name=lisi&age=11
@RequestMapping(value = "/hello")
public String hello(String name, Integer age){
System.out.println("hello "+ name + ", age is "+ age);
return "hello";
}
实体类类型
要求表单中的参数和实体类的属性名称保持一致
public class Address implements Serializable {
private String provinceName; //省份
private String cityName;//城市
省略getter、setter方法
}
public class Person implements Serializable {
private String name;
private Integer age;
private Address address;
省略getter、setter方法
}
@Controller
public class PersonController {
@RequestMapping("/person")
public void person(Person person){
}
}
# 表单
<form action="/person" method="get">
<input type="text" name="name">
<input type="text" name="age">
<input type="text" name="address.provinceName">
<input type="text" name="address.cityName">
</form>
集合类型
两种方式,第一种要求集合类型的请求参数必须在实体类中;第二种接收的请求参数是json格式数据,需要借助一个注解实现。
public class Company {
private String name;
private List<Person> persons;
private Map<String, Person> personMap;
}
<form action="/user" method="get">
<input type="text" name="name">
<input type="text" name="persons[0].name">
<input type="text" name="persons[1].name">
<input type="text" name="personMap['first'].name">
<input type="text" name="personMap['seconed'].name">
</form>
SpringMVC支持使用原始 ServletAPI 对象作为控制器方法的参数
支持原始 ServletAPI 对象有:
HttpServletRequest,HttpServletResponse,HttpSession
InputStream,OutputStream
Reader,Writer
java.security.Principal
Locale
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request,HttpServletResponse response,HttpSession session) {
}
RequestParam
把请求中指定名称的参数给控制器中的形参赋值
属性
value: 请求参数中的名称
required: 请求参数中是否必须提供此参数。默认值:true
@RequestMapping("/person")
public void person(@RequestParam("name") String username, @RequestParam(value = "age", required = false) Integer age){
}
RequestBody
用于获取请求体内容。直接使用得到是 key=value&key=value...结构的数据,get 请求方式不适用
属性
required: 是否必须有请求体。默认值是:true
@RequestMapping("/person")
public void person(@RequestBody(required = false) String body){
System.out.println(body); //name=lisi&age=11
}
ResponseBody
该注解用于将 Controller 的方法返回的对象,通过 HttpMessageConverter 接口转换为指定格式的数据如:json,xml 等,通过 Response 响应给客户端
PathVaribale
用于绑定 url 中的占位符。
例如:请求 url 中 /delete/{id},这个{id}就是 url 占位符。
url 支持占位符是 spring3.0 之后加入的。是 springmvc 支持 rest 风格 URL 的一个重要标志。
属性:
value:用于指定 url 中占位符名称。
required:是否必须提供占位符。
# /person/20
@RequestMapping("/person/{id}")
public void person(@PathVariable("id") Integer id){
}
RequestHeader
用于获取请求消息头,在实际开发中一般不怎么用。
属性:
value:提供消息头名称
required:是否必须有此消息头
@RequestMapping("/person")
public void person(@RequestHeader(value = "Accept-Language", required = false) String requestHeader){
}
CookieValue
用于把指定 cookie 名称的值传入控制器方法参数
属性:
value:指定 cookie 的名称。
required:是否必须有此 cookie。
@RequestMapping("/useCookieValue")
public vode person(@CookieValue(value="JSESSIONID",required=false) String cookieValue){
}
ModelAttribute
用于修饰方法和参数,出现在方法上,表示当前方法会在控制器的方法执行之前,先执行
属性
value:用于获取数据的 key。key 可以是 POJO 的属性名称,也可以是 map 结构的 key。应用场景:
当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据
SessionAttribute
用于多次执行控制器方法间的参数共享。
属性:
value:用于指定存入的属性名称
type:用于指定存入的数据类型。
响应数据和结果视图
返回值
字符串
返回字符串可以指定逻辑视图名,通过视图解析器解析为物理视图地址。
@RequestMapping("/hello")
public String hello(){
return "success";
}
void
返回值为void,可以在代码中指定逻辑逻辑视图路径。
@RequestMapping("/person")
public void person(HttpServletRequest request, HttpServletResponse response) throws Exception{
//1. 使用request跳转页面
request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request, response);
//2. 使用response重定向
response.sendRedirect("");
//3. 使用response指定相应结果
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=urf-8");
response.getWriter().write("hello");
}
ModelAndView
@RequestMapping("/person")
public ModelAndView person() throws Exception{
ModelAndView modelAndView = new ModelAndView();
//这里添加的数据, 在也面上可以通过el表达式直接获取
modelAndView.addObject("name", "lisi");
//设置视图名称,视图解析器会根据名称前往指定的视图
modelAndView.setViewName("success");
return modelAndView;
}
forward转发和Redireac重定向
@RequestMapping("/person")
public String person() throws Exception{
//等价于request.getRequestDispatcher("url").forward(request, response)
return "forward:/WEB-INF/pages/success.jsp";
}
@RequestMapping("/person")
public String person() throws Exception{
//等价于response.sendRedirect(url);
return "redireac:url";
}
乱码问题
web.xml
<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>
网友评论