SpringMVC框架(一)

一、三层架构和MVC

1. 三层架构

  1. 开发服务器端程序,一般都基于两种形式,一种C/S架构程序,一种B/S架构程序
  2. 使用Java语言基本上都是开发B/S架构的程序,B/S架构又分成了三层架构
  3. 三层架构
    1. 表现层:WEB层,用来和客户端进行数据交互的。表现层一般会采用MVC的设计模型
    2. 业务层:处理公司具体的业务逻辑的
    3. 持久层:用来操作数据库的

2. MVC模型

  1. MVC全名是Model View Controller 模型视图控制器,每个部分各司其职。
  2. Model:数据模型,JavaBean的类,用来进行数据封装。
  3. View:指JSP、HTML用来展示数据给用户
  4. Controller:用来接收用户的请求,整个流程的控制器。用来进行数据校验等。

二、SpringMVC的入门案例

1. SpringMVC的概述

  1. SpringMVC的概述
    1. 是一种基于Java实现的MVC设计模型的请求驱动类型的轻量级WEB框架。
    2. Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。
    3. 使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的SpringMVC框架或集成其他MVC开发框架,如Struts1(现在一般不用),Struts2等。
  2. SpringMVC在三层架构中的位置    表现层框架
  3. SpringMVC和Struts2框架的对比

       ①设计理念:Spring MVC遵循的是一种基于组件的设计理念,通过各种组件的组合来处理请求和生成响应。每个组件都有明确的职责,例如控制器处理请求,模型保存数据,视图渲染页面等。而Struts2则更注重配置,通过配置文件来定义请求和响应的处理方式。

      ②控制器:Spring MVC的控制器类似于Servlet,需要实现特定的接口或者继承特定的类。而Struts2的控制器则是一个普通的POJO,通过注解或者配置文件来定义其行为。

      ③视图:Spring MVC和Struts2都支持多种视图技术,如JSP、Freemarker、Velocity等。但是,Spring MVC对于这些技术的支持更加直接和简洁。

      ④配置:Spring MVC的配置相对简单,大部分情况下只需要在Spring的配置文件中定义相应的bean即可。而Struts2则需要大量的配置文件和注解来定义其行为。

      ⑤测试:Spring MVC更加容易进行单元测试和集成测试,因为它的组件化设计使得每个组件都可以独立地进行测试。而Struts2的测试则相对复杂一些,因为它的控制器是一个普通的Java类,没有实现任何接口,测试起来需要更多的工作。

      ⑥安全性:Struts2提供了一些内置的安全功能,如拦截器、验证等。而Spring MVC则需要开发者自行设计和实现这些功能。

总的来说,Spring MVC更加灵活、简洁和易于测试,因此在现代Java Web开发中得到了广泛的应用。而Struts2则在一些特定的情况下,如在需要使用大量的自定义配置和安全措施时,可能会有更好的表现。

2. SpringMVC的入门程序

创建meavenjavaweb工程,引入开发的jar包

具体的坐标如下

 
    
        5.0.2.RELEASE
    
    
    
        
            org.springframework
            spring-context
            ${spring.version}
        
            org.springframework
            spring-web
            ${spring.version}
        
            org.springframework
            spring-webmvc
            ${spring.version}
        
            javax.servlet
            servlet-api
            2.5
            provided
        
            javax.servlet.jsp
            jsp-api
            2.0
            provided
        
    

编写index.jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    入门程序


    <%--超链接--%>
    

入门

入门程序

编写suc.jsp页面,路径为:/WEB-INF/pages/suc.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    成功

    
    

入门成功了2...

编写Controller类和方法

package com.qcby.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/** 
 * 控制器类,处理用户的请求
 */
// 把当前类交给IOC容器进行管理
@Controller
//@RequestMapping(path = "/hello.do")  一级
public class HelloController {
    /**
     * 处理超链接发送出来的请求
     * @return
     */
    // 配置映射的配置
    @RequestMapping(path = "/hello.do")  //二级
    public String sayHello(){
        System.out.println("入门方法执行了2...");
        // 跳转的JSP页面的路径,默认使用的是请求的转发
        // return "/WEB-INF/pages/suc.jsp";
        // 配置了视图解析器后,写法
        return "suc";
    }

}
​

在web.xml配置文件中配置核心控制器DispatcherServlet

 
  
    dispatcherServlet
    org.springframework.web.servlet.DispatcherServlet
    
    
      contextConfigLocation
      classpath:springmvc.xml
    
    
    1
  
  
    dispatcherServlet
    《!--*.do-->
    /
  

编写springmvc.xml的配置文件



        
    
    
     
    
    
        
        
    
    
    

启动Tomcat服务器,进行测试

3. 入门案例的执行过程分析

入门案例的执行流程

  1. 当启动Tomcat服务器的时候,因为配置了load-on-startup标签,所以会创建DispatcherServlet对象,就会加载springmvc.xml配置文件
  2. 开启了注解扫描,那么HelloController对象就会被创建
  3. 从index.jsp发送请求,请求会先到达DispatcherServlet核心控制器,根据配置@RequestMapping注解找到执行的具体方法
  4. 根据执行方法的返回值,再根据配置的视图解析器,去指定的目录下查找指定名称的JSP文件
  5. Tomcat服务器渲染页面,做出响应

SpringMVC官方提供图形

入门案例中的组件分析

①   前端控制器(DispatcherServlet)

       这是Spring MVC框架的入口点。所有的Web请求都首先由它接收。

       它负责根据请求选择一个处理器(Handler)来处理请求,并确保响应被发送回客户端。

②   处理器映射器(HandlerMapping)

       处理器映射器负责根据请求找到相应的处理器(Handler)。

       它根据URL和请求参数等信息,将请求映射到一个处理器。

③   处理器(Handler)

       处理器是实际处理请求的组件。

       它通常是一个Controller类的方法,负责处理业务逻辑。

④   处理器适配器(HandlerAdapter)

       处理器适配器是一个适配器,用于将请求适配到处理器。

       它根据处理器的类型和请求的特性,决定如何调用处理器。

⑤   视图解析器(View Resolver)

       视图解析器负责将逻辑视图名解析为实际的视图实现。

       它根据逻辑视图名找到相应的视图,如JSP、Thymeleaf等。

⑥   视图(View)

       视图是用于渲染响应的组件,它将模型数据呈现给用户。

       Spring MVC支持多种视图技术,如JSP、Thymeleaf、Freemarker等。

4、RequestMapping注解

RequestMapping注解的作用是建立请求URL和处理方法之间的对应关系

RequestMapping注解可以作用在方法和类上

  1. 作用在类上:第一级的访问目录
  2. 作用在方法上:第二级的访问目录
  3. 细节:路径可以不编写 / 表示应用的根目录开始

RequestMapping的属性

  1. path 指定请求路径的url
  2. value value属性和path属性是一样的
  3. mthod 指定该方法的请求方式
  4. params 指定限制请求参数的条件
package com.qcby.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping(path = "/role")        // 一级请求路径
public class RoleController {

    /**
     * /role/save.do
     * method="当前方法允许请求方式能访问"
     * params="请求路径上传参数"
     * @return
     */
    @RequestMapping(path = "/save.do",method = {RequestMethod.GET},params = "username")
    public String save(){
        System.out.println("保存角色...");
        return "suc";
    }

    @RequestMapping(value = "/delete.do")
    public String delete(){
        System.out.println("删除角色...");
        return "suc";
    }

}

​

三、请求参数的绑定

请求参数的绑定说明

  1. 绑定机制
    1. 表单提交的数据都是k=v格式的 username=haha&password=123
    2. SpringMVC的参数绑定过程是把表单提交的请求参数,作为控制器中方法的参数进行绑定的
    3. 要求:提交表单的name和参数的名称是相同的
  2. 支持的数据类型
    1. 基本数据类型和字符串类型
    2. 实体类型(JavaBean)
    3. 集合数据类型(List、map集合等)

基本数据类型和字符串类型

  1. 提交表单的name和参数的名称是相同的
  2. 区分大小写

实体类型(JavaBean)

  1. 提交表单的name和JavaBean中的属性名称需要一致
  2. 如果一个JavaBean类中包含其他的引用类型,那么表单的name属性需要编写成:对象.属性 例如:address.name

给集合属性数据封装

  1. JSP页面编写方式:list[0].属性、map['1'].属性

jsp代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    请求参数绑定

请求参数绑定入门

姓名:
年龄:

请求参数绑定(封装到实体类)

姓名:
年龄:

请求参数绑定(封装到实体类,存在引用类型)

姓名:
年龄:
金额:

请求参数绑定(封装到实体类,存在list集合)

姓名:
年龄:
金额:
集合金额1:
集合金额2:

请求参数绑定(封装到实体类,存在map集合)

姓名:
年龄:
金额:
集合金额1:
集合金额2:
map集合1:
map集合2:

Javabean代码

package com.qcby.mapper;
import java.io.Serializable;
import java.util.List;
import java.util.Map;

public class User implements Serializable {

    private String username;
    private Integer age;

        // 引用对象
    private Address address;

    // list集合
    private List
list; // Map集合 private Map map; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public List
getList() { return list; } public void setList(List
list) { this.list = list; } public Map getMap() { return map; } public void setMap(Map map) { this.map = map; } @Override public String toString() { return "User{" + "username='" + username + '\'' + ", age=" + age + ", address=" + address + ", list=" + list + ", map=" + map + '}'; } } package com.qcby.mapper; import java.io.Serializable; public class Address implements Serializable { // 金额 private Double money; public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } @Override public String toString() { return "Address{" + "money=" + money + '}'; } }

controller代码

package com.qcby.controller;
import com.qcby.mapper.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 用户的模块
 */
@Controller
@RequestMapping("/user")
public class UserController {

    /**
     * 请求参数的绑定
     * @return
     */
    @RequestMapping("/save1.do")
    public String save(String username,Integer age){
        System.out.println("姓名:"+username);
        System.out.println("年龄:"+age);
        return "suc";
    }

    /**
     * 请求参数的绑定
     * @return
     */
    @RequestMapping("/save2.do")
    public String save2(User user){
        System.out.println("姓名:"+user.getUsername());
        System.out.println("年龄:"+user.getAge());
        System.out.println("user对象:"+user);
        return "suc";
    }

    /**
     * 请求参数的绑定
     * @return
     */
    @RequestMapping("/save3.do")
    public String save3(User user){
        System.out.println("user对象:"+user);
        return "suc";
    }

    /**
     * 请求参数的绑定
     * @return
     */
    @RequestMapping("/save4.do")
    public String save4(User user){
        System.out.println("user对象:"+user);
        return "suc";
    }

}
 ​

请求参数中文乱码的解决

在web.xml中配置Spring提供的过滤器类

 
    
        characterEncodingFilter
        org.springframework.web.filter.CharacterEncodingFilter
        
        
            encoding
            UTF-8
        
    
    
        characterEncodingFilter
        /*
    

自定义类型转换器

第一种方式使用DateTimeFormat注解的方式

// 2000-11-11 格式的日期不能进行转换了,开发使用还是比较多,比较简单
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birthday;​

并且在springmvc.xml文件中配置


    

第二种方式,自定义类型转换器。如果想自定义数据类型转换,可以实现Converter的接口

package com.qcby.mapper;
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 自定义类型转换器 把String转换成Date
 */
public class StringToDate implements Converter{
    /**
     * 进行类型转换的方法
     * @param s     用户输入的内容
     * @return
     */
    @Override
    public Date convert(String s) {
        // 判断
        if(s == null){
            throw new RuntimeException("请输入内容");
        }
        // 进行转换
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            // 进行转换
            return sdf.parse(s);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }
}​

注册自定义类型转换器,在springmvc.xml配置文件中编写配置



        
        
        
        
    
        
            
                
            
        
    

在控制器中使用原生的ServletAPI对象

只需要在控制器的方法参数定义HttpServletRequest和HttpServletResponse对象

/**
     * 原生的API
     * @return
     */
    @RequestMapping("/save6.do")
    public String save6(HttpServletRequest request, HttpServletResponse response){
        System.out.println(request);
        // 获取到HttpSession对象
        HttpSession session = request.getSession();
        System.out.println(session);
        System.out.println(response);
        return "suc";
    }  ​

四、常用的注解

1、RequestParam注解

  1. 作用:把请求中的指定名称的参数传递给控制器中的形参赋值
  2. 属性
    1. value:请求参数中的名称
    2. required:请求参数中是否必须提供此参数,默认值是true,必须提供
  3. 代码如下
package com.qcby.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@RequestMapping("/dept")
public class DeptController {
    /**
     * RequestParam注解
     * required = false ,默认值是true,必须要传请求参数,不传就会报错
     * defaultValue = "abc" 如果没有传请求参数,使用默认值
     * @return
     */
    @RequestMapping("/save1.do")
    public String save(@RequestParam(value = "username",required = false,defaultValue = "abc") String name){
        System.out.println("姓名:"+name);
        return "suc";
    }
}

2、RequestBody注解

  1. 作用:用于获取请求体的内容(注意:get方法不可以)
  2. 属性
    1. required:是否必须有请求体,默认值是true
  3. 代码如下
    @RequestMapping("/save2.do")
    public String save2(@RequestBody String body){
        System.out.println("请求体内容:"+body);
        return "suc";
    }        

3、PathVaribale注解

    1. 作用:拥有绑定url中的占位符的。例如:url中有/delete/{id},{id}就是占位符

    2. 属性

  1. value:指定url中的占位符名称
  2. Restful风格的URL
    1. 请求路径一样,可以根据不同的请求方式去执行后台的不同方法
    2. restful风格的URL优点
      1. 结构清晰
      2. 符合标准
      3. 易于理解
      4. 扩展方便
  3. 代码如下
package com.qcby.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
// @RequestMapping("/emp")
public class EmpController {
    /**
     * 保存
     * post  新增
     * delete  删除
     * put 修改
     * get 查询
     * 访问:localhost:8080/emp
     */
    @RequestMapping(path = "/emp",method = RequestMethod.POST)
    public String save(){
        System.out.println("保存员工...");
        return "suc";
    }

    /**
     * 查询所有
     * @return
     * 访问:localhost:8080/emp
     */
    @RequestMapping(path = "/emp",method = RequestMethod.GET)
    public String findAll(){
        System.out.println("查询员工...");
        return "suc";
    }

    /**
     * 根据id查询
     * @return
     * 访问:localhost:8080/emp/1
     */
    @RequestMapping(path = "/emp/{id}",method = RequestMethod.GET)
    public String findById(@PathVariable(value = "id") Integer id){
        System.out.println("通过id查询员工..."+id);
        return "suc";
    }
    
    @RequestMapping(path = "/emp/name/{name}", method = RequestMethod.GET)
    public String findByName(@PathVariable(value = "name") String name) {
        // 根据名字查询员工
        System.out.println("通过名字查询员工..." + name);
        return "suc";
    }
}
​

修改前端控制器的配置文件


  
    dispatcherServlet
    org.springframework.web.servlet.DispatcherServlet
    
    
      contextConfigLocation
      classpath:springmvc.xml
    
    
    1
  
  
  
    dispatcherServlet
    /
   

4、RequestHeader注解

  1. 作用:获取指定请求头的值
  2. 属性
    1. value:请求头的名称
  3. 代码如下
/**
     * RequestHeader 获取请求头的值
     * @return
     */
    @RequestMapping("/save3.do")
    public String save3(@RequestHeader(value = "Accept") String header){
        System.out.println("Accept请求头的值:"+header);
        return "suc";
    }   

5、CookieValue注解

  1. 作用:用于获取指定cookie的名称的值
  2. 属性
    1. value:cookie的名称
  3. 代码
 /**
     * CookieValue 获取到cookie中的值
     * @return
     */
    @RequestMapping("/save4.do")
    public String save4(@CookieValue(value = "JSESSIONID") String cookie){
        System.out.println("值:"+cookie);
        return "suc";
    } 

你可能感兴趣的:(java,mvc)