注:学习笔记,比较杂乱

Spring MVC业务处理流程

DAO层、Service层和Controller层

1、DAO层

数据访问层(data access object),具体到对某张表的增删改查,某一DAO一定对应着数据库中的某张表。在DAO层应该只做增删改查操作。

2、Service层

服务层,对一个或多个DAO的再次封装,封装成一个服务。需要进行事务控制。

3、Controller层

负责请求转发,接受页面发过来的参数,传递给Service处理,接到返回结果在传递给页面。

总结:DAO面向表,Service面向业务。后端开发时先设计出数据库中的表,再针对每一张表设计出DAO层,然后根据具体的业务逻辑进一步把DAO封装成Service层,对外提供一个服务。

 

 SpringMVC开发环境搭建——IDEA版(Maven)

1、使用Maven创建项目

左侧选择“Maven”,在右侧勾选“Create from archetype(意思是从原型创建)”,在左侧原型列表中找到“maven-archetype-webapp ”并选中,点击Next。不要忘记选择合适的SDK。

 输入Name(项目名)和GroupId(一般是公司名),点击Next。

 设置Maven属性。在Properties里添加一组键值对“archetypeCatalog-internal”,解决maven项目创建过慢的问题。点击finish。

 2、补全目录结构。Maven项目的目录结构是固定的,但是创建出来的项目目录结构是不全的,所以需要手动补全。在src-main目录上右键,new-Directory,在弹出的窗口选择Java,添加Java目录;再用同样的方式添加resources目录(IDEA2020.1.2版本,不能这么添加的可以手动输入java和resources添加,然后右键java目录“Make Directory as --Source Root”;右键resources目录“Make Directory as --Resources Root)。

  =======>>>   

 

3、修改项目pom.xml配置文件,引入SpringMVC依赖。将<maven.compiler.source>和<maven.compiler.target>两个标签中的内容改为使用的JDK版本。并添加<Spring.Version>标签。如下所示。

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>14</maven.compiler.source>
    <maven.compiler.target>14</maven.compiler.target>
    <spring.version>5.0.2.RELEASE</spring.version>
  </properties>

在项目pom.xml文件的<dependencies>标签内填入以下代码:

<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
      <scope>provided</scope>
    </dependency>

4、配置SpringMVC的配置文件。在第2步创建的resources文件夹上New-XML Configuration File-Spring Config,命名为SpringMVC(名字随便取,叫SpringMVC便于识别)

5、配置前端控制器(即servlet)。在src—main—webapp—WEB-INF—web.xml文件内的<web-app>标签内添加以下代码。其中,<servlet-class>标签内的org.springframework.web.servlet.DispatcherServlet是固定的,<url-pattern>内的/表示拦截所有请求。两个<xxx-name>标签内可以随便填写,一般填写类的小写名称。

<!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>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:SpringMVC.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

</web-app>

6、部署服务器。点击右上角“Add Configuration”,点击弹出的窗口左上角的加号,选择tomcat,然后选择Deployment选项卡,点击右侧的加号,选择Artifact,在选择“项目名:war”,删掉“Application Context”中的内容(也可以不删,如果不删的话项目中的链接都要在前面加上Application Context里的内容,我这里没删,应该加上/SpringMVCLearn_war),点击OK,再点击OK。

 编写入门程序

1、删掉src—main—webapp目录下的index.jsp,新建index.html文件

 2、先在index.html文件的body标签内添加一个<h2>和<a>标签,<a>标签的href属性先留空。代码如下:

<body>
<h2>入门程序</h2>
<a href="">入门程序</a>
</body>

3、创建后台类。在src—main—java目录下新建controller文件夹,创建一个 名为HelloController的类。

====>>>

 4、在HelloController类上添加注解@Controller,将其标记为Controller。添加一个名问sayHello的方法,并添加注解@RequestMapping(path = "/hello")

package controller;

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

//控制器类
@Controller
public class HelloController { @RequestMapping(path = "/hello") //url应为“/SpringMVCLearn_war/hello”,如果Application Context内的内容删掉了,则url为“/hello” public String sayHello() { System.out.println("Hello SpringMVC"); return "success"; } }

5、在webapp目录下新建一个名为HTML的文件夹,存放.html文件。在新建的HTML文件夹内新建一个名为success.html的文件,随便写点东西。

6、修改SpringMVC.xml配置文件,开启注解扫描,并指定视图解析器的寻找路径。在SpringMVC.xml文件内添加以下代码:

<?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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--开启注解扫描-->
    <context:component-scan base-package="controller"></context:component-scan>

    <!-- 默认的注解映射 -->
    <mvc:annotation-driven />

    <!-- 解除servlet对静态资源文件访问的限制,使得静态资源先经过,必须设置,不然启动时无法访问主页-->
    <mvc:default-servlet-handler />

    <!--视图解析器对象:class是固定的-->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--寻找视图的路径 此处要与上一步创建的文件夹路径严格对应起来!!!!!!!-->
        <property name="prefix" value="/HTML/" /> 
        <!--寻找文件的后缀名-->
        <property name="suffix" value=".html" />
    </bean>

</beans>

7、在index.html的<a>标签的href属性内写入“/SpringMVCLearn_war/hello”。

 8、点击右上角启动按钮启动。

 

 注解

RequestMapping注解

作用:建立请求url和处理请求方法之间的对应关系

常用属性:

  value与path:作用相同,指定映射路径。如果只用了RequestMapping注解的一个属性,可以省略参数名只写路径名

  method:指定请求方式。RequestMethod枚举类

  params:用于指定限制请求参数的条件,支持简单的表达式。要求请求参数的key和value必须和配置的一模一样

    例如:

      params={“accountName”},表示请求中必须有accountName

      params={“money!100”},表示请求参数中money不能是100

  headers:用于指定限制请求消息头的条件

  注意:以上4个属性同时出现2个或以上时,它们之间是与的关系,即必须同时成立。

RequestParam注解

作用:把请求中指定名称的参数给控制器中的形参赋值

常用属性:

  value:请求参数中的名称

  required:请求参数中是否必须提供此参数。默认值:true,表示必须提供,如果不提供将报错。

  例如:

<a href="/hello?name=hahaha"></a>
    @RequestMapping(path = "/hello")
    public String sayHello(@RequestParam("name") String userName) {
        System.out.println(userName);
        return "success";
    }

RequestBody注解

作用:用于获取请求体的内容。直接使用得到的是key=value&key=value……结构的数据。不适用于get请求,因为get请求没有请求体。

属性:

  required:是否必须有请求体。默认值是:true。当取值为true时,get请求方式会报错。如果取值为false,get请求得到null。

ResponseBody注解

作用:将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML。可用于类和方法。

PathVariable注解

作用:用于绑定url中的占位符。例如:请求url中/delete/{id},这个{id}就是url占位符。url支持占位符是Spring3.0之后加入的,是SpringMVC支持rest风格URL的重要标志。

属性:

  name和value:用于指定url中占位符的名称。

  required:指定是否必须提供占位符。

  例如:

<a href="/PathVariable/10">PathVariable注解</a>
    @RequestMapping("/PathVariable/{id}")
    public String testPathVariable(@PathVariable(name = "id") String id) {
        System.out.println(id);
        return "success";
    }

上述代码后台会输出"10"

RequestHeader注解

作用:用于获取请求消息头。(一般用不到此注解)

属性:

  value:提供消息头名称。

  required:是否必须有此消息头。

CookieValue注解

作用:用于把指定cookie名称的值传入控制器方法参数。

属性:

  value:指定cookie的名称。

  required:指定是否必须有此cookie。

ModelAttribute注解(此注解可能已过期,带查阅资料确定)

作用:该注解是SpringMVC4.3版本引入的,它可以用于修饰方法和参数。该注解修饰方法时,表示当前方法会在控制器的方法执行之前先执行。它可以修饰没有返回值的方法,也可以修饰有返回值的方法。出现在参数上时,获取指定的数据给参数赋值。

属性:

  value:用于获取数据的key。key可以是POJO的属性名称,也可以是map结构的key。

应用场景:

  当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据。

  例如:

    我们在编辑一个用户时,用户有一个创建信息字段,该字段的值是不允许被修改的。在提交表单时肯定没有此字段的内容,一旦更新会把该字段内容置为null,此时就可以使用此注解解决问题。

SessionAttributes注解(在html中不太好用,待解决或寻找其他方式,例如Ajax)

作用:用于多次执行控制器方法间的参数共享

属性:

  value:用于指定存入的属性名称。

  type:用于指定存入的数据类型。

请求参数的绑定

 1、后台方法会自动接收传递的url中与方法参数名相同的参数,例如:

    @RequestMapping("paramsTest")
    public String ParamsMethod(String user,String pwd){
        /**/
        System.out.println(user);
        System.out.println(pwd);
        return null;
    }

如果传递过来的url为“***/paramsTest?user=song&pwd=123456,则后台会打印song(即user)和123456(即pwd)

2、使用JavaBean绑定

java类:

package domain;

import java.io.Serializable;

public class Account implements Serializable {
    private String userName;
    private String password;
    private double money;

    private User user;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public String toString() {
        return "Account{" +
                "userName='" + userName + '\'' +
                ", password='" + password + '\'' +
                ", money=" + money +
                ", user=" + user +
                '}';
    }
}
/**
 * @author :宋庆国
 * @date :Created in 2020/7/5 21:37
 * @modified By:
 */
package domain;

import java.io.Serializable;

public class User implements Serializable {
    private String uname;
    private Integer age;

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "uname='" + uname + '\'' +
                ", age=" + age +
                '}';
    }
}

页面表单:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h2>JavaBean参数绑定</h2>
<form action="/saveAccount" method="post">
    姓名:<input type="text" name="userName"/><br> <!--name的值严格对应Account类的属性名-->
    密码:<input type="text" name="password"/><br>
    金额:<input type="text" name="money"/><br>
    用户姓名:<input type="text" name="user.uname"/><br>  <!--Account类中还有个User引用类型的实例,要想给这个User类传递参数,应使用此类"实例名.属性名"-->
    用户年龄:<input type="text" name="user.age"/><br>
    <input type="submit" value="提交"/>
</form>
</body>
</html>

Controller类:

package controller;

import domain.Account;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class ParamsBind {
    /*
     * 请求参数绑定,把数据封装到JavaB的类中
     *
     * */
    @RequestMapping("/saveAccount")
    public String saveAccount(Account account) {
        System.out.println(account.toString());
        return "success";
    }
}

配置解决中文乱码的过滤器

在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>