SpringMVC入门

2019-09-21  本文已影响0人  iDevOps

简介

三层架构是什么

三层架构分别是表现层、业务层和持久层。
表现层也就是我们常说的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

Hello SpringMVC

执行流程分析

第一阶段
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>
上一篇下一篇

猜你喜欢

热点阅读