drop database if exists springmvc;
create database springmvc;
use springmvc;
##创建图书表
create table t_book(
`id` int(11) primary key auto_increment, ## 主键
`name` varchar(50) not null, ## 书名
`author` varchar(50) not null, ## 作者
`price` decimal(11,2) not null, ## 价格
`sales` int(11) not null, ## 销量
`stock` int(11) not null ## 库存
);
## 插入初始化测试数据
insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock`)
values(null , 'java从入门到放弃' , '国哥' , 80 , 9999 , 9);
insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock`)
values(null , '数据结构与算法' , '严敏君' , 78.5 , 6 , 13);
insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock`)
values(null , '怎样拐跑别人的媳妇' , '龙伍' , 68, 99999 , 52);
insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock`)
values(null , '木虚肉盖饭' , '小胖' , 16, 1000 , 50);
insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock`)
values(null , 'C++编程思想' , '刚哥' , 45.5 , 14 , 95);
insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock`)
values(null , '蛋炒饭' , '周星星' , 9.9, 12 , 53);
insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock`)
values(null , '赌神' , '龙伍' , 66.5, 125 , 535);
insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock`)
values(null , 'Java编程思想' , '阳哥' , 99.5 , 47 , 36);
insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock`)
values(null , 'JavaScript从入门到精通' , '婷姐' , 9.9 , 85 , 95);
insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock`)
values(null , 'cocos2d-x游戏编程入门' , '国哥' , 49, 52 , 62);
insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock`)
values(null , 'C语言程序设计' , '谭浩强' , 28 , 52 , 74);
insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock`)
values(null , 'Lua语言程序设计' , '雷丰阳' , 51.5 , 48 , 82);
insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock`)
values(null , '西游记' , '罗贯中' , 12, 19 , 9999);
insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock`)
values(null , '水浒传' , '华仔' , 33.05 , 22 , 88);
insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock`)
values(null , '操作系统原理' , '刘优' , 133.05 , 122 , 188);
insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock`)
values(null , '数据结构 java版' , '封大神' , 173.15 , 21 , 81);
insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock`)
values(null , 'UNIX高级环境编程' , '乐天' , 99.15 , 210 , 810);
insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock`)
values(null , 'javaScript高级编程' , '国哥' , 69.15 , 210 , 810);
insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock`)
values(null , '大话设计模式' , '国哥' , 89.15 , 20 , 10);
insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock`)
values(null , '人月神话' , '刚哥' , 88.15 , 20 , 80);
## 查看表内容
select id,name,author,price,sales,stock from t_book;
创建一个web工程
导入需要jar包
c3p0-0.9.1.2.jar
commons-logging-1.1.3.jar
log4j-1.2.17.jar
mysql-connector-java-5.1.37-bin.jar
spring-aop-4.0.0.RELEASE.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
spring-jdbc-4.0.0.RELEASE.jar
spring-orm-4.0.0.RELEASE.jar
spring-test-4.0.0.RELEASE.jar
spring-tx-4.0.0.RELEASE.jar
spring-web-4.0.0.RELEASE.jar
spring-webmvc-4.0.0.RELEASE.jar
添加jdbc.properties属性配置文件:
jdbc.user=root
jdbc.password=123456
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/springmvc
# Global logging configuration
log4j.rootLogger=INFO, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
配置Spring访问数据库需要的组件:
并分别对DataSource 和JdbcTemplate 进行测试:
@ContextConfiguration(locations="classpath:springmvc.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringMVCTest {
@Autowired
DataSource dataSource;
@Autowired
JdbcTemplate jdbcTemplate;
@Test
public void testDataSource() {
try {
System.out.println(dataSource.getConnection());
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Test
public void testJdbcTemplate() {
System.out.println(jdbcTemplate);
}
}
public class Book {
private Integer id;
private String name;
private String author;
private BigDecimal price;
private Integer sales;
private Integer stock;
@Repository
public class BookDao {
@Autowired
JdbcTemplate jdbcTemplate;
public int saveBook(Book book) {
String sql = "insert into t_book(`name` , `author` , `price` , `sales` , `stock`) values(?,?,?,?,?)";
return jdbcTemplate.update(sql, book.getName(), book.getAuthor(),
book.getPrice(), book.getSales(), book.getStock());
}
public int deleteBookById(Integer id) {
String sql = "delete from t_book where id = ?";
return jdbcTemplate.update(sql, id);
}
public int updateBook(Book book) {
String sql = "update t_book set name=?,author=?,price=?,sales=?,stock=? where id = ?";
return jdbcTemplate
.update(sql, book.getName(), book.getAuthor(), book.getPrice(),
book.getSales(), book.getStock(), book.getId());
}
public Book queryBookById(Integer id) {
String sql = "select `id`,`name` , `author` , `price` , `sales` , `stock` from t_book where id = ?";
return jdbcTemplate.queryForObject(sql,
new BeanPropertyRowMapper(Book.class), id);
}
public List queryList() {
String sql = "select `id`,`name` , `author` , `price` , `sales` , `stock` from t_book";
return jdbcTemplate.query(sql, new BeanPropertyRowMapper(
Book.class));
}
}
@Service
public class BookService {
@Autowired
private BookDao bookDao;
public void saveBook(Book book) {
bookDao.saveBook(book);
}
public void deleteBookById(Integer id) {
bookDao.deleteBookById(id);
}
public void updateBook(Book book) {
bookDao.updateBook(book);
}
public Book queryBookById(Integer id) {
return bookDao.queryBookById(id);
}
public List queryList() {
return bookDao.queryList();
}
}
springDispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
1
springDispatcherServlet
/
POST请求乱码在web.xml中配置Filter解决
CharacterEncodingFilter
org.springframework.web.filter.
encoding
UTF-8
forceEncoding
true
CharacterEncodingFilter
/*
GET请求乱码在tomcat的server.xml配置文件中做如下的配置:
@RequestMapping(value = "/book")
@Controller
public class BookController {
@Autowired
private BookService bookService;
@RequestMapping(value = "/list")
public ModelAndView list() {
List bookList = bookService.queryList();
// 设置跳转去的地址是 /jsp/bookList.jsp页面
ModelAndView modelAndView = new ModelAndView("bookList");
//保存到request域中
modelAndView.addObject("list", bookList);
return modelAndView;
}
}
@RequestMapping(value="/addBook")
public ModelAndView addBook(Book book) {
bookService.saveBook(book);
ModelAndView modelAndView = new ModelAndView("redirect:/book/list");
return modelAndView;
}
注:添加成功之后还要跳转到列表页面,所以这里跳到list
需要在SpringMVC配置文件中添加如下的配置:
Controller中的代码:
@RequestMapping(value = "/deleteBook")
public ModelAndView deleteBook(Integer id) {
System.out.println("这是我要删除的图书id:" + id);
bookService.deleteBookById(id);
ModelAndView modelAndView = new ModelAndView("redirect:/book/list");
return modelAndView;
}
bookList.jsp页面中的代码:
图书列表
<%
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ request.getContextPath() + "/";
%>
修改页面中修改连接的跳转地址:
<a href="${ pageContext.request.contextPath }/book/getBook?id=${book.id}">修改a>td>
BookController中的getBook方法如下:
@RequestMapping(value="/getBook")
public ModelAndView getBook(Integer id) {
System.out.println("这是我要修改的图书id:" + id);
Book book = bookService.queryBookById(id);
ModelAndView modelAndView = new ModelAndView("bookEdit");
modelAndView.addObject("book", book);
return modelAndView;
}
bookEdit.jsp页面需要修改动态的提交地址
Controller中的方法:
@RequestMapping(value = "/updateBook")
public ModelAndView updateBook(Book book) {
bookService.updateBook(book);
ModelAndView modelAndView = new ModelAndView("redirect:/book/list");
return modelAndView;
}
效果图:
Restful 一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
6
REST(英文:Representational State Transfer,简称REST)描述了一个架构样式的网络系统,比如 web 应用程序。它首次出现在 2000 年 Roy Fielding 的博士论文中,他是 HTTP 规范的主要编写者之一。在目前主流的三种Web服务交互方案中,REST相比于SOAP(Simple Object Access protocol,简单对象访问协议)以及XML-RPC更加简单明了,无论是对URL的处理还是对Payload的编码,REST都倾向于用更加简单轻量的方法设计和实现。值得注意的是REST并没有一个明确的标准,而更像是一种设计的风格。
REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。
Web 应用程序最重要的 REST 原则是,客户端和服务器之间的交互在请求之间是无状态的。从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服务器在请求之间的任何时间点重启,客户端不会得到通知。此外,无状态请求可以由任何可用服务器回答,这十分适合云计算之类的环境。客户端可以缓存数据以改进性能。
在服务器端,应用程序状态和功能可以分为各种资源。资源是一个有趣的概念实体,它向客户端公开。资源的例子有:应用程序对象、数据库记录、算法等等。每个资源都使用 URI (Universal Resource Identifier) 得到一个唯一的地址。所有资源都共享统一的接口,以便在客户端和服务器之间传输状态。使用的是标准的 HTTP 方法,比如 GET、PUT、POST 和 DELETE。Hypermedia 是应用程序状态的引擎,资源表示通过超链接互联。
干货(简单明了):
Restful是一种设计风格。对于我们Web开发人员来说。就是使用一个url地址表示一个唯一的资源。然后把原来的请求参数加入到请求资源地址中。然后原来请求的增,删,改,查操作。改为使用HTTP协议中请求方式GET、POST、PUT、DELETE表示。
1、把请求参数加入到请求的资源地址中
2、原来的增,删,改,查。使用HTTP请求方式,POST、DELETE、PUT、GET分别一一对应。
添加 对应 post请求
删除 对应delete请求
修改 对应put请求
查询 对应get请求
传统的方式是:
比如:http://ip:port/工程名/资源名?请求参数
举例:http://127.0.0.1:8080/springmvc/book?action=delete&id=1
restful风格是:
比如:http://ip:port/工程名/资源名/请求参数
举例:http://127.0.0.1:8080/springmvc/book/1
请求的动作删除由请求方式delete决定
GET请求 对应 查询
http://ip:port/工程名/book/1 HTTP请求GET 表示要查询id为1的图书
http://ip:port/工程名/book HTTP请求GET 表示查询全部的图书
POST请求 对应 添加
http://ip:port/工程名/book HTTP请求POST 表示要添加一个图书
PUT请求 对应 修改
http://ip:port/工程名/book/1 HTTP请求PUT 表示要修改id为1的图书信息
DELETE请求 对应 删除
http://ip:port/工程名/book/1 HTTP请求DELETE 表示要删除id为1的图书信息
我们知道发起GET请求和POST请求,只需要在表单的form标签中,设置method=”get” 就是GET请求。
设置form标签的method=”post”。就会发起POST请求。而PUT请求和DELETE请求。要如何发起呢。
1、要有post请求的form标签
2、在form表单中,添加一个额外的隐藏域_method=”PUT”或_method=”DELETE”
3、在web.xml中配置一个Filter过滤器org.springframework.web.filter.HiddenHttpMethodFilter(注意,这个Filter一定要在处理乱码的Filter后面)
index.jsp页面中的代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
查询一个图书
查询全部图书
控制器:
@Controller
public class BookController {
@RequestMapping(value = "/book", method = RequestMethod.GET)
public String list() {
System.out.println("查询全部图书");
return "redirect:/index.jsp";
}
@RequestMapping(value = "/book/1", method = RequestMethod.GET)
public String queryBookById() {
System.out.println("查询id为1的图书信息");
return "redirect:/index.jsp";
}
@RequestMapping(value = "/book", method = RequestMethod.POST)
public String addBook(Book book) {
System.out.println("把book对象【" + book + "】插入到数据库");
return "redirect:/index.jsp";
}
@RequestMapping(value = "/book/1", method = RequestMethod.DELETE)
public String deleteBookById() {
System.out.println("删除id为1的图书信息");
return "redirect:/index.jsp";
}
@RequestMapping(value = "/book/1", method = RequestMethod.PUT)
public String updateBook(Book book) {
System.out.println("修改图书-->>" + book);
return "redirect:/index.jsp";
}
}
在Tomcat8之后的一些高版本,使用restful风格访问然后转发到jsp页面。就会有如下的错误提示:
解决办法有两种:
一:在jsp页面中,修改page指定
<%@ page language="java" contentType="text/html; charset=UTF-8"
isErrorPage="true"
pageEncoding="UTF-8"%>
二:在Controller中使用重定向跳转。而不用转发(默认)
前面我们已经知道如何编写和配置restful风格的请求和控制器。
那么 现在的问题是。如何接收restful风格请求的参数。比如前面的id值。
/book/{id} 中 {id} 是占位符
第一种情况,一个path参数:
/**
* @PathVariable 路径参数
* 表示把请求地址中{id}占位符所表示的地址参数。注入到 方法参数的id中。
*/
@RequestMapping(value = "/book/{id}", method = RequestMethod.GET)
public String queryBookById(@PathVariable(value = "id") Integer id) {
System.out.println("查询id为" + id + "的图书信息");
return "redirect:/index.jsp";
}
第二种情况,多个path参数(不怎么推荐多个参数):
/**
* @PathVariable 路径参数
* 表示把请求地址中{id}占位符所表示的地址参数。注入到 方法参数的id中。
*/
@RequestMapping(value = "/book/{id}/{name}", method = RequestMethod.GET)
public String queryBookById(@PathVariable(value = "id") Integer id,
@PathVariable("name") String name) {
System.out.println("这是参数id的值:" + id + ",参数name的值:" + name);
System.out.println("查询id为" + id + "的图书信息");
return "redirect:/index.jsp";
}
把前面的传统请求方式的图书的CRUD换成刚刚讲的Restful风格的图书模块的CRUD。只需要修改页面端的请求方式和地址,以及服务器端Controller的接收。
有jdbc.properties属性配置文件:
jdbc.user=root
jdbc.password=123456
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/springmvc
springmvc.xml配置文件:
web.xml中的配置:
restful
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceEncoding
true
CharacterEncodingFilter
/*
HiddenHttpMethodFilter
org.springframework.web.filter.HiddenHttpMethodFilter
HiddenHttpMethodFilter
/*
springDispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
1
springDispatcherServlet
/
index.html
index.htm
index.jsp
default.html
default.htm
default.jsp
页面端:
<a href="${pageContext.request.contextPath}/book">跳去图书管理a>
restful风格的图书列表查询:
@Controller
public class BookController {
@Autowired
private BookService bookService;
@RequestMapping(value = "/book", method = RequestMethod.GET)
public ModelAndView list() {
ModelAndView modelAndView = new ModelAndView("bookList");
modelAndView.addObject("list", bookService.queryList());
return modelAndView;
}
}
bookList页面中的代码:
删除、
注:${ pageContext.request.contextPath }/book/deleteBook?id=${book.id}也就不起作用了,可以删除,但不想修改以前的a标签的function,所以这里就不单独为form添加标签id了。还是用class="deleteA"
删除提示操作: