目录
细节:Tomcat默认不能进行delete和put,需要修改 readonly 属性;具体教程
0、写在前面
原文:SpringMVC【入门】篇_Mr.东方老赢的博客-CSDN博客
SpringMVC1
-
什么是SpringMVC?
-
概念
Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的Spring MVC框架或集成其他MVC开发框架,如Struts1(现在一般不用),Struts 2(一般老项目使用)等。-
Model(模型):数据模型,提供要展示的数据,因此包含数据和行为,可以认为是领域模型或 JavaBean 组件(包含数据和行为),不过现在一般都分离开来:Value Object(数据) 和 服务层(行为)。也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。
-
View(视图):负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西。
-
Controller(控制器):接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型数据返回给视图,由视图负责展示。
-
-
三层框架
-
SpringMVC运行原理
-
-
SpringMVC入门
- 搭建开发环境
- Tomcat下载及安装教程
- 第一步,创建工程:正常创建maven工程,选择webapp(注意是maven下的)
- 第二步:创建之后再main下创建java和resources两个文件夹(我这里是直接创建文件夹类型就给定义好了,如果创建出来是普通的文件夹,可以右键文件夹选择
Mark Directory as
然后选择相应类型:java选择Sources Root
,resources选择Resources Root
) - 第三步:在pom.xml中添加依赖
- 第四步:配置web.xml文件(前端配置器)
- 第五步:在resources文件夹下创建配置文件
- 编写入门程序
- 首先在index.jsp文件中添加一个超链接标签用于跳转
- 然后新建一个
controller
类:方法返回值可做跳转页面的文件名 - 在
springmvc.xml
主配置文件中进行配置
在WEB-INF
下创建文件夹pages
,并在pages
中创建跳转页面success.jsp
- 配置web.xml
- 开启tomcat运行测试,运行结果
运行原理解析
- 首先在index.jsp文件中添加一个超链接标签用于跳转
补充:请求参数的绑定(非常重要) - 搭建开发环境
1. 请求参数邦定入门
/*param.jsp*/
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="param/testParam?username=user&password=123456">请求参数绑定</a>
</body>
</html>
package it.mvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @Author: 东方老赢
* @Date: 2020/4/19 14:18
*/
@Controller
@RequestMapping("param")
public class ParamController {
@RequestMapping("testParam")
public String testParam(String username,String password){
System.out.println("执行了");
System.out.println(username);
System.out.println(password);
return "success";
}
}
运行结果
2. 请求参数绑定实体类型
//1.创建user实体类
package it.mvc.domain;
import java.io.Serializable;
/**
* @Author: 东方老赢
* @Date: 2020/4/19 14:42
*/
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 +
'}';
}
}
//2.创建Account实体类,并引用user实体类
package it.mvc.domain;
import java.io.Serializable;
/**
* @Author: 东方老赢
* @Date: 2020/4/19 14:32
*/
public class Account implements Serializable {
private String username;
private String password;
// 实体类中有引用实体类
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.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;
}
@Override
public String toString() {
return "Account{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", user=" + user +
'}';
}
}
//在ParamController中创建方法,接受参数为实体类
@RequestMapping("saveParam")
public String saveParam(Account account){
System.out.println("执行了");
System.out.println(account);
return "success";
}
<%-- 使用表单提交的方式提交信息 --%>
<body>
<form action="param/saveParam" method="post">
账户<input type="text" name="username"/><br/>
密码<input type="text" name="password"/><br/>
<%-- 实体类中有引用实体类的传参--%>
姓名<input type="text" name="user.uname"/></br>
年龄<input type="text" name="user.age"/></br>
<input type="submit" value="提交">
</form>
</body>
- 测试结果:
在这里如果你输入中文就会发现控制台输出乱码,这时我们就要配置解决中文乱码的过滤器
在主配置文件web.xml中加入下列代码(==注意!!==要写在前端控制器之前,否则排列顺序不对,web-app标签会标红)
<!--配置解决中文乱码的过滤器-->
<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>
- 乱码问题就解决啦
与上述步骤基本一致,这里只展示不同部分
//实体类中引用集合,添加get、set和toString方法
private List<User> list;
private Map<String,User> map;
public List<User> getList() {
return list;
}
public void setList(List<User> list) {
this.list = list;
}
public Map<String, User> getMap() {
return map;
}
public void setMap(Map<String, User> map) {
this.map = map;
}
<form action="param/saveParam" method="post">
账户<input type="text" name="username"/><br/>
密码<input type="text" name="password"/><br/>
<%-- 实体类中有集合传参--%>
姓名<input type="text" name="list[0].uname"/></br>
年龄<input type="text" name="list[0].age"/></br>
姓名<input type="text" name="map['one'].uname"/></br>
年龄<input type="text" name="map['one'].age"/></br>
<input type="submit" value="提交">
</form>
- 运行结果
问题:网页传参都是String格式,而SpringMVC在传参的过程中自动进行了类型转换,但是也有个别案例。
如:默认可转换的日期格式为 yyyy/MM/dd,如果输入日期格式为 yyyy-MM-dd,则会报错
代码编写:(SpringMVC为我们提供了一个接口,用于我们自己编写转换代码)
1.在User实体类中加入Date属性,并添加get、set方法(此处就不展示了)
//2.创建字符串转化类
package it.mvc.utiles;
import org.springframework.core.convert.converter.Converter;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Author: 东方老赢
* @Date: 2020/4/19 17:19
*
* 将字符串转换为指定格式日期
*/
public class StringToDateConverter implements Converter<String, Date> {
@Override
public Date convert(String s) {
if (s == null){
throw new RuntimeException("没有数据!!!");
}
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
try {
return df.parse(s);
} catch (ParseException e) {
throw new RuntimeException("数据类型转换出现错误!!!");
}
}
}
<!--3.在主配置文件springmvc.xml文件中配置-->
<!-- 配置自定义类型转换器-->
<bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<!-- 配置路径-->
<bean class="it.mvc.utiles.StringToDateConverter"></bean>
</set>
</property>
</bean>
<!-- 开启springmvc框架注解支持 手动开启类型转换-->
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"/>
//4.添加转换方法
@RequestMapping("StringToDate")
public String StringToDate(User account){
System.out.println("执行了");
System.out.println(account);
return "success";
}
//5.表单提交测试
<form action="param/StringToDate" method="post">
账户<input type="text" name="uname"/><br/>
密码<input type="text" name="age"/><br/>
生日 <input type="text" name="birthday"><br/>
<input type="submit" value="提交">
</form>
- 运行通过说明你成功啦!
细节:怎么通过SpringMVC获取Servlet原生API
<%--1.编写超链接--%>
<a href="param/getServlet">获取servlet原生API</a>
/**
* 2.获取Servlet原生API
* @param request
* @param response
* @return
*/
@RequestMapping("getServlet")
public String getServlet(HttpServletRequest request, HttpServletResponse response){
System.out.println("执行了");
System.out.println(request);
HttpSession session = request.getSession();
System.out.println(session);
ServletContext servletContext = session.getServletContext();
System.out.println(servletContext);
System.out.println(response);
return "success";
}
- 运行结果:
作用:把请求中指定名称的参数给控制器形参赋值(即网页传参名称与方法中参数名不一致时可用)
属性:
- value:请求参数中的名称
- required:请求参数中是否必须提供此参数。默认值为true。表示必须提供,不提供会出错
<a href="anno/testRequestParam?name=haha">testRequestParam</a>
@RequestMapping("/testRequestParam")
public String testRequestParam(String username){
System.out.println(username);
return "success";
}
运行结果:
细节:当添加了注解之后,网页传参的参数名称必须与注解中的一致,否则会报错
作用:用于获取请求体内容。直接使用得到的是 key=value&key=value结构的数据(get方式不适用)
属性:
- required:是否必须有请求体,默认为true。 当取值为true时,get请求方式会报错。如果取值为false,get请求得到的是null
<form action="anno/testRequestBody" method="post">
用户:<input type="text" name="username"><br/>
密码:<input type="text" name="password"><br/>
<input type="submit" value="提交">
</form>
@RequestMapping("/testRequestBody")
public String testRequestBody(@RequestBody String body){
System.out.println(body);
return "success";
}
运行结果:
作用:用于绑定url中的占位符。例如:请求url中/delete/{id},这个{id}就是占位符。(url支持占位符是spring3.0之后加入的,是springmvc支持restful风格url的一个重要标志)
属性:
- value:用于指定url中占位符的位置
- required:是否必须提供占位符
<a href="anno/testPathVariable/10">testPathVariable</a>
@RequestMapping("/testPathVariable/{sid}")
public String testPathVariable(@PathVariable(name = "sid") String id){
System.out.println(id);
return "success";
}
运行结果:
- 作用:由于浏览器form表单只支持get与post请求,而default、put等method并不支持,spring3.0添加了一个过滤器,可以将浏览器请求改为指定的请求方式,发送给我们的控制器方法,使得支持get、post、put与delete请求
- 使用方法:
- 第一步:在web.xml中设置过滤器
- 第二步:请求方式必须使用post请求
- 第三步:按照要求提供_method请求参数,该参数的取值就是我们需要的请求方式
作用:用于获取请求消息头
属性:
- value:提供消息头名称
- required:是否必须有此消息头
注:使其开发中一般不用
<a href="anno/testRequestHeader">testRequestHeader</a>
@RequestMapping("/testRequestHeader")
public String testRequestHeader(@RequestHeader(value = "Accept") String header){
System.out.println(header);
return "success";
}
运行结果
作用:用于把指定cookie名称的值传入控制器方法参数
属性:
- value:指定cookie的名称
- required:是否必须有cookie
<a href="anno/testCookieValue">testCookieValue</a>
@RequestMapping("/testCookieValue")
public String testCookieValue(@CookieValue(value = "JSESSIONID") String cookie){
System.out.println(cookie);
return "success";
}
- 运行结果:
作用:该注解是springmvc4.3版本之后加入的,他可以用于修饰方法和参数
- 出现在方法上:表示当前方法会在控制器执行之前执行。它可以修饰没有返回值的方法,也可以修饰有具体返回值的方法
- 出现在参数上,获取指定的数据给参数赋值
属性:
- value:用于获取数据的key。key可以是POJO的属性名称,也可以是map结构的key
应用场景:
- 当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据
例如:我们在编辑一个用户时,用户有一个创建信息的字段,该字段的值是不允许被修改的。在提交表单数据是肯定没有此字段的内容,一旦更新会把该字段内容置为null,此时就可以使用此注解解决问题
<form action="anno/testModelAttribute" method="post">
用户:<input type="text" name="uname"><br/>
密码:<input type="text" name="age"><br/>
<input type="submit" value="提交">
</form>
@RequestMapping("/testModelAttribute")
public String testModelAttribute(User user){
System.out.println(user);
return "success";
}
/**
* 该方法会先执行,与表单提交重复的内容会被表单覆盖,表单没有的内容原封不动的传上去
* @param uname
* @return
*/
@ModelAttribute
public User showUser(String uname){
System.out.println("showUser执行了");
//通过用户名查询数据库(模拟)
User user = new User();
user.setUname(uname);
user.setAge(20);
user.setBirthday(new Date());
return user;
}
@RequestMapping("/testModelAttribute")
public String testModelAttribute(@ModelAttribute("abc") User user){
System.out.println(user);
return "success";
}
/**
* 未带参数的方法需要添加到 map中
* @param uname
* @param map
*/
@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.setBirthday(new Date());
map.put("abc",user);
}
运行效果:表单只提交了两项,覆盖掉了showUser()方法中的相同参数的两项,方法中未重复的日期参数则会原封不动的传上去
作用:用于多次执行控制器方法间的参数共享
属性:
- value:用于指定存入的属性名称
- type:用于指定存入的数据类型
/**
* 存入session
* @param model
* @return
*/
@RequestMapping("/testSessionAttributes")
public String testSessionAttributes(Model model){
model.addAttribute("msg","东方老赢");
return "success";
}
/**
* 获取session
* @return
*/
@RequestMapping("/getSessionAttributes")
public String getSessionAttributes(ModelMap modelmap){
String msg = (String) modelmap.get("msg");
System.out.println(msg);
return "success";
}
/**
* 删除session
* @return
*/
@RequestMapping("/delSessionAttributes")
public String delSessionAttributes(SessionStatus status){
status.setComplete();
return "success";
}
<a href="anno/testSessionAttributes">testSessionAttributes</a>
<a href="anno/getSessionAttributes">getSessionAttributes</a>
<a href="anno/delSessionAttributes">delSessionAttributes</a>
运行:
SpringMVC第二篇
-
响应数据和结果视图
/** * 使用Model * @param model * @return */ @RequestMapping("/testModel") public String testModel(Model model){ User user = new User(); user.setUsername("东方老赢"); user.setPassword("123456"); user.setAge(20); model.addAttribute(user); return "success"; } /** * 使用jsp */ @RequestMapping("/testVoid") public void testVoid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //编写请求转发的程序 // request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response); //重定向(重定向无法请求/WEB-INF/pages中的jsp文件) // response.sendRedirect(request.getContextPath()+"/response.jsp"); //设置中文乱码 response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); //直接会进行响应 response.getWriter().print("东方老赢"); return; } /** * 使用ModelAndView */ @RequestMapping("/testModelAndView") public ModelAndView testModelAndView(){ ModelAndView mv = new ModelAndView(); User user = new User(); user.setUsername("东方老赢"); user.setPassword("123456"); user.setAge(20); mv.addObject("user",user); mv.setViewName("success"); return mv; }
@RequestMapping("/testForwardOrRedirect") public String testForwardOrRedirect(){ //请求的转发 // return "forward:/WEB-INF/pages/success.jsp"; //重定向 return "redirect:/response.jsp"; }
-
在webapp下创建js文件夹,导入jquery.min.js
-
导入json需要的jar包
<!-- json字符串与Javabean对象相互转换过程中,需要用到jackson的jar包--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.9.0</version> </dependency>
-
编写JavaScript代码
-
编写controller代码,模拟服务器响应
/** * @RequestBody:服务器接收到的json格式的数据解析成实体类型 * @ResponseBody:服务器响应时将返回的数据解析成json格式 * * @param user * @return */ @RequestMapping("/testAjax") public @ResponseBody User testAjax(@RequestBody User user){ //客户端发送ajax请求,传的是ajax字符串,后端把json字符串封装到user对象中 System.out.println(user); //做响应,模拟查询数据库 user.setUsername("东方老赢"); user.setPassword("654321"); user.setAge(25); return user; }
- SpringMVC实现文件上传
-
-
- form表单的enctype取值必须是:multipart/form-data(enctype:是表单请求正文的类型)
- method的属性取值必须是Post
- 提供一个文件选择域 <input type=“ file ”/>
-
当form表单的enctype取值不是默认值之后,request.getParameter( ) 将失效
enctype = “application/x-www-from-urlencoded”(即默认值)时,form表单的正文内容是:- key = value&key = value&key = value
当form表单的enctype取值为 multipart/form-data 时,请求正文的内容就变成
- 每一部分都是MIME类型描述的正文
================================7de1a433602ac 分界符
Content- Disposition:form-data;name=“userName” 协议头
aaaa 协议正文
================================7de1a433602ac 分界符
Content- Disposition : form-data ; name = “file”;filename = “C:\xxx\xxx\b.txt”
Content-Type:text/plain 协议类型(MIME类型)
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
================================7de1a433602ac
借助第三方组件实现文件上传: commons-fileupload-x.x.x.jar、commons-io-x.x.jar
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency>
<form action="user/fileupload1" method="post" enctype="multipart/form-data"> 浏览文件<input type="file" name="upload"/><br/> <input type="submit" value="上传"/> </form>
@RequestMapping("/fileupload1") public String fileupload1(HttpServletRequest request) throws Exception { System.out.println("成功执行 传统文件上传"); //使用fileupload组件完成文件上传 //上传的位置 String path = request.getSession().getServletContext().getRealPath("/uploads/"); System.out.println(path); //判断该路径是否存在 File file = new File(path); //不存在则创建该文件夹(在工程target文件夹下) if (!file.exists()){ file.mkdirs(); } //解析request对象,获取上传文件项 DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); //解析requesth得到一个list集合 List<FileItem> items = upload.parseRequest(request); System.out.println(items); //遍历 for (FileItem item : items) { //进行判断,当前item对象是否是上传文件项 if (item.isFormField()){ //为true,书名普通表单项 System.out.println("普通表单项"); }else { //为false说明上传文件项 //获取上传文件的名称 System.out.println("上传文件项"); String name = item.getName(); System.out.println(name); //完成文件上传 item.write(new File(path,name)); //删除临时文件 item.delete(); } } return "success"; }
-
添加jar包
<!-- 允许跨服务器上传文件--> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-core</artifactId> <version>1.18.1</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-client</artifactId> <version>1.18.1</version> </dependency> </dependencies>
-
添加新表单
-
创建新工程模拟图片服务器,并部署tomcat测试是否成功
-
Controller代码
@RequestMapping("/fileupload3") public String fileupload3(MultipartFile upload) throws Exception { System.out.println("成功执行 Springmvc跨服务器文件上传"); String path = "http://localhost:9090/fileupload_war/uploads/"; //获取上传文件的名称 String name = upload.getOriginalFilename(); //创建客户端的对象 Client client = Client.create(); //和图片服务器进行连接 WebResource webResource = client.resource(path+name); //完成文件上传 webResource.put(upload.getBytes()); return "success"; }
-
运行测试即可
细节:Tomcat默认不能进行delete和put,需要修改 readonly 属性;具体教程
-
SpringMVC的异常处理Controller调用service,service调用dao,异常都是向上抛出的,最终有DispatcherServlet找异常处理器进行一场的处理
-
编写自定义异常类(做提示信息)
package com.mvc.exception; /** * @Author: 东方老赢 * @Date: 2020/4/23 11:02 */ public class SysException extends Exception { //存储提示信息 private String message; @Override public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public SysException(String message) { this.message = message; } }
-
编写异常处理器
-
配置异常处理器
<!-- 配置异常处理器--> <bean id="sysExceptionResolver" class="com.mvc.exception.SysExceptionResolver"></bean>
- 1
- 2
-
-
SpringMVC中的拦截器SpringMVX中的拦截器类似于Servlet中的过滤器Filter,用于对处理器进行预处理和后处理
谈到拦截器,还要提一个词——拦截器链(Interceptor Chain)。拦截器链就是将拦截器按一定顺序联结成一条链。在访问被拦截的方法和字段之时,拦截器链中的拦截器就会按其之前定义的顺序被调用
拦截器预过滤器的区别:- 过滤器是servlet规范中的一部分,任何java web工程都可以用
- 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
- 过滤器在url-patten 中配置 /* 之后,可以对所有要访问的资源进行拦截。
- 拦截器只会拦截访问的控制器的方法,如果访问的是 jsp、html、css、image或者js是不会进行拦截的
- 细节:他也是AOP思想的具体应用
- 想要自定义拦截器,必须要求实现:HandlerInterceptor接口
-
自定义拦截器的步骤
- 编写自定义拦截器
package com.mvc.interceptor; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @Author: 东方老赢 * @Date: 2020/4/23 18:01 */ public class MyIntercepter1 implements HandlerInterceptor { /** * 预处理,controller方法执行前 * return true:放行,执行下一个拦截器。如果没有,执行conroller方法 * return false:不放行 * * @param request * @param response * @param handler * @return * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("Interceptor运行成功"); return true; } }
- 配置拦截器(springmvc.xml)
<!--配置拦截器--> <mvc:interceptors> <!--配置单个拦截器--> <mvc:interceptor> <!--要拦截的具体方法 path = /user/* 表示拦截当前类下的所有方法 path = /** 表示拦截所有方法--> <mvc:mapping path="/user/*"/> <!--不要拦截的方法--> <!--<mvc:exclude-mapping path=""/>--> <!--配置拦截器对象--> <bean class="com.mvc.interceptor.MyIntercepter1"></bean> </mvc:interceptor> </mvc:interceptors>
运行测试
- preHandle:是controller方法执行之前拦截的方法
- 可以使用request或者response跳转到指定页面
- return true放行,执行下一个拦截器,如果没有拦截器,则直接执行controller中的方法
- return false 不放行,不会执行controller中的方法
- postHandle:是controller方法执行后执行的方法,在JSP视图执行前
- 可以使用request或者response跳转到指定页面
- 如果指定了跳转的页面,那么controller方法跳转的页面将不会显示
第三篇 重头戏:SSM整合
-
首先创建一个数据库
CREATE TABLE ssm( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(20), money DOUBLE );
-
创建Maven工程,导包
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <spring.version>5.0.2.RELEASE</spring.version> <mysql.version>5.1.6</mysql.version> <mybatis.version>3.4.5</mybatis.version> </properties> <dependencies> <!-- spring--> <!--AOP相关技术--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.6.8</version> </dependency> <!--AOPjar包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <!--context容器--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <!--mvc相关jar包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!--单元测试--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <!--事务--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <!--JDBC技术--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <!--单元测试--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>compile</scope> </dependency> <!--Mysql驱动jar包--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> <!--Servlet相关jar包--> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> <!--页面 el、jstl表达式--> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- log strat--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.12</version> </dependency> <!-- log end--> <!--Mybatis相关jar包组件--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <!--spring整合mybatis所需jar包--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.0</version> </dependency> <!--数据库连接池:c3p0--> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.1</version> <type>jar</type> <scope>compile</scope> </dependency> </dependencies>
-
搭建环境
-
-
配置文件:
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 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/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 开启注解扫描 只需要处理service和dao--> <context:component-scan base-package="com.ssm"> <!-- 配置哪些注解不扫描--> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> </beans>
-
编写代码测试
@Service("accountService") public class AccountServiceImpl implements IAccountService { @Override public List<Account> findAll() { System.out.println("业务层,查询所有。。。"); return null; } @Override public void saveAccount(Account account) { System.out.println("业务层,保存账户。。。"); } }
public class TestSpring { @Test public void run1(){ ApplicationContext ac = new ClassPathXmlApplicationContext("SpringConfig.xml"); IAccountService accountService = (IAccountService) ac.getBean("accountService"); accountService.findAll(); } }
运行结果:通过
-
-
-
首先编写SpringMVC框架(详情见上)
- 细节:springmvc.xml配置注解扫描
<!-- 开启注解扫描,只扫描Controller注解--> <context:component-scan base-package="com.ssm"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
-
然后开始整合
<!-- 配置spring的监听器,默认只加载WEB-INF目录下的配置文件--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 但是由于SpringConfig.xml配置文件不在WEB-INF目录下,所以需要指定路径--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:SpringConfig.xml</param-value> </context-param>
@Controller @RequestMapping("/account") public class AccountController { @Autowired private IAccountService accountService; @RequestMapping("/findAll") public String findAll(){ System.out.println("表现层:查询所有。。。"); accountService.findAll(); return "success"; } }
-
运行结果
-
-
-
首先编写Mybatis框架,详情见:如果你读完这篇文章,恭喜你!你的Mybatis入门了!
-
测试通过后开始整合(在SpringConfig.xml中整合)
<!--Spring整合Mybatis框架--> <!--配置连接池--> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring"></property> <property name="user" value="root"></property> <property name="password" value="123456"></property> </bean> <!--配置SqLSessionFactory工厂--> <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> </bean> <!--配置AccountDao接口所在包--> <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.ssm.dao"></property> </bean>
@Service("accountService") public class AccountServiceImpl implements IAccountService { @Autowired private IAccountDao accountDao; @Override public List<Account> findAll() { System.out.println("业务层,查询所有。。。"); return accountDao.findAll(); } @Override public void saveAccount(Account account) { System.out.println("业务层,保存账户。。。"); accountDao.saveAccount(account); } }
@Controller @RequestMapping("/account") public class AccountController { @Autowired private IAccountService accountService; @RequestMapping("/findAll") public String findAll(Model model){ System.out.println("表现层:查询所有。。。"); List<Account> list = accountService.findAll(); model.addAttribute("list",list); return "success"; } }
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>Title</title> </head> <body> 成功 <c:forEach items="${list}" var="account"> ${account.name} ${account.money} </c:forEach> </body> </html>
运行结果:
-