注:学习笔记,比较杂乱
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>