1.简介
1.1 MVC
-
MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。
-
是将业务逻辑、数据、显示分离的方法来组织代码。
-
MVC主要作用是降低了视图与业务逻辑间的双向偶合。
-
MVC不是一种设计模式,MVC是一种架构模式。当然不同的MVC存在差异。
职责分析:
Controller:控制器
-
取得表单数据
-
调用业务逻辑
-
转向指定的页面
Model:模型
-
业务逻辑
-
保存数据的状态
View:视图
-
显示页面
1.2 SpringMVC简介
官方文档:https://docs.spring.io/spring-framework/reference/web/webmvc.html
1.2.1 概念
Spring MVC是Spring的一部分,是基于Java实现MVC的轻量级Web框架。Spring MVC也叫
Spring Web MVC 主要应用在web开发中。
Spring MVC是基于servlet设计的,底层还是调度servlet,其核心是DispatchServlet。
1.2.2 优势
-
轻量级,简单易学
-
高效 , 基于请求响应的MVC框架
-
与Spring兼容性好,无缝结合
-
约定优于配置
-
功能强大:RESTful、数据验证、格式化、本地化、主题等
-
简洁灵活
最重要的一点还是用的人多 , 使用的公司多。
1.2.3 执行原理
图为SpringMVC的一个较完整的流程图,实线表示SpringMVC框架提供的技术,不需要开发者实现,虚线表示需要开发者实现。
1.3 总结
Spring的web框架围绕DispatcherServlet [ 调度Servlet ] 设计。
DispatcherServlet的作用是将请求分发到不同的处理器。从Spring 2.5开始,使用Java 5或者以上版本的用户可以采用基于注解形式进行开发,十分简洁;
正因为SpringMVC好 , 简单 , 便捷 , 易学 , 天生和Spring无缝集成(使用SpringIoC和Aop) , 使用约定优于配置 . 能够进行简单的junit测试 . 支持Restful风格 .异常处理 , 本地化 , 国际化 , 数据验证 , 类型转换 , 拦截器 等等......所以我们要学习 .
2.HelloSpringMVC
1.新建一个普通Maven模型,添加web框架支持
2.配置maven依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>springmvc</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl-api</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.30</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> </dependencies> </project>
3.配置web.xml文件
<?xml version="1.0" encoding="UTF8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 配置DispatchServlet: 这是SpringMVC的核心: 请求分发器,前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- DispatcherServlet要绑定Spring的配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
</servlet>
<!-- 在springMVC中 /和/*有区别,
/:只匹配所有的请求,不会去匹配jsp页面
/* :匹配所有的请求,包括jsp页面 -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
4.编写springMVC的配置文件:springmvc-servlet.xml [根据官方设定],也可以自行设定。
4.1 配置处理器映射器
<!-- 处理器映射器 --> <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
4.2 配置处理器适配器
<!-- 处理器适配器 --> <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
4.3 配置视图解析器
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver"> <!-- 前缀 --> <property name="prefix" value="/WEB-INF/jsp/"/> <!-- 后缀 --> <property name="suffix" value=".jsp"/> </bean>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<!-- 处理器映射器 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!-- 处理器适配器 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!-- 后缀 -->
<property name="suffix" value=".jsp"/>
</bean>
<!-- BeanNameUrlHandlerMapping:bean -->
<bean id="/hello" class="com.heima.controller.HelloController"/>
</beans>
5.配置Controller业务层,可以实现Contorller接口,也可以使用注解
public class HelloController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mv = new ModelAndView();
//业务代码
String result = "HelloSpringMVC!";
mv.addObject("msg",result);
//试图跳转
mv.setViewName("test");
return mv;
}
}
需要返回一个ModelAndView对象, 模型和视图
6.将我们配置的业务层controller交给SpringIOC容器,在springmvc-servelt.xml中注册bean
<!-- Handle -->
<bean id="/hello" class="com.heima.controller.HelloController"/>
7.在WEB-INF目录下创建一个测试目录jsp创建我们要跳转的jsp页面test.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>HeiMa</title>
</head>
<body>
${msg}
</body>
</html>
8.配置Tomcat启动程序
可能遇到的问题:访问出现404,排查步骤:
-
查看控制台输出,看一下是不是缺少了什么jar包。
-
如果jar包存在,显示无法输出,就在IDEA的项目发布中,添加lib依赖!
解决方法:
然后导入所有maven依赖即可
3. 重启Tomcat 即可解决!
3.注解实现servlet配置
3.1 新建一个Model ,springmvc-02-annotation 添加web框架支持
3.2 配置maven依赖,如果存在Maven资源过滤问题,导入配置
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
3.3 编写web.xml配置,配置注册DispatchServlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--1.注册servlet-->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--通过初始化参数指定SpringMVC配置文件的位置,进行关联-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!-- 启动顺序,数字越小,启动越早 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!--所有请求都会被springmvc拦截 -->
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
注意点:
/ 和 /* 的区别:< url-pattern > / </ url-pattern > 不会匹配到.jsp, 只针对我们编写的请求;即:.jsp 不会进入spring的 DispatcherServlet类 。< url-pattern > /* </ url-pattern > 会匹配 *.jsp,会出现返回 jsp视图 时再次进入spring的DispatcherServlet 类,导致找不到对应的controller所以报404错
- 注意web.xml版本问题,要最新版!
- 注册DispatcherServlet
- 关联SpringMVC的配置文件
- 启动级别为1
- 映射路径为 / 【不要用/*,会404】
3.4 配置springMVC配置文件springmvc-servlet.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
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
<context:component-scan base-package="com.heima.controller"/>
<!-- 让Spring MVC不处理静态资源 -->
<mvc:default-servlet-handler />
<!--
支持mvc注解驱动
在spring中一般采用@RequestMapping注解来完成映射关系
要想使@RequestMapping注解生效
必须向上下文中注册DefaultAnnotationHandlerMapping
和一个AnnotationMethodHandlerAdapter实例
这两个实例分别在类级别和方法级别处理。
而annotation-driven配置帮助我们自动完成上述两个实例的注入。
-->
<mvc:annotation-driven />
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 后缀 -->
<property name="suffix" value=".jsp" />
</bean>
</beans>
3.5 创建控制器Controller, 使用注解实现
package com.heima.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController{
//真实访问地址 : 项目名/hello
@RequestMapping("/hello")
public String hello(Model model){
//封装数据
model.addAttribute("msg","HelloAnnotationMVC!");
return "hello";//会被视图解析器处理
}
@RequestMapping("/test")
public String test(Model model){
//封装数据
model.addAttribute("message","这是测试页面test.jsp");
//跳转,即被视图解析器处理后跳转页面
return "test";
}
}
-
@Controller是为了让Spring IOC容器初始化时自动扫描到;
-
@RequestMapping是为了映射请求路径,这里因为类与方法上都有映射所以访问时应该是/HelloController/hello;
-
方法中声明Model类型的参数是为了把Action中的数据带到视图中;
-
方法返回的结果是视图的名称hello,加上配置文件中的前后缀变成WEB-INF/jsp/hello.jsp。
3.6 创建视图层 .jsp 文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
3.7 配置Tomcat服务器启动
使用springMVC必须配置的三大件:
处理器映射器、处理器适配器、视图解析器
通常,我们只需要手动配置视图解析器,而处理器映射器和处理器适配器只需要开启注解驱动即可,而省去了大段的xml配置
4. Controller控制器
-
控制器复杂提供访问应用程序的行为,通常通过接口定义或注解定义两种方法实现。
-
控制器负责解析用户的请求并将其转换为一个模型。
-
在Spring MVC中一个控制器类可以包含多个方法
-
在Spring MVC中,对于Controller的配置方式有很多种
实现Controller接口
controller接口中只有一个方法
//实现该接口的类获得控制器功能
public interface Controller {
//处理请求且返回一个模型与视图对象
ModelAndView handleRequest(HttpServletRequest var1, HttpServletResponse var2) throws Exception;
}
测试:
1.新建一个Model,springmvc-04-controller,添加web框架支持
2.将03中的所有配置copy一份,spingmvc-servlet.xml文件中只留下视图解析器
3.创建一个Controller类,实现Controller接口
package com.heima.controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mv = new ModelAndView();
mv.addObject("msg","Controller接口下的controller");
mv.setViewName("hello");
return mv;
}
}
4.在springmvc-servlet.xml文件中注册bean
<bean id="/hello" class="com.heima.controller.HelloController"/>
5.在WEB-INF目录下创建一个测试目录jsp创建我们要跳转的jsp页面test.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
4. RestMapping
@RequestMapping
-
@RequestMapping注解用于映射url到控制器类或一个特定的处理程序方法。可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
-
为了测试结论更加准确,我们可以加上一个项目名测试 myweb
-
只注解在方法上面
package com.heima.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController2 {
@RequestMapping("/hello2")
public String helloController(Model model){
model.addAttribute("msg","annotation下的controller");
return "hello";
}
}
访问地址为:http://localhost:8080 / 项目名 / hello2
package com.heima.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/Controller3")
public class HelloController3 {
@RequestMapping("/hello3")
public String hello(Model model){
model.addAttribute("msg","RequestMapping中的controller");
return "hello";
}
}
访问地址为:http://localhost:8080 / 项目名 / Controller3/hello2 (不推荐使用)
5. RestFul风格
5.1 概念
Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
5.2 功能
资源:互联网所有的事物都可以被抽象为资源
资源操作:使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作。
分别对应 添加、 删除、修改、查询。更加安全。
5.3 传统方式操作资源 :通过在地址栏传入不同的参数来实现不同的效果!方法单一,post 和 get
package com.heima.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class preMethod {
@RequestMapping("/test")
public String method1(int a, int b, Model model){
int res = a + b;
model.addAttribute("msg","结果为:" + res);
return "test";
}
}
缺点:不安全,参数信息能通过地址栏看到。
5.4 使用RESTful操作资源 :可以通过不同的请求方式来实现不同的效果!
package com.heima.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class RestFul {
//映射访问路径
@RequestMapping("/test2/{a}/{b}")
public String method(@PathVariable int a,@PathVariable String b, Model model){
String res = a + b;
//Spring MVC会自动实例化一个Model对象用于向视图中传值
model.addAttribute("msg","结果为:" + res);
//返回视图位置
return "test";
}
}
通过在参数中加入注解@PathVariable以及@RequestMapping中使用/{参数值1}/{参数值2}实现参数传入。传入方式://http:localhost:8080/test2/1/2
5.5 思考:
使用路径变量的好处?
- 使路径变得更加简洁;
- 获得参数更加方便,框架会自动进行类型转换。
- 通过路径变量的类型可以约束访问参数,如果类型不一样,则访问不到对应的请求方法,如这里访问是的路径是/commit/1/a,则路径与方法不匹配,而不会是参数转换失败。
5.6 使用method属性指定请求类型
用于约束请求的类型,可以收窄请求范围。指定请求谓词的类型如GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE等
//映射访问路径,必须是POST请求
@RequestMapping(value = "/hello",method = {RequestMethod.POST})
public String index2(Model model){
model.addAttribute("msg", "hello!");
return "test";
}
当我们使用浏览器地址栏进行访问默认是Get请求,会报错405:
如果将POST修改为GET则正常了;
//映射访问路径,必须是POST请求
@RequestMapping(value = "/hello",method = {RequestMethod.GET})
public String index2(Model model){
model.addAttribute("msg", "hello!");
return "test";
}
5.7 小结:
Spring MVC 的 @RequestMapping 注解能够处理 HTTP 请求的方法, 比如 GET, PUT, POST, DELETE 以及 PATCH。
5.8 所有的地址栏请求默认都会是 HTTP GET 类型的。
方法级别的注解变体有如下几个:组合注解
@GetMapping @PostMapping @PutMapping @DeleteMapping @PatchMapping
@GetMapping 是一个组合注解,平时使用的会比较多!
它所扮演的是 @RequestMapping(method =RequestMethod.GET) 的一个快捷方式。
6. 结果跳转方式
方式:请求转发【Forward】和重定向【Redirect】
设置ModelAndView对象 , 根据view的名称 , 和视图解析器跳到指定的页面 .
页面 : {视图解析器前缀} + viewName +{视图解析器后缀}
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 后缀 -->
<property name="suffix" value=".jsp" />
</bean>
6.1 通过SpringMVC来实现转发和重定向 - 无需视图解析器;
测试前,需要将视图解析器注释掉
@Controller
public class ResultSpringMVC {
@RequestMapping("/rsm/t1")
public String test1(){
//转发
return "/index.jsp";
}
@RequestMapping("/rsm/t2")
public String test2(){
//转发二
return "forward:/index.jsp";
}
@RequestMapping("/rsm/t3")
public String test3(){
//重定向
return "redirect:/index.jsp";
}
}
6.2 通过SpringMVC来实现转发和重定向 - 有视图解析器;
重定向 , 不需要视图解析器 , 本质就是重新请求一个新地方 , 注意路径问题.
可以重定向到另外一个请求实现 .
@Controller
public class ResultSpringMVC2 {
@RequestMapping("/rsm2/t1")
public String test1(){
//转发
return "test";
}
@RequestMapping("/rsm2/t2")
public String test2(){
//重定向
return "redirect:/index.jsp";
//return "redirect:hello.do"; //hello.do为另一个请求/
}
}
注意:当有视图解析器时,我们使用 return "redirect1:/index.jsp";会将url拼接成一个奇怪的地址
http:localhost:8080/WEB-INF/jsp/redirect1:/index.jsp.jsp
7. 数据处理
6.1 提交的参数是普通类型:
package com.heima.controller;
import com.heima.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
@RequestMapping("user")
public class UserController {
//接收前端用户传递的参数,判断参数的名字.假设名字直接在方法上,可以直接使用
//http://localhost:8080/user/test1?username=xxx;
@GetMapping("/test1")
public String test1(@RequestParam("username") String name, Model model){
//1.接收前端参数
System.out.println("收到前端参数:" + name);
//2.将返回的结果传递给前端,Model
model.addAttribute("msg",name);
//3.视图跳转
return "test";
}
}
7.1.1 提交的域名称和处理方法的参数名一致
提交数据 : http://localhost:8080/user/test1?name=heima
后台输出 : 收到前端参数:heima
7.1.2 提交的域名称和处理方法的参数名不一致
提交数据 : http://localhost:8080/hello?username=heima
后台输出 : 收到前端参数:null
此时我们需要在name参数前加上@RequestParam("username"),
后台输出 : 收到前端参数:heima
但当我们使用 http://localhost:8080/user/test1?name=heima时,会报404错误.
7.2 提交的类型是对象:
要求提交的表单域和对象的属性名一致 , 参数使用对象即可
7.2.1 创建实体类
package com.heima.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private int age;
private String pwd;
}
7.2.2 创建测试类UserController继承Controller
package com.heima.controller;
import com.heima.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
@RequestMapping("user")
public class UserController {
/*
1.接收前端用户传递的参数,判断参数的名字.假设名字直接在方法上,可以直接使用
2.假设传递的是一个对象User,匹配User对象中的字段名,如果名字一致就ok,否则匹配不到
*/
//接收到的是一个对象
@RequestMapping("/test2")
public String test2(User user){
System.out.println(user);
return "test";
}
}
7.2.3 提交数据 : http://localhost:8080/user/test2?name=heima&age=15&pwd=123123
7.2.4 后台输出 :User(name=heima, age=21, pwd=123123)
说明:如果使用对象的话,前端传递的参数名和对象名必须一致,否则就是null。
8.数据显示到前端
第一种 : 通过ModelAndView
我们前面一直都是如此 . 就不过多解释
public class ControllerTest1 implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
//返回一个模型视图对象
ModelAndView mv = new ModelAndView();
mv.addObject("msg","ControllerTest1");
mv.setViewName("test");
return mv;
}
}
第二种 : 通过ModelMap
ModelMap
@RequestMapping("/hello")
public String hello(@RequestParam("username") String name, ModelMap model){
//封装要显示到视图中的数据
//相当于req.setAttribute("name",name);
model.addAttribute("name",name);
System.out.println(name);
return "hello";
}
第三种 : 通过Model
@RequestMapping("/ct2/hello")
public String hello(@RequestParam("username") String name, Model model){
//封装要显示到视图中的数据
//相当于req.setAttribute("name",name);
model.addAttribute("msg",name);
System.out.println(name);
return "test";
}
对比
就对于新手而言简单来说使用区别就是:
Model 只有寥寥几个方法只适合用于储存数据,简化了新手对于Model对象的操作和理解; ModelMap 继承了 LinkedMap ,除了实现了自身的一些方法,同样的继承 LinkedMap 的方法和特性; ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。当然更多的以后开发考虑的更多的是性能和优化,就不能单单仅限于此的了解。
请使用80%的时间打好扎实的基础,剩下18%的时间研究框架,2%的时间去学点英文,框架的官方文档永远是最好的教程。
9. 解决乱码问题
在web.xml文件中配置过滤器CharacterEncodingFilter即可
<!-- 配置springmvc的乱码过滤器 -->
<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的支持不好。另外如果我们要跳转到jsp文件,我们必须在过滤器配置中我们的<url-pattern>/*</url-pattern>,不能是/,因为/不会过来jsp请求。
处理方法:
修改tomcat配置文件 :设置编码! 在tomcat/conf/server.xml下
<Connector URIEncoding="utf-8" port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
10. JSON交互处理
10.1 什么是JSON
json就是一种在各个编程语言中流通的数据格式,负责不同编程语言中的数据传递和交互。
JSON格式:{"name":"admin","age":18}
-
对象表示为键值对,数据由逗号分隔
-
花括号保存对象
-
方括号保存数组
这就是一种最简单的json,如果有学过js的开发者是不是发现json的语法与js中object的语法几乎相同。
但是,注意:
- json是一种纯字符数据,不属于编程语言
- json的语法与js中object的语法几乎一致(下一部分说明不同)
- json数据以键值对形式存在,多个键值对之间用逗号
,
隔开,键值对的键和值之间用冒号:
连接 - json数据在js对象的基础上做了严格化
- json数据中的键值对可以使用编程语言中所谓的关键字(*见注意事项)
- json的数据可以用花括号
{}
或中括号[]
包裹,对应js中的object和array
10.2 JSON和javaScript
关系:JSON 是 JavaScript 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。
var obj = {a: 'Hello', b: 'World'}; //这是一个对象,注意键名也是可以使用引号包裹的
var json = '{"a": "Hello", "b": "World"}'; //这是一个 JSON 字符串,本质是一个字符串
互相转换:parse(JSON --> javaScript)方法和stringify(javaScript --> JSON)方法
stringify方法:
var user = {
name:"黑麻",
age:18,
pwd:123123
};
//调用JSON的stringify方法使javaScript对象转换为JSON字符串
var json = JSON.stringify(user);
console.log(json);
parse方法:
var user = {
name:"黑麻",
age:18,
pwd:123123
};
console.log(user);
console.log("==================");
console.log("==================");
//调用JSON的parse方法使JSON字符串转换为javaScript对象
var obj = JSON.parse(json);
console.log(obj);
代码测试:
创建一个html页面, jsonTest.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript">
var user = {
name:"黑麻",
age:18,
pwd:123123
};
console.log(user);
console.log("==================");
//调用JSON的stringify方法使javaScript对象转换为JSON字符串
var json = JSON.stringify(user);
console.log(json);
console.log("==================");
//调用JSON的parse方法使JSON字符串转换为javaScript对象
var obj = JSON.parse(json);
console.log(obj);
</script>
</head>
<body>
</body>
</html>
输出结果为:
由此看出,JSON就是由{xx:xx}格式组成的字符串
10.3 JSON用法
10.3.1 jackjson
10.3.1 先导入maven配置
<dependencies> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.3</version> </dependency> </dependencies>
10.3.2 解决乱码问题,在springmvc配置文件springmvc-servlet.xml中配置
<mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <constructor-arg value="UTF-8"/> </bean> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="objectMapper"> <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"> <property name="failOnEmptyBeans" value="false"/> </bean> </property> </bean> </mvc:message-converters> </mvc:annotation-driven>
10.3.3 在web.xml文件中配置springmvc默认信息
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--1.注册servlet-->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--通过初始化参数指定SpringMVC配置文件的位置,进行关联-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!-- 启动顺序,数字越小,启动越早 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!--所有请求都会被springmvc拦截 -->
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encoding</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>encoding</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
</web-app>
10.3.4编写一个User的实体类,然后我们去编写我们的测试Controller;
package com.kuang.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
//需要导入lombok
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private int age;
private String pwd;
}
10.3.5 编写一个controller类
package com.heima.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.heima.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
//@RestController = @Controller + @ResponseBody
@Controller
public class UserController {
//创建一个jackson的对象映射器,用来解析数据
@RequestMapping(value = "/json1")
@ResponseBody //它代表方法不会走视图解析器,会直接返回一个字符串
public String json1() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
User user = new User("黑麻", 21, "123123");
//将我们的对象解析成为json格式
String obj = mapper.writeValueAsString(user);
/由于@ResponseBody注解,这里会将str转成json格式返回;十分方便
return obj;
}
}
另外:
1. json还自带另一种处理乱码的配置
通过@RequestMaping的produces属性来实现,修改下代码
//produces:指定响应体返回类型和编码
@RequestMapping(value = "/json1",produces = "application/json;charset=utf-8")
2. 返回json字符串统一解决
在类上直接使用 @RestController ,这样子,里面所有的方法都只会返回 json 字符串了,不用再每一个都添加@ResponseBody !我们在前后端分离开发中,一般都使用 @RestController ,十分便捷!
package com.heima.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.heima.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
//@RestController = @Controller + @ResponseBody
@RestController
public class UserController {
@RequestMapping(value = "/json1")
public String json1() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
User user = new User("黑麻", 21, "123123");
String obj = mapper.writeValueAsString(user);
return obj;
}
}
3.json还提供修改时间格式,可以自行查阅文档,这里就不赘述了...
10.3.2 fastjson
三个核心类
- JSONObject 代表 json 对象
- JSONArray 代表 json 对象数组
- JSON代表 JSONObject和JSONArray的转化
1.导入fastjson依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
2.创建测试类 fastJsonController
package com.heima.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.heima.pojo.User;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
public class FastJsonController {
public static void main(String[] args) {
ArrayList<User> userList = new ArrayList<>();
User u1 = new User("黑麻", 21, "123123");
User u2 = new User("张三", 15, "111222333");
User u3 = new User("李四", 16, "123123");
userList.add(u1);
userList.add(u2);
userList.add(u3);
//java --> json 1
System.out.println("==== java-->json 1====");
String str1 = JSON.toJSONString(userList);
System.out.println(str1);
String str2 = JSON.toJSONString(u1);
System.out.println(str2);
//json --> java 1
System.out.println("==== json-->java 1====");
User json_user1 = JSON.parseObject(str2, User.class);
System.out.println(json_user1);
//java --> json 2
System.out.println("==== json-->java 2====");
JSONObject jsonObject = (JSONObject) JSON.toJSON(u2);
System.out.println(jsonObject);
//json --> java 2
System.out.println("==== json-->java 2====");
User json_user2 = JSON.toJavaObject(jsonObject, User.class);
System.out.println(json_user2);
}
}
11. 整合SSM
11.1 示例:
1 创建新项目
创建一个普通maven项目ssmbuild,导入ssm依赖,添加web框架支持
<dependencies> <!--Junit--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <!--数据库驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <!-- 数据库连接池 --> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency> <!--Servlet - JSP --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!--Mybatis--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.2</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.2</version> </dependency> <!--Spring--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.9.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.1.9.RELEASE</version> </dependency> </dependencies>
2. 解决maven静态资源过滤问题
<build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build>
3. 在 项目结构中创建lib导入依赖
4.建立基本框架以及配置框架
-
com.heima.pojo
-
com.heima.dao
-
com.heima.service
-
com.heima.controller
-
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> </configuration>
-
applicationContext.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> </beans>
5.配置ssm核心配置文件
Mybatis层
1.数据库配置文件 database.properties
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=false&useUnicode=true&characterEncoding=utf8 jdbc.username=root jdbc.password=hsp
2.编写mybatis核心配置文件,mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.heima.pojo"/>
</typeAliases>
<mappers>
<mapper class="com.heima.dao.BookMapper"/>
</mappers>
</configuration>
3.创建实体类Books
package com.heima.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Books {
private String bookID;
private String bookName;
private int bookCounts;
private String detail;
}
4.编写Dao层,Mapper接口
package com.heima.dao;
import com.heima.pojo.Books;
import org.apache.ibatis.annotations.Param;
import java.awt.print.Book;
import java.util.List;
public interface BookMapper {
//增加一本书
int addBook(Books book);
//删除一本书
int deleteBookById(@Param("bookID") int id);
//更新一本书
int updateBook(Books book);
//查询一本书
Books queryBookById(@Param("bookID") int id);
//查询一本书
Books queryBookByName(@Param("bookName") String name);
//查询全部书
List<Books> queryAllBook();
}
5.编写接口对应的xml文件,BookMapper.xml,编写数据库操作
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.heima.dao.BookMapper">
<insert id="addBook" parameterType="Books">
insert into ssmbuild.books(bookID,bookName,bookCounts,detail) values
(#{bookID},#{bookName},#{bookCounts},#{detail});
</insert>
<delete id="deleteBookById" parameterType="int">
delete from ssmbuild.books where bookID = #{bookID};
</delete>
<update id="updateBook" parameterType="Books">
update ssmbuild.books
set bookName=#{bookName},bookCounts = #{bookCounts}, detail = #{detail}
where bookID = #{bookID};
</update>
<select id="queryBookById" resultType="Books">
select * from ssmbuild.books where bookID = #{bookID};
</select>
<select id="queryAllBook" resultType="Books">
select * from ssmbuild.books;
</select>
<select id="queryBookByName" resultType="Books">
select * from ssmbuild.books where bookName=#{bookName};
</select>
</mapper>
6.编写业务层接口Service,
package com.heima.service;
import com.heima.pojo.Books;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface BookService {
//增加一本书
int addBook(Books book);
//删除一本书
int deleteBookById(int id);
//更新一本书
int updateBook(Books book);
//查询一本书
Books queryBookById(int id);
//查询一本书
Books queryBookByName(String name);
//查询全部书
List<Books> queryAllBook();
}
7.编写实现类ServiceImpl,service层调用dao层
package com.heima.service;
import com.heima.dao.BookMapper;
import com.heima.pojo.Books;
import java.util.List;
public class BookServiceImpl implements BookService{
//service层调dao层
private BookMapper bookMapper;
public void setBookMapper(BookMapper bookMapper) {
this.bookMapper = bookMapper;
}
public BookMapper getBookMapper() {
return bookMapper;
}
@Override
public int addBook(Books book) {
return bookMapper.addBook(book);
}
@Override
public int deleteBookById(int id) {
return bookMapper.deleteBookById(id);
}
@Override
public int updateBook(Books book) {
return bookMapper.updateBook(book);
}
@Override
public Books queryBookById(int id) {
return bookMapper.queryBookById(id);
}
@Override
public Books queryBookByName(String name) {
Books books = bookMapper.queryBookByName(name);
System.out.println("=====>" + books);
return books;
}
@Override
public List<Books> queryAllBook() {
return bookMapper.queryAllBook();
}
}
至此,我们完成了mybatis的工作
Spring层
1.整合Mybatis中的配置,使用数据库连接池c3p0
2.编写Spring整合Mybatis的相关的配置文件;spring-dao.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 1.关联数据库配置文件 -->
<context:property-placeholder location="classpath:database.properties"/>
<!-- 2.连接池 -->
<bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- 3.sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="datasource"/>
<!-- 绑定mybatis的配置文件 -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!-- 配置dao接口扫描包,动态的实现了Dao接口库可以注入到Spring容器中! -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 注入sqlSessionFactory -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!-- 要扫描的dao包 -->
<property name="basePackage" value="com.heima.dao"/>
</bean>
</beans>
这里注意,我们在注入sqlSesionFactory时,参数名要为sqlSessionFactoryBeanName,而不是sqlSessionTemplateBeanName。
3.编写spring-service.xml,将service层业务注入到ioc容器中
<?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
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<import resource="spring-dao.xml"/>
<!-- 扫描service下的包 -->
<context:component-scan base-package="com.heima.service"/>
<!-- 将我们的所有业务类,注入到spring,可以通过配置或者注解解决 -->
<bean id="BookServiceImpl" class="com.heima.service.BookServiceImpl">
<property name="bookMapper" ref="bookMapper"/>
</bean>
<!-- 声明式事务配置 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入事务源 -->
<property name="dataSource" ref="datasource"/>
</bean>
<!-- 结合aop实现事务的织入 -->
<!-- 配置事务通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 给哪些方法配置事务 -->
<tx:attributes>
<!-- 全部方法 -->
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- aop事务支持 -->
<aop:config>
<aop:pointcut id="toPointCut" expression="execution(* com.heima.dao.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="toPointCut"/>
</aop:config>
</beans>
至此,我们完成了spring层的操作,我们整合了Mybatis,也将ServiceImpl注入到了ioc容器中。
springmvc层
1、web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- DispatachServlet -->
<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:applicationContext.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>
<filter>
<filter-name>encoding</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>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Session -->
<session-config>
<session-timeout>20</session-timeout>
</session-config>
</web-app>
2、编写spring-mvc.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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
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 https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 注解驱动 -->
<mvc:annotation-driven/>
<!-- 静态资源过滤 -->
<mvc:default-servlet-handler/>
<!-- 扫描包 -->
<context:component-scan base-package="com.heima.controller"/>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
3、Spring配置整合文件,applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="spring-dao.xml"/>
<import resource="spring-service.xml"/>
<import resource="spring-mvc.xml"/>
</beans>
至此,我们完成了ssm整合框架的基本配置。
现在,我们来做项目基本测试.
1、BookController 类编写 , 方法一:查询全部书籍
package com.heima.controller;
import com.heima.pojo.Books;
import com.heima.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.ArrayList;
import java.util.List;
@Controller
@RequestMapping("/book")
public class BookController {
//Controller层 调用service层
@Autowired
@Qualifier("BookServiceImpl")
private BookService bookService;
//查询全部的书籍,并且返回到一个书籍展示页面
@RequestMapping("/allBook")
public String list(Model model){
List<Books> books = bookService.queryAllBook();
model.addAttribute("list",books);
return "allBook";
}
}
2、编写首页 index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>首页</title>
<style>
a{
text-decoration: none;
color: black;
font-size: 18px;
}
h3{
width:180px;
height: 50px;
margin: 180px auto;
line-height: 38px;
background: deepskyblue;
border-radius: 5px;
}
</style>
</head>
<body>
<h3>
<a href="${pageContext.request.contextPath}/book/allBook">进入书籍页面</a>
</h3>
</body>
</html>
3、书籍列表页面 allbook.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>书籍展示页面</title>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<div class="page-header">
<h1>
<small>书籍列表 ------- 显示所有书籍</small>
</h1>
</div>
</div>
</div>
<div class="row">
<div class="row-md-4 column">
<%-- toAddBook --%>
<a class="btn btn-primary" href="${pageContext.request.contextPath}/book/toAddBook">新增书籍</a>
<a class="btn btn-primary" href="${pageContext.request.contextPath}/book/allBook">显示所有书籍</a>
</div>
<div class="row-md-4 column">
<div class="row-md-4 column">
<%-- 查询书籍 --%>
<form class="form-inline" action="${pageContext.request.contextPath}/book/queryBook" method="post" style="float:right">
<span style="color: red;font-weight: bold">${error}</span>
<input type="text" name="queryBookName" class="form-control" placeholder="请输入要查询的书籍名称">
<input type="submit" value="查询">
</form>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-md-12 column">
<table class="table table-hover table-striped">
<thead>
<th>书籍编号</th>
<th>书籍名称</th>
<th>书籍数量</th>
<th>书籍详情</th>
<th>操作</th>
</thead>
<tbody>
<%-- 书籍即可从书中查询出来,从这个list中遍历出来:foreach --%>
<c:forEach var="book" items="${list}">
<tr>
<td>${book.bookID}</td>
<td>${book.bookName}</td>
<td>${book.bookCounts}</td>
<td>${book.detail}</td>
<td>
<a href="${pageContext.request.contextPath}/book/toUpdateBook?id=${book.bookID}">修改<a/>
|
<a href="${pageContext.request.contextPath}/book/deleteBook?id=${book.bookID}">删除<a/>
<tr/>
</c:forEach>
</tbody>
</table>
</div>
</div>
</body>
</html>
4、BookController 类编写 , 方法二:添加书籍
package com.heima.controller;
import com.heima.pojo.Books;
import com.heima.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.ArrayList;
import java.util.List;
@Controller
@RequestMapping("/book")
public class BookController {
//Controller层 调用service层
@Autowired
@Qualifier("BookServiceImpl")
private BookService bookService;
//跳转到增加书籍页面的请求(WEB-INF下的文件不能直接访问,只能通过第三方调用)
@RequestMapping("/toAddBook")
public String toAddBook(Books book){
// bookService.addBook(book);
return "addBook";
}
//添加书籍的请求
@RequestMapping("/addBook")
public String addBook(Books book){
bookService.addBook(book);
return "redirect:/book/allBook";
}
}
5、添加书籍页面:addBook.js
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>新增书籍</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 引入 Bootstrap -->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<div class="page-header">
<h1>
<small>新增书籍</small>
</h1>
</div>
</div>
</div>
<form action="${pageContext.request.contextPath}/book/addBook" method="post">
书籍名称:<input type="text" name="bookName" required><br><br><br>
书籍数量:<input type="text" name="bookCounts" required><br><br><br>
书籍详情:<input type="text" name="detail" required><br><br><br>
<input type="submit" value="添加">
</form>
</div>
</body>
</html>
6、BookController 类编写 , 方法三:修改书籍
package com.heima.controller;
import com.heima.pojo.Books;
import com.heima.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.ArrayList;
import java.util.List;
/**
* @Author 黑麻哥
* @Date 2023/10/17 18:50
* @Version 1.0
*/
@Controller
@RequestMapping("/book")
public class BookController {
//Controller层 调用service层
@Autowired
@Qualifier("BookServiceImpl")
private BookService bookService;
//跳转到更新书籍页面
@RequestMapping("/toUpdateBook")
public String toUpdateBook(int id, Model model){
Books books = bookService.queryBookById(id);
System.out.println(books);
model.addAttribute("QBook",books);
return "updateBook";
}
//修改书籍
@RequestMapping("/updateBook")
public String updateBook(Books book){
System.out.println("updateBook =>"+book);
bookService.updateBook(book);
return "redirect:/book/allBook";
}
}
7、修改书籍页面 updateBook.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>修改书籍</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 引入 Bootstrap -->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<form action="${pageContext.request.contextPath}/book/updateBook" method="post">
<input type="hidden" name="bookID" value="${QBook.bookID}"/>
书籍名称:<input type="text" name="bookName" value="${QBook.bookName}" required><br><br><br>
书籍数量:<input type="text" name="bookCounts" value="${QBook.bookCounts}" required><br><br><br>
书籍详情:<input type="text" name="detail" value="${QBook.detail}" required><br><br><br>
<input type="submit" value="提交">
</form>
</div>
</body>
</html>
8、BookController 类编写 , 方法四:删除书籍
package com.heima.controller;
import com.heima.pojo.Books;
import com.heima.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.ArrayList;
import java.util.List;
@Controller
@RequestMapping("/book")
public class BookController {
//Controller层 调用service层
@Autowired
@Qualifier("BookServiceImpl")
private BookService bookService;
//删除书籍
@RequestMapping("/deleteBook")
public String deleteBook(int id){
bookService.deleteBookById(id);
return "redirect:/book/allBook";
}
}
配置Tomcat,进行运行!
到目前为止,这个SSM项目整合已经完全的OK了,可以直接运行进行测试!这个练习十分的重要,大家需要保证,不看任何东西,自己也可以完整的实现出来!