1、概念
名称 | 职责 |
Model | 模型:即业务模型,负责完成业务中的数据通信处理,对应项目中的 service和dao |
View | 视图:渲染数据,生成页面。对应项目中的Jsp |
Controller | 控制器:直接对接请求,控制MVC流程,调度模型,选择视图。对应项目中的Servlet |
2、开发流程
2.1 导入依赖:spring-webmvc
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
2.2 配置核心(前端)控制器:
前端向后端发起请求 无法直接请求到SpringMVC 所以MVC框架设计了一款前端控制器 选型在 Servlet 或 Filter两者之一 在框架最前沿率先工作 接收所有请求。
配置的所有请求都要找到 DispatcherServlet ====> SpringMVC ======> mvc.xml
MVC ==== > 返回给前端时也通过了一些过程
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 局部参数:声明配置文件位置 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:mvc.xml</param-value>
</init-param>
<!-- Servlet启动时刻:可选 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
2.3 mvc.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/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">
<!-- 告知springmvc 使用的那些包需要注解式开发 -->
<context:component-scan base-package="com.qf.controller"></context:component-scan>
<!-- 注册注解开发驱动 -->
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
2.4 小案例:配置文件需要加入视图解析器
//通过Controller 将HelloAction注入到容器中
//配置的前置处理器就可以找到 ====> Action
//根据一级目录找到类 根据二级目录找到方法
//return 表示你要响应前端那个页面
//写完的页面需要MVC视图解析器 解析后才能显示 解析在返回值的前后拼接 ==> "/index.jsp"-->
@Controller
@RequestMapping("/hello")
public class HelloAction {
@RequestMapping("/test7")
public String test1(){
System.out.println("hello");
return "index";
}
}
<!-- 视图解析器作用:
1.捕获后端控制器的返回值="index"
2.解析在返回值的前后 拼接 ==> "/index.jsp"-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/"></property>
<!-- 后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
3、接收请求参数
3.1 前端通过地址 给后端传值 基本数据类型 请求参数的方法的形参 同名即可
@Controller
@RequestMapping("/param")
//前端通过地址给后端传值
//http://localhost:8080/param/demo1?id=1&name=Tom&sex=false&birthday=2023/2/9
public class ParamAction {
@RequestMapping("/demo1")
public String demo1(Integer id, String name, Boolean sex, Date birthday){
System.out.println(id);
System.out.println(name);
System.out.println(sex);
System.out.println(birthday);
return "index";
}
@RequestMapping("/demo2")
public String demo2(User user){
System.out.println(user);
return "index";
}
}
3.2 实体接收参数
public class User {
private Integer id;
private String name;
private Boolean sex;
private Date birthday;
// 构造器 get set toString
// 路径 id=?&name=?...
}
3.3 数组收参
@RequestMapping("/demo3")
public String demo3(String[] hobby){
System.out.println(Arrays.toString(hobby));
return "form";
//hobby=football&hobby=basketball
<form action="/param/demo3" method="post">
足球:<input type="checkbox" name="hobby" value="football">
篮球:<input type="checkbox" name="hobby" value="basketball">
网球:<input type="checkbox" name="hobby" value="wq">
<input type="submit" value="保存">
</form>
3.4 集合接收(了解)
<form action="/param/demo4" method="post">
id:<input type="text" name="users[0].id"/>编号
name:<input type="text" name="users[0].name"/>姓名
sex:<input type="text" name="users[0].sex"/>性别
id:<input type="text" name="users[1].id"/>编号
name:<input type="text" name="users[1].name"/>姓名
sex:<input type="text" name="users[1].sex"/>性别
<input type="submit" value="保存">
</form>
@RequestMapping("/demo4")
public String demo4(UserList users){
System.out.println(users.getUsers());
return "form";
public class UserList {
private List<User> users;
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
//users[0].id=1&users[0].name=zhangsan&users[0].birth=2018-12-12&users[1].id=2&.... 注:地址栏不能有符号:[]
}
3.5 路径参数 RestFul风格
//获取RestFul风格的参数
@RequestMapping("/demo5/{id}")
public String demo5(@PathVariable("id") Integer id){
System.out.println(id);
return "index";
}
3.6 中文乱码问题
3.6.1 首先页面中字符集统一
JSP : <%@page pageEncoding="utf-8" %>
HTML : <meta charset="UTF-8">
3.6.2 其次,tomcat中字符集设置,对get请求中,中文参数乱码有效
Tomcat server.xml 配置:URIEncoding=utf-8
<Connector connectionTimeout="20000"port="8080" protocol="HTTP/1.1"redirectPort="8443" maxPostSize="0" URIEncoding="UTF-8"/>
3.6.3 最后,设置此filter,对post请求中,中文参数乱码有效
<!-- 此过滤器会进行:request.setCharactorEncoding("utf-8"); -->
<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>
4、请求转发 重定向
4.1 请求转发:
@SuppressWarnings("{all}")
@Controller
@RequestMapping("/hello")
public class HelloAction {
@RequestMapping("/test7")
public String test1(){
System.out.println("hello");
return "index";
}
@RequestMapping("/forward")
public String forward2(){
System.out.println("forward");
//绝对路径:要访问到8080后的绝对路径
return "forward:/hello/test7";
//return "forward:test7"; 访问相对路径
//return test1(); 实现调方法也可以实现
}
}
4.2 重定向
@Controller
@SuppressWarnings({"all"})
@RequestMapping("/redir")
public class RedirectController {
@RequestMapping("/test1")
public String test1(){
System.out.println("test redirect1");
return "redirect:test1";
}
@RequestMapping("test2")
public String testRedirect2(){
System.out.println("test testRedirect2");
return "redirect:/index.jsp";
}
}
5、接传值
5.1 导入jitl依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
5.2 Request和Session
@RequestMapping("/request")
public String request(HttpServletRequest request, HttpSession session){
System.out.println(request);
System.out.println(session);
//通过后端给前端传值
request.setAttribute("request","request");
session.setAttribute("session","session");
return "index";
}
5.3 JSP中取值
//jsp中用EL表达式 取值即可
${requestScope.request}
${sessionScope.session}
5.4 model model中的数据,会在V渲染之前,将数据复制一份给request
//在jsp中直接取值:${requestScope.model}
@RequestMapping("/model")
public String model(Model model){
System.out.println(model);
model.addAttribute("model","model");
return "index";
}
5.5 ModelAndView
@RequestMapping("/modelAndView")
public ModelAndView modelAndView(){
//新建ModelAndView对象
ModelAndView mv = new ModelAndView();
System.out.println(mv);
//设置视图名 即如何跳转
mv.setViewName("forward:/index.jsp");//表示你要到那个页面去 请求转发/重定向
//给前端传modelAndView 增加数据
mv.addObject("modelAndView","modelandview");
return mv;
//${requestScope.modelAndView} JSP直接取值
}
5.6 @SessionAttributes(不好使)
@Controller
@SessionAttributes(names={"gender","name"}) // model中的 name和gender 会存入session中
public class UserController {
@RequestMapping("/hello")
public String hello(Model m){
m.addAttribu te("gender",true); // 会存入session
m.addObject("name","zhj"); // 会存入session //不推荐
return "index";
}
//jsp中用EL表达式 取值即可
${sessionScope.name}
${sessionScope.gender}
@RequestMapping("/hello2")
public String hello(SessionStatus status){
// 移除通过SessionAttributes存入的session
status.setComplete();
return "index";
}
}
6、静态资源
6.1 静态资源问题:
静态文件没有url-pattern 所以默认是访问不到的,之所以可以访问,是因为,tomcat中有一个全局的servlet:org.apache.catalina.servlets.DefaultServlet,它的url-pattern是 "/",是全局默认的Servlet. 所以每个项目中不能匹配的静态资源的请求,有这个Servlet来处理即可但在SpringMVC中DispatcherServlet也采用了 “/” 作为url-pattern, 则项目中不会再使用全局的Serlvet,则静态资源不能完成访问
6.2 解决方案1:
DispathcerServlet采用其他的url-pattern 此时,所有访问handler的路径都要以 action结尾!!
<servlet>
<servlet-name>mvc9</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>mvc9</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
@RequestMapping("/test1")
public String test1(){
System.out.println("test");
return "forward:test2.action";
}
@RequestMapping("/test2")
public String test2(){
System.out.println("test2");
return "index";
}
6.3 解决方案2:DispathcerServlet的url-pattern依然采用 "/",但追加配置
<!--
额外的增加一个handler,且其requestMapping: "/**" 可以匹配所有请求,但是优先级最低
所以如果其他所有的handler都匹配不上,请求会转向 "/**" ,恰好,这个handler就是处理静态资源的
处理方式:将请求转会到tomcat中名为default的Servlet
-->
<mvc:default-servlet-handler/>
7、SSM整合 (环境搭建)
7.1 Springjar包的依赖体系:
一、 Core Container
1. spring-core:依赖注入IoC与DI的最基本实现
2. spring-beans:Bean工厂与bean的装配
3. Spring Context:在基础IOC功能上提供扩展服务,此外还提供许多企业级服务的支持,有邮件服务、任务调度、JNDI定位,EJB集成、远程访问、缓存以及多种视图层框架的支持(不常用)
4. Spring Context Support:Spring context的扩展支持,用于MVC方面(不常用)
5. spring-expression:spring表达式语言(不常用)
二、 AOP Aspects Instrumentation Messaging
1. spring-aop :提供了面向切面编程的实现,它允许你定义拦截器 (interceptors) 和 切点 (pointcuts),用以解耦(decouple) 关注点不同的代码
2. Aspects :spring-aspects AOP
3. spring-instrument: 提供了用于某些应用程序服务器的类工具支持和类加载器(ClassLoader)实现(不常用)
4. spring-instrument-tomcat 是 Spring instrumentation agent for Tomcat (不常用)
三、 Data Access
1. spring-jdbc:为JDBC、Hibernate、JDO、JPA等提供的一致的声明式和编程式事务管理
2. spring-tx:事务控制
3. spring-orm:对象关系映射,集成orm框架(不常用)
4. spring-oxm:对象xml映射(不常用)
5. spring-jms:java消息服务(不常用)
四、 Web
1. Spring websocket:提供 Socket通信, web端的推送功能(不常用)
2. Servlet
3. Spring web:包含Web应用开发时,用到Spring框架时所需的核心类,包括自动载入WebApplicationContext特性的类、Struts与JSF集成类、文件上传的支持类、Filter类和大量工具辅助类
4. Spring webmvc portlet:Spring MVC的增强(不常用)
<?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>com.qf</groupId>
<artifactId>java2207-SpringMVC-1</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<!--设置为web项目-->
<packaging>war</packaging>
<dependencies>
<!--AOP面向切面编程-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<!--web中引入MVC导入的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<!--Spring JDBC依赖对JDBC的支持-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<!--jstl JSP的依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<!-- Spring整合mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!-- mysql驱动 依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.25</version>
<scope>runtime</scope>
</dependency>
<!-- 德鲁伊连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<!-- Junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
</dependencies>
</project>
五、applicationContext.Xml(resources)下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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/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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- DataSource -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!--基本配置-->
<property name="driverClassName" value="${jdbc.driverClass}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="${jdbc.init}"/>
<property name="minIdle" value="${jdbc.minIdle}"/>
<property name="maxActive" value="${jdbc.maxActive}"/>
<!-- 配置获取连接等待超时的时间 ms-->
<property name="maxWait" value="60000"/>
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000"/>
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000"/>
</bean>
<!-- SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入连接池 -->
<property name="dataSource" ref="dataSource"></property>
<!-- 注入dao-mapper文件信息 ,如果映射文件和dao接口 同包且同名,则此配置可省略-->
<property name="mapperLocations">
<list>
<value>classpath:com/qf/dao/*.xml</value>
</list>
</property>
<!-- 为 dao-mapper文件中的实体 定义缺省包路径
如:<select id="queryAll" resultType="User"> 中 User类可以不定义包
<property name="typeAliasesPackage" value="com.qf.entity"></property>-->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<props>
<!-- 页号 调整到合理的值 0 max -->
<prop key="reasonable">true</prop>
</props>
</property>
</bean>
</array>
</property>
</bean>
<!-- DAO MapperScannerConfigurer dao层的自动注入 -->
<bean id="mapperScannerConfigurer9" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.qf.dao"></property>
<!-- 如果工厂中只有一个SqlSessionFactory的bean,此配置可省略 -->
<!--<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>-->
</bean>
<!-- 为导致Spring 与 SpringMVc 自动注入的bean不冲突自动注入的bean
expression="org.springframework.stereotype.Controller扫描包,并排除Controller -->
<context:component-scan base-package="com.qf" use-default-filters="true">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 引入一个事务管理器,其中依赖DataSource,借以获得连接,进而控制事务逻辑 -->
<bean id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- @Transactional -->
<tx:annotation-driven transaction-manager="tx"/>
</beans>
六、SpringMVC配置文件(mvc.xml)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/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">
<!-- 告知springmvc 使用的那些包需要注解式开发 -->
<context:component-scan base-package="com.qf.controller"></context:component-scan>
<!-- 注册注解开发驱动 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 视图解析器
作用:1.捕获后端控制器的返回值="index"
2.解析: 在返回值的前后 拼接 ==> "/index.jsp"-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/"></property>
<!-- 后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
<!-- <context:component-scan base-package="com.qf"/>-->
<!--
<context:component-scan base-package="com.zhj" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
-->
</beans>
七、jdbc.properties(resources)
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/qf.edu?useSSL=false&useUnicode=true&characterEncoding=UTF8
jdbc.username=root
jdbc.password=1234
jdbc.init=1
jdbc.minIdle=1
jdbc.maxActive=3
八、Mapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--namespace:所需实现的接口全限定名--> <mapper namespace="com.qf.dao.AdminDao"> <sql id="repeatSql"> select * from admin </sql> <select id="queryAdmins" resultType="com.qf.pojo.Admin"> <include refid="repeatSql"></include> </select> </mapper>
九、web.xml(配置前端处理器)src\main\webapp\web\inf\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">
<!-- 导入前端控制器 首先接收前端请求 也就是Servlet/Filter 在框架最前沿工作 接收前端请求-->
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 局部参数:声明配置文件位置 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:mvc.xml</param-value>
</init-param>
<!-- Servlet启动时刻:可选 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 此过滤器会进行:request.setCharactorEncoding("utf-8"); -->
<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>
<!-- 启动Spring工厂 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
</web-app>
十、demo
实体:
public class Admin {
private String username;
private String password;
private String phone;
private String address;
//get set toString 构造器 可以使用lomBok
}
dao层:
public interface AdminDao {
List<Admin> queryAdmins();
}
service层(接口):
public interface AdminService {
List<Admin> queryAll();
}
接口实现类:
@Service("adminService")
public class AdminServiceImpl implements AdminService{
@Autowired
private AdminDao adminDao;
@Override
public List<Admin> queryAll() {
return adminDao.queryAdmins();
}
}
controller层:
/**
* @author S7
* @version 1.0
*/
@Controller
@RequestMapping("/admin")
public class AdminAction {
@Autowired
private AdminService adminService;
@RequestMapping("/queryAll")
public String queryAll(Model model){
List<Admin> list = adminService.queryAll();
model.addAttribute("list",list);
return "admin";
}
}
八、Json
8.1 环境搭建resources下:(beans.xml)(1.视图解析器 2.注册开发驱动 3.解决中文乱码问题)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/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">
<!-- 告知springmvc 使用的那些包需要注解式开发 -->
<context:component-scan base-package="com.qf.controller"></context:component-scan>
<!-- 注册注解开发驱动 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 视图解析器
作用:1.捕获后端控制器的返回值="index"
2.解析: 在返回值的前后 拼接 ==> "/index.jsp"-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/"></property>
<!-- 后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
<!-- <context:component-scan base-package="com.qf"/>-->
<!--
<context:component-scan base-package="com.zhj" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
-->
<!-- 编码格式 -->
<mvc:default-servlet-handler/>
</beans>
8.2 pom.xml(1.设置成web项目 2.导入web-mvc依赖3.导入Json所需要的 Jaskson依赖)
<?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>com.qf</groupId>
<artifactId>java2207Springmvc-json-ssm</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<packaging>war</packaging>
<dependencies>
<!--web中引入MVC导入的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
<!-- Jackson springMVC默认的Json解决方案选择是 Jackson,所以只需要导入jackson的jar,即可使用。-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<!--FastJson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
</dependencies>
</project>
8.3 web.xml(1.导入前端控制器 2.DispatcherServlet 声明配置文件位置classpath 3.设置过滤器)
<?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">
<!-- 导入前端控制器 首先接收前端请求 也就是Servlet/Filter 在框架最前沿工作 接收前端请求-->
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 局部参数:声明配置文件位置 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:beans.xml</param-value>
</init-param>
<!-- Servlet启动时刻:可选 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 此过滤器会进行:request.setCharactorEncoding("utf-8"); -->
<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>
8.4.1 demo实体
/**
* @author S7
* @version 1.0
*/
public class User {
@JsonProperty("new_id")//传给前端的数据id属性 名称更改为new_id
private String name;
//@JsonIgnore 注释在那个属性上面那个属性就不会传到前端
//若"name==null" 忽略此属性 此处测试的是List
//@JsonInclude(JsonInclude.Include.NON_NULL)
private Integer id;
@JsonFormat(pattern = "yyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date birthday;
@JsonInclude(value= JsonInclude.Include.NON_EMPTY) // 若hobby长度为0或==null 忽略此属性
private List<String> hobby;
//自定义序列化
@JsonSerialize(using = MySerializer.class)
private Double salary = 1000.111;
public User(String name, Integer id, Date birthday, List<String> hobby, Double salary) {
this.name = name;
this.id = id;
this.birthday = birthday;
this.hobby = hobby;
this.salary = salary;
}
public User(String name, Integer id) {
this.name = name;
this.id = id;
}
public List<String> getHobby() {
return hobby;
}
public void setHobby(List<String> hobby) {
this.hobby = hobby;
}
public User(String name, Integer id, Date birthday) {
this.name = name;
this.id = id;
this.birthday = birthday;
}
public User(String name, Integer id, Date birthday, List<String> hobby) {
this.name = name;
this.id = id;
this.birthday = birthday;
this.hobby = hobby;
}
public User() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", id=" + id +
", birthday=" + birthday +
", hobby=" + hobby +
", salary=" + salary +
'}';
}
}
8.4.2 测试类
//前端访问路径 通过json给前端传值
//@Controller + @ResponseBody = @RestController加载类上
@RestController
@RequestMapping("/json")
public class JsonAction {
@RequestMapping("/test1")
//@ResponseBody
public User test1(){
User user = new User("tom",101);
return user;
}
@RequestMapping("/test2")
//@ResponseBody
public List<User> test2(){
List<User> list = new ArrayList<>();
list.add(new User("jack",2));
list.add(new User("S7",24));
return list;//return 给通过json返给前端的请求
}
//中文乱码问题 在@RequestMapping中设置
@RequestMapping(value="/test3",produces = "text/html;charset=utf-8")
//@ResponseBody
public String test3(){
return "宁";
}
@RequestMapping("/test4")
public String test4(@RequestBody User user){
//加上注释就能将传过来的Json串转换成对象
System.out.println(user);
return "ok";
}
@RequestMapping("/test5")
public User test5(){
return new User("s7",24,new Date());
}
}
8.4.3 序列化工具类
public class MySerializer extends JsonSerializer<Double> {
@Override
public void serialize(Double aDouble, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
String number = BigDecimal.valueOf(aDouble).setScale(2,BigDecimal.ROUND_HALF_UP).toString();
//输出四舍五入的值
jsonGenerator.writeNumber(number);
}
}
8.4.4 前端页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/jquery-3.6.1.min.js"></script>
<script>
$(function () {
$("#btn1").click(function () {
var user = {id:1,name:"tom",birthday:"2020-12-12"};
$.ajax({
url: '/json/test4',//路径
type: 'post',//请求方式
contentType: "application/json",//声明请求参数类型为 json
data: JSON.stringify(user),// 转换js对象成json
success: function (data) {
console.log(data);
}
});
});
})
</script>
</head>
<body>
<button id="btn1">发送json</button>
<!--绑定单击事件 向后端发送json-->
</body>
</html>
8.4.5 Json依赖
<!-- Jackson springMVC默认的Json解决方案选择是 Jackson,所以只需要导入jackson的jar,即可使用。-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
<!--FastJson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
8.4.6 Json常用注解:
1. 通过前端访问路径 通过json给前端传值 注解+@ResponseBody
2. @Controller + @ResponseBody = @RestController加载类上
3. @RequestMapping(value="/test3",produces = "text/html;charset=utf-8") 中文乱码问题设置
4. public String test4(@RequestBody User user) 加上@RequestBody注释将前端传入Json代码转换成想要的方式类对象
5. @JsonProperty("new_id") 传给前端的数据id属性 名称更改为new_id
6. @JsonIgnore 注释在那个属性上面那个属性就不会传到前端
7. @JsonInclude(JsonInclude.Include.NON_NULL)在类中显示对象属性为空的
8. @JsonInclude(value= JsonInclude.Include.NON_EMPTY) 定义在属性上 如果该属性为 null 或者 长度=0 则忽略此属性
9. @JsonFormat(pattern = "yyy-MM-dd HH:mm:ss", timezone = "GMT+8") 传给前端Data类型注释
10. 自定义序列化 @JsonSerialize(using = MySerializer.class)
例:将三位小数四舍五入
类 private Double salary = 1000.111; public class MySerializer extends JsonSerializer<Double> { @Override public void serialize(Double aDouble, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { String number = BigDecimal.valueOf(aDouble).setScale(2,BigDecimal.ROUND_HALF_UP).toString(); //输出四舍五入的值 jsonGenerator.writeNumber(number); } }
九、异常解析器
定义异常解析器,统一处理异常
Controller中的每个Handler不再自己处理异常,而是直接throws所有异常。定义一个“异常解析器” 集中捕获处理 所有异常 此种方案,在集中管理异常方面,更有优势!
前端发起请求后 到异常时候调用工具类:
@RequestMapping("/ex")
@RestController
public class ExceptionAction {
@RequestMapping("/test1")
public void test1(){
System.out.println("todo");
throw new NullPointerException("null----");
}
}
工具类:com.qf.Exception.MyExResolver implements HandlerExceptionResolver
public class MyExResolver implements HandlerExceptionResolver {
/**
* 异常解析器:主体逻辑
* 执行时刻:当handler中抛出异常时,会执行:捕获异常,并可以跳到错误页面
*/
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
ex.printStackTrace();//打印异常栈
//创建一个ModelAndView
ModelAndView mv = new ModelAndView();
//识别异常
if (ex instanceof NullPointerException) {
mv.setViewName("redirect:/error1.jsp");
}else if(ex instanceof ClassCastException){
mv.setViewName("redirect:/error2.jsp");
}else{
mv.setViewName("redirect:/error.jsp");
}
return mv;
}
}
MVC.xml
<!-- 声明异常解析器 -->
<bean class="com.baizhi.exception.resolver.MyExResolver"></bean>
十、拦截器(抽取handler中的冗余功能 )
//test1和test2方法产生了冗余
@RequestMapping("/inter")
@SessionAttributes("state")
public class InterController(){
@RequestMapping("/login")
public String login(Model mode){
model.addAttribute("state","ok");
return "index";
}
@RequestMapping("/test1")
public String test1(Model model){
if(model.asMap()).get("state") != null){
System.out.println("service1");
return "index";
}else{
return "login";
}
}
@RequestMapping("/test1")
public String test2(Model model){
if(model.asMap()).get("state") != null){
System.out.println("service1");
return "index";
}else{
return "login";
}
}
}
定义拦截器:
public class MyInter1 implements HandlerInterceptor{
//主要逻辑:在handler之前执行:抽取handler中的冗余代码
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("pre~~~");
/*
response.sendRedirect("/springMVC_day2/index.jsp");//响应
return false;//中断请求
*/
/*
HttpSession session = request.getSession();
if(session.getAttribute("state") != null){
return true;
}
*/
return true;//放行,后续的拦截器或handler就会执行
}
//在handler之后执行,响应之前:进一步的响应定制
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("post~~");
}
//在页面渲染完毕之后,执行:资源回收
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("after~~");
}
}
//删除冗余代码
@RequestMapping("/login")
public String login(Model mode){
model.addAttribute("state","ok");
return "index";
}
@RequestMapping("/test1")
public String test1(Model model){
System.out.println("service1");
return "index";
}
@RequestMapping("/test1")
public String test2(Model model){
System.out.println("service1");
return "index";
}
配置拦截路径
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/inter/test1"/>
<mvc:mapping path="/inter/test2"/>
<mvc:mapping path="/inter/test*"/> <!-- test开头 -->
<mvc:mapping path="/inter/**"/> <!-- /** 任意多级任意路径 -->
<mvc:exclude-mapping path="/inter/a/**"/> <!--不拦截此路径-->
<bean class="com.baizhi.interceptor.MyInter1"></bean> <!--拦截器类-->
</mvc:interceptor>
</mvc:interceptors>
十一、上传
11.1 导入jar包
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
11.2 表单
<form action="${pageContext.request.contextPath }/upload/test1" method="post"
enctype="multipart/form-data">
file: <input type="file" name="source"/> <br>
<input type="submit" value="提交"/>
</form>
11.3 上传解析器
<!-- 上传解析器
id必须是:“multipartResolver”
-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 最大可上传的文件大小 单位:byte 超出后会抛出MaxUploadSizeExceededException异常,可以异常解析器捕获 1048576=1M tomcat7的几个版本好用,其他版本看不到效果-->
<property name="maxUploadSize" value="1048576"></property>
</bean>
11.4 Handler
@RequestMapping("/test1")
public String hello1(String username,MultipartFile source,HttpSession session) {
//文件的原始名称
String filename = source.getOriginalFilename();
//定制全局唯一的命名
String unique = UUID.randomUUID().toString();
//获得文件的后缀
String ext = FilenameUtils.getExtension(filename);//abc.txt txt hello.html html
//定制全局唯一的文件名
String uniqueFileName = unique+"."+ext;
System.out.println("唯一的文件名:"+uniqueFileName);
//文件的类型
String type = source.getContentType();
System.out.println("filename:"+filename+" type:"+type);
//获得 upload_file的磁盘路径 ==> 在webapp目录下创建一个目录"upload_file",且此目录初始不要为空,否则编译时被忽略
String real_path = session.getServletContext().getRealPath("/upload_file");
System.out.println("real_path:"+real_path);
//将上传的文件,存入磁盘路径中
//source.transferTo(new File("d:/xxxx/xxxx/xx.jpg"))
source.transferTo(new File(real_path+"\\"+uniqueFileName));
return "index";
}
也可以在拦截器中拦截文件大小,并手动抛出MaxUploadSizeExceededException异常
public class MyFileUploadInterceptor implements HandlerInterceptor {
private Long maxFileuploadSize;
public Long getMaxFileuploadSize() {
return maxFileuploadSize;
}
public void setMaxFileuploadSize(Long maxFileuploadSize) {
this.maxFileuploadSize = maxFileuploadSize;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 判断上传文件大小 1048576
ServletRequestContext servletRequestContext = new ServletRequestContext(request);
// 文件大小 byte
long l = servletRequestContext.contentLength();
if(l>maxFileuploadSize){
throw new MaxUploadSizeExceededException(maxFileuploadSize);
}
return true;
}
}
//在异常解析器中处理
public class MyExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
ModelAndView modelAndView = new ModelAndView();
if(e instanceof MyException1){
// error1.jsp
modelAndView.setViewName("redirect:/error1.jsp");
}else if(e instanceof MyException2){
// error2.jsp
modelAndView.setViewName("redirect:/error2.jsp");
}else if(e instanceof MyException3){
// error3.jsp
modelAndView.setViewName("redirect:/error3.jsp");
}else if(e instanceof MaxUploadSizeExceededException){
modelAndView.setViewName("redirect:/uploadError.jsp");
}
return modelAndView;
}
}
<!-- 拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!--<mvc:mapping path="/inter/test1"/>
<mvc:mapping path="/inter/test2"/>-->
<mvc:mapping path="/inter/**"/> <!-- /inter/a/test1 /inter/b/test2 -->
<mvc:exclude-mapping path="/inter/login"/>
<bean class="com.qf.interceptor.MyInterceptor"/>
</mvc:interceptor>
<!--上传文件大小拦截器-->
<mvc:interceptor>
<mvc:mapping path="/upload/test1"/>
<bean class="com.qf.interceptor.MyFileUploadInterceptor">
<property name="maxFileuploadSize" value="1048576"/>
</bean>
</mvc:interceptor>
</mvc:interceptors>
十二 、下载
12.1 超链接 :
<a href="${pageContext.request.contextPath}/download/test1?name=Koala.jpg">下载</a>
12.2 Handler:
@RequestMapping("/test1")
public void hello1(String name,HttpSession session,HttpServletResponse response){
System.out.println("name:"+name);
//获得要下载文件的绝对路径
String path = session.getServletContext().getRealPath("/upload_file");
//文件的完整路径
String real_path = path+"\\"+name;
//设置响应头 告知浏览器,要以附件的形式保存内容 filename=浏览器显示的下载文件名
response.setHeader("content-disposition","attachment;filename="+name);
//读取目标文件,写出给客户端
IOUtils.copy(new FileInputStream(real_path), response.getOutputStream());
//上一步,已经是响应了,所以此handler直接是void
}
十三 、验证码
13.1 作用:防止暴力攻击 前端安全保护
13.2 导入Jar包
<!-- Kaptcha -->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
13.3 声明验证码组件
<servlet>
<servlet-name>cap</servlet-name>
<servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
<init-param>
<param-name>kaptcha.border</param-name>
<param-value>no</param-value>
</init-param>
<init-param>
<param-name>kaptcha.textproducer.char.length</param-name>
<param-value>4</param-value>
</init-param>
<init-param>
<param-name>kaptcha.textproducer.char.string</param-name>
<param-value>abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</param-value>
</init-param>
<init-param>
<!-- 验证码 图片底色 -->
<param-name>kaptcha.background.clear.to</param-name>
<param-value>211,229,237</param-value>
</init-param>
<init-param>
<!-- session.setAttribute("captcha","验证码") -->
<param-name>kaptcha.session.key</param-name>
<param-value>captcha</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>cap</servlet-name>
<url-pattern>/captcha</url-pattern>
</servlet-mapping>
13.4 Page
<img src="${pageContext.request.contextPath}/captcha" style="width:85px" id="cap"/>
<img src="${pageContext.request.contextPath}/captcha" style="width:85px" id="cap" onclick="refresh();"/>
<script>
$(function(){
$("#cap").click(function(){
//刷新验证码
path = $(this).attr("src")+"?"+new Date().getTime();
$(this).attr("src",path);
});
});
function refresh(){
var img = document.getElementById("cap");
img.src = "${pageContext.request.contextPath}/captcha?"+new Date().getTime();
}
</script>
13.5 登录验证
@Controller
@RequestMapping("/captcha")
public class CaptchaControll(){
@RequestMapping("/test1")
public String test1(String cap, HttpSession session){
String captcha = session.getAttribute("captcha");
if(cap.equals(captcha)){
return "index";
}
return "error1";
}
}
<from action="${pageContext.request.contextPath}/captcha/test1">
<img src="${pageContext.request.contextPath}/captcha" style="width:85px" id="cap"/>
<input type="text" name="cap"/>
<br />
<input type="submit" value="提交"/>
</from>
十四、 Rest开发风格
1. 是一种开发风格,遵从此风格开发软件,符合REST风格,则RESTFUL
1.1 每个资源都有唯一的表示(Url)
1.2 不同的行为,使用对应的http-method
例:通过二级路径查询用户 三级路径查询用户1四级用户查询用户1的所有订单
访问标识 | 资源 |
http://localhost:8989/xxx/users | 所有用户 |
http://localhost:8989/xxx/users/1 | 用户1 |
http://localhost:8989/xxx/users/1/orders | 用户1的所有订单 |
请求方式 | 标识 | 意图 |
GET | http://localhost:8989/xxx/users | 查询所有用户 |
POST | http://localhost:8989/xxx/users | 在所有用户中增加一个 |
PUT | http://localhost:8989/xxx/users | 在所有用户中修改一个 |
DELETE | http://localhost:8989/xxx/users/1 | 删除用户1 |
GET | http://localhost:8989/xxx/users/1 | 查询用户1 |
GET | http://localhost:8989/xxx/users/1/orders | 查询用户1的所有订单 |
POST | http://localhost:8989/xxx/users/1/orders | 在用户1的所有订单中增加一个 |
@RestController
@RequestMapping("/restful")
//@RequestMapping(value="/users",method = RequestMethod.GET) 等价 @GetMapping("/users")
public class RestFull {
@GetMapping("/users")
public List<User> queryAllUsers(){
System.out.println("get");
List<User> users = new ArrayList<>();
users.add(new User(101,"tom",new Date()));
users.add(new User(102,"lucky",new Date()));
return users;
}
@PostMapping("/users")
public String addUser(@RequestBody User user){
System.out.println("Post user :"+user);
return "{status:1}";
}
@PutMapping("/users")
public String updateUser(@RequestBody User user){
System.out.println("Put user" + user+":user");
return "{status:1}";
}
@GetMapping("/users/{id}")
public String queryOneUser(@PathVariable Integer id){//@PathVariable 接收路径中的值
System.out.println("Get user id:"+id);
return "{status:1}";
}
@DeleteMapping("/users/{id}")
public String deleteOneUser(@PathVariable Integer id){//@PathVariable 接收路径中的值
System.out.println("delete user id:"+id);
return "{status:1}";
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/jquery-3.6.1.min(1).js"></script>
<script>
$(function (){
$("#btn1").click(function (){
//传日期是用8位字符串
var user = {id:1,name:"tom",birthday:"20221212"};
$.ajax({
url:'/json/test4',//要访问的地址
type:'post ',//请求方式
contentType:"application/json",//声明请求参数类型为json
data:JSON.stringify(user),//转换js对象成json
success:function (data){
console.log(data);
}
})
});
$("#btn2").click(function (){
//传日期是用8位字符串
var user = {id:1,name:"tom",birthday:"2022-12-12 12:12:12"};
$.ajax({
url:'/restful/users',//要访问的地址
type:'get',//请求方式
contentType:"application/json",//声明请求参数类型为json
//data:JSON.stringify(user),//转换js对象成json
success:function (data){
console.log(data);
}
})
});
$("#btn3").click(function (){
//传日期是用8位字符串
var user = {id:1,name:"tom",birthday:"2022-12-12 12:12:12"};
$.ajax({
url:'/restful/users',//要访问的地址
type:'post',//请求方式
contentType:"application/json",//声明请求参数类型为json
data:JSON.stringify(user),//转换js对象成json
success:function (data){
console.log(data);
}
})
});
$("#btn4").click(function (){
//传日期是用8位字符串
var user = {id:1,name:"lucky",birthday:"2022-12-12 12:12:12"};
$.ajax({
url:'/restful/users',//要访问的地址
type:'put',//请求方式
contentType:"application/json",//声明请求参数类型为json
data:JSON.stringify(user),//转换js对象成json
success:function (data){
console.log(data);
}
})
});
$("#btn5").click(function (){
//传日期是用8位字符串
var user = {id:1,name:"tom",birthday:"2022-12-12 12:12:12"};
$.ajax({
url:'/restful/users/1',//要访问的地址
type:'delete',//请求方式
contentType:"application/json",//声明请求参数类型为json
//data:JSON.stringify(user),//转换js对象成json
success:function (data){
console.log(data);
}
})
});
})
</script>
</head>
<body>
<button id="btn1">发送json</button>
<button id="btn2">queryAllUsers</button>
<button id="btn3">addUser</button>
<button id="btn4">updateUser</button>
<button id="btn5">deleteOneUser</button>
</body>
</html>
SpringMVC执行流程