SpringMVC_01

1 关于三层架构和 MVC

1.1 三层架构

在JavaEE 开发中,几乎全都是基于 B/S 架构的开发。那么在 B/S 架构中,系统标准的三层架构,包括:表现层、业务层、持久层

  • 表现层:
    也就是我们常说的web层。它负责接收客户端请求,向客户端响应结果,通常客户端使用http协议请求web 层,web 需要接收 http 请求,完成 http 响应。
    表现层包括展示层和控制层:控制层负责接收请求,展示层负责结果的展示。
    表现层依赖业务层,接收到客户端请求一般会调用业务层进行业务处理,并将处理结果响应给客户端。
    表现层的设计一般都使用 MVC 模型。(MVC 是表现层的设计模型,和其他层没有关系)
  • 业务层:
    也就是我们常说的 service 层。它负责业务逻辑处理,和我们开发项目的需求息息相关。web 层依赖业务层,但是业务层不依赖 web 层。
    业务层在业务处理时可能会依赖持久层,如果要对数据持久化需要保证事务一致性。(也就是我们说的,事务应该放到业务层来控制
  • 持久层:
    也就是我们是常说的 dao 层。负责数据持久化,包括数据层即数据库和数据访问层,数据库是对数据进行持久化的载体,数据访问层是业务层和持久层交互的接口,业务层需要通过数据访问层将数据持久化到数据库中。通俗的讲,持久层就是和数据库交互,对数据库表进行曾删改查的。

1.2 MVC 模型

MVC 全名是 Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,是一种用于设计创建 Web 应用程序表现层的模式。
MVC 中每个部分各司其职:

  • Model(模型):
    通常指的就是我们的数据模型。作用一般情况下用于封装数据。
  • View(视图):
    通常指的就是我们的 jsp 或者 html。作用一般就是展示数据的。
    通常视图是依据模型数据创建的。
  • Controller(控制器):
    是应用程序中处理用户交互的部分。作用一般就是处理程序逻辑的。

2 SpringMVC 的入门

2.1 入门案例

  1. 导入项目所需坐标,将maven项目下的文件夹补全,创建配置文件springmvc.xml,加入一些约束信息。
  2. 配置spring.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">


    <!--开启注解扫描  spring创建容器时要扫描的包-->
    <context:component-scan base-package="cn.itcast"></context:component-scan>
    
    <!--配置视图解析器对象-->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--控制器执行成功后跳转到指定页面-->
        <!--找目录下文件-->
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <!--文件后缀-->
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--开启springMVC框架注解的支持-->
    <mvc:annotation-driven></mvc:annotation-driven>
</beans>
  1. 配置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>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--加载配置文件springmvc.xml -> 注解扫描生效 -> 类生效-->
    <!--全局的初始化-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <!--原本应该是第一次发请求,servlet才创建,配置标签后,在启动服务器时,
    容器就加载并初始化这个servlet,然后执行init-->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>
  1. 控制器
//前端:
<body>
    <h3>入门程序</h3>
    <%--相对路径--%>
    <a href="hello">入门程序</a>
</body>


//后台处理
/**
 * 控制器类
 */
//把类交给ioc容器管理
@Controller
public class HelloController {

    //请求的映射:提供请求路径  (用于建立请求 URL 和处理请求方法之间的对应关系。)
    @RequestMapping(path = "/hello")
    public String sayHello(){
        System.out.println("hello springMvc");
        return "success";   //默认表示jsp名字
    }
}
  • 流程总结:
    在这里插入图片描述

2.2 组件和注解

组件

在这里插入图片描述

  • DispatcherServlet:前端控制器
    用户请求到达前端控制器,它就相当于 mvc 模式中的 c,dispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,dispatcherServlet 的存在降低了组件之间的耦合性。
  • HandlerMapping:处理器映射器
    HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
  • Handler:处理器
    它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到 Handler。由Handler 对具体的用户请求进行处理。
  • HandlAdapter:处理器适配器
    通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
  • View Resolver:视图解析器
    View Resolver 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名,即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。

之前的案例中,我们并没有把组件全部配置,但是仍然可以使用,原因是我们开启了springMvc的注解支持:

  • <mvc:annotation-driven>说明
    在 SpringMVC 的各个组件中,处理器映射器、处理器适配器、视图解析器称为 SpringMVC 的三大组件。
    使 用 <mvc:annotation-driven> 自动加载 RequestMappingHandlerMapping (处理映射器) 和RequestMappingHandlerAdapter ( 处 理 适 配 器 ) , 可 用 在 SpringMVC.xml 配 置 文 件 中 使 用<mvc:annotation-driven>替代注解处理器和适配器的配置。
注解
  • @RequestMapping
    • 作用:用于建立请求 URL 和处理请求方法之间的对应关系
    • 定义:可以定义在类上或者方法上,如果定义在类上则表示一级目录,此时类上的注解表示二级目录,这样可以使Url模块化管理,也可以直接定义在方法上,表示要访问的路径。
    • 属性:
      value:用于指定请求的 URL。它和 path 属性的作用是一样的。
      method:用于指定请求的方式。
      params:用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的 key 和 value 必须和配置的一模一样。
//method = {RequestMethod.POST}超链接失败405,Request method 'GET' not supported
//params必须传入对应参数,要求请求参数的 key 和 value 必须和配置的一模一样
//headers:用于指定限制请求消息头的条件,需要包含指定请求头
@RequestMapping(value = "/testRequestMapping",params = {"username=heihei"},headers = {"Accept"})

3 请求参数的绑定

  1. 简单的数据
    对于较少的数据,获取请求参数,可以直接在controller方法的形参中接收。
jsp
<%--请求参数绑定--%>
<a href="param/testParam?username=hehe&password=123">请求参数绑定</a>

@Controller
@RequestMapping("/param")
public class ParamCtroller {

    @RequestMapping("testParam")
    public String testParam(String username,String password){
        System.out.println("执行...");
        System.out.println(username+"--->"+password);
        return "success";
    }

}
  1. 数据封装到 JavaBean
<form action="param/saveAccount" method="post">
        <%--name与javaBean的属性一致,会去找对应的set方法--%>
        姓名:<input type="text" name="username"><br>
        密码:<input type="text" name="password"><br>
        金额:<input type="text" name="money"><br>
        <%--实体类中包含引用类型--%>
        用户姓名:<input type="text" name="user.uname"><br>
        用户年龄:<input type="text" name="user.age"><br>
        <input type="submit" value="提交">
    </form>
实体类Bean
public class Account implements Serializable {
    private String username;
    private String password;
    private Double money;

    private User user;		//引用类型
    ...
}

Controller
 //请求参数绑定,把数据封装到javaBean的类中
    @RequestMapping("saveAccount")
    public String saveAccount(Account account){ //默认表单传过来的数据会被封装成Account
        System.out.println("执行...");
        System.out.println(account);
        return "success";
    }
  1. 请求参数绑定集合类型
<%--把数据封装到Account类中,类中存在list和map集合--%>
    <form action="param/saveAccount" method="post">
        姓名:<input type="text" name="username"><br>
        密码:<input type="text" name="password"><br>
        金额:<input type="text" name="money"><br>
        <%--list	把参数封装成user对象,存到list--%>
        用户姓名:<input type="text" name="list[0].uname"><br>
        用户年龄:<input type="text" name="list[0].age"><br>
        <%--map  key为'one' --%>
        用户姓名:<input type="text" name="map['one'].uname"><br>
        用户年龄:<input type="text" name="map['one'].age"><br>
        <input type="submit" value="提交">
    </form>
实体类存在集合类型
public class Account implements Serializable {
    private String username;
    private String password;
    private Double money;

    private List<User> list;
    private Map<String,User> map;
}
  1. 配置解决中文乱码的过滤器
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>
  1. 自定义类型转换器
/**
 * 把字符串转换为日期
 */
public class StringToDateConverter implements Converter<String, Date> {
        
    @Override
    public Date convert(String source) {    //String source:传进来的字符串
        //判断
        if(source==null){
            throw new RuntimeException("请传入参数");
        }
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        //把字符串转换为日期
        try {
            return df.parse(source);
        } catch (ParseException e) {
            throw new RuntimeException("数据类型转换错误");
        }
    }
}
springmvc.xml
<!--配置自定义类型转换器-->
    <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <bean class="cn.itcast.utils.StringToDateConverter"></bean>
            </set>
        </property>
    </bean>

    <!--开启springMVC框架注解的支持
        conversion-service="conversionService":使自定义类型转换器生效
    -->
    <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
  1. 使用 ServletAPI 对象作为方法参数
    SpringMVC 还支持使用原始 ServletAPI 对象作为控制器方法的参数。
//原生servletApi  --- 直接在方法上加参数(想获得的对象)
    @RequestMapping("/textServlet")
    public String textServlet(HttpServletRequest request, HttpServletResponse response){
        System.out.println("执行...");
        System.out.println(request);
        System.out.println(response);
        HttpSession session = request.getSession();
        System.out.println(session);
        ServletContext servletContext = session.getServletContext();
        System.out.println(servletContext);
        return "success";
    }

4 常用注解

  1. RequestParam
  • 作用:把请求中指定名称的参数给控制器中的形参赋值。
  • 属性:
    value:请求参数中的名称。
    required:请求参数中是否必须提供此参数。默认值:true。表示必须提供,如果不提供将报错。
jsp
<a href="anno/textRequestParam?name=哈哈">RequestParam</a>

控制器
@Controller
@RequestMapping("/anno")
public class AnnoController {
    @RequestMapping("/textRequestParam")
    //必须传入指定名称参数,required 默认true,修改false则参数不必要,可不提供
    public String textRequestParam(@RequestParam(name = "name",required = true) String username){
        System.out.println("执行了");
        System.out.println(username);
        return "success";
    }
}
  1. RequestBody
  • 作用:
    用于获取请求体内容。直接使用得到是 key=value&key=value…结构的数据。
    get 请求方式不适用(get没有请求体)。
  • 属性:
    required:是否必须有请求体。默认值是:true。当取值为 true 时,get 请求方式会报错。如果取值为 false,get 请求得到是 null。
<form action="anno/textRequestBody" method="post">
   用户姓名:<input type="text" name="username"><br>
   用户年龄:<input type="text" name="age"><br>
   <input type="submit" value="提交">
</form>
--------------------------------------------
    //获取请求体的内容
    @RequestMapping("/textRequestBody")
    public String textRequestBody(@RequestBody String body){
        System.out.println("执行了");
        System.out.println(body);   //username=zhangsan+&age=29
        return "success";
    }
  1. PathVaribale
  • 作用:
    用于绑定 url 中的占位符。例如:请求 url 中 /delete/{id},这个{id}就是 url 占位符。
    url 支持占位符是 spring3.0 之后加入的。是 springmvc 支持 rest 风格 URL 的一个重要标志。
  • 属性:
    value:用于指定 url 中占位符名称。
    required:是否必须提供占位符。
直接 / 后加参数
<a href="anno/textPathVaribale/10">textPathVaribale</a>
--------------------------------------------
//PathVaribale注解
    @RequestMapping("/textPathVaribale/{sid}")
    //绑定uri中占位符
    public String textPathVaribale(@PathVariable(name = "sid") String id){
        System.out.println("执行了");
        System.out.println(id);
        return "success";
    }
  1. RequestHeader(不常用)
  • 作用:用于获取请求消息头。
  • 属性:
    value:提供消息头名称
    required:是否必须有此消息头
<a href="anno/textRequestHeader">RequestHeader</a>

//获取请求头的值
    @RequestMapping("/textRequestHeader")
    //获取特定请求头的值
    public String textRequestHeader(@RequestHeader(value = "Accept") String header){
        System.out.println("执行了");
        System.out.println(header);
        return "success";
    }
  1. CookieValue
  • 作用:用于把指定 cookie 名称的值传入控制器方法参数。
  • 属性:
    value:指定 cookie 的名称。
    required:是否必须有此 cookie。
<a href="anno/textCookieValue">CookieValue</a>

//获取Cookie的值
    @RequestMapping("/textCookieValue")
    public String textCookieValue(@CookieValue(value = "JSESSIONID") String cookieValue){
        System.out.println("执行了");
        System.out.println(cookieValue);
        return "success";
    }
  1. ModelAttribute
  • 作用:
    该注解是 SpringMVC4.3 版本以后新加入的。它可以用于修饰方法和参数
    出现在方法上,表示当前方法会在控制器的方法执行之前,先执行。它可以修饰没有返回值的方法,也可以修饰有具体返回值的方法。
    出现在参数上,获取指定的数据给参数赋值。
  • 属性:
    value:用于获取数据的 key。key 可以是 POJO 的属性名称,也可以是 map 结构的 key。
  • 应用场景:
    当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据。
    例如:
    我们在编辑一个用户时,用户有一个创建信息字段,该字段的值是不允许被修改的。在提交表单数据是肯定没有此字段的内容,一旦更新会把该字段内容置为 null,此时就可以使用此注解解决问题。
//ModelAttribute注解
    @RequestMapping("/textModelAttribute")
    //1 带返回值user
    public String textModelAttribute(User user){
    //2 不带返回值,从map中取数据
    //public String textModelAttribute(@ModelAttribute(value = "abc") User user){
        System.out.println("textModelAttribute执行了...");
        System.out.println(user);
        return "success";
    }

//1 ModelAttribute 修饰方法带返回值 
@ModelAttribute //修饰方法,优先执行
    public User showUser(String uname){
        System.out.println("showUser执行...");
        //通过用户名查询数据库
        User user = new User();
        user.setUname(uname);
        user.setAge(20);
        user.setDate(new Date());
        return user;
    } 


//2 修饰方法,无返回值
@ModelAttribute 
    public void showUser(String uname, Map<String,User> map){
        System.out.println("showUser执行...");
        //通过用户名查询数据库
        User user = new User();
        user.setUname(uname);
        user.setAge(20);
        user.setDate(new Date());
        map.put("abc",user);
    }
  1. SessionAttribute
  • 作用:用于多次执行控制器方法间的参数共享
  • 属性:
    value:用于指定存入的属性名称
    type:用于指定存入的数据类型。
<a href="anno/textSessionAttribute">SessionAttribute</a>
<a href="anno/getSessionAttribute">getSessionAttribute</a>
<a href="anno/delSessionAttribute">delSessionAttribute</a>


//修饰在类上
@SessionAttributes(value = {"msg"}) //把msg=美美存入到session域中
public class AnnoController {
	...
	//SessionAttribute注解
    @RequestMapping("/textSessionAttribute")
    public String textSessionAttribute(Model model){
        System.out.println("执行了SessionAttribute");
        //底层会存储到request域中
        model.addAttribute("msg","美美");
        return "success";
    }

    //获取session值
    @RequestMapping("/getSessionAttribute")
    public String getSessionAttribute(ModelMap modelMap){
        System.out.println("getSessionAttribute...");
        String msg = (String) modelMap.get("msg");  //从session取值
        System.out.println(msg);    //美美
        return "success";
    }

    //清除session
    @RequestMapping("/delSessionAttribute")
    public String delSessionAttribute(SessionStatus status){
        System.out.println("delSessionAttribute...");
        status.setComplete();   //设置完成,清除session
        return "success";
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值