个人博客网:https://wushaopei.github.io/ (你想要这里多有)
一、返回值的设置
1、返回 String
【1】返回 String 默认情况
@RequestMapping("/hello1")
public String hello1() {
System.out.println("hello1被访问了");
// 默认是使用的转发
return "return";
}
默认情况下。如果有视图解析器。则返回的结果和视图解析器的前缀+返回值+后缀。拼接之后再转发。
如果没有视图解析器。而直接拿返回的字符串,做转发路径。
【2】显示转发
@RequestMapping("/hello2")
public String hello2() {
System.out.println("hello2被访问了");
// 在返回的字符串前面,加上 forward:表示显示的使用转发。
// 显示的转发,结果不会经过视图解析器。
// forward:/pages/user/return.jsp是绝对路径
// 绝对路径解析后得到的地址是:http://localhost:8080/springmvc_return/pages/user/return.jsp
// forward:pages/user/return.jsp是相对路径(相对于当前请求的地址)
// 当前请求的地址是:http://localhost:8080/springmvc_return/hello2
// 由相对路径的地址替换得到的路径是:http://localhost:8080/springmvc_return/pages/user/return.jsp
return "forward:/pages/user/return.jsp";
}
显示的转发是:
forward:
forward:后面可以是相对路径,也可以是绝对路径。(开发都是绝对)
相对路径(不要使用):
forward:pages/user/return.jsp
相对路径,在解析成为绝对路径的时候。会参照当前请求的地址。
如果当前请求地址是:http://localhost:8080/springmvc_return/return/hello2
解析之后得到的地址是:http://localhost:8080/springmvc_return/return/pages/user/return.jsp
绝对路径(开发只用绝对路径):
forward:/pages/user/return.jsp
当前请求地址是:http://localhost:8080/springmvc_return/return/hello2
绝对路径转得到最终地址后是:http://localhost:8080/springmvc_return/pages/user/return.jsp
【3】显示重定向
@RequestMapping("/hello3")
public String hello3() {
System.out.println("hello3被访问了");
// 在返回的字符串前面加redirect:就是显示重定向
// 只要是显示的转发或重定向都不会经过视图解析器
/**
* 相对路径:
* redirect:return<br/>
* 当前请求的地址是:http://localhost:8080/springmvc_return/return/hello3<br/>
* 相对路径在解析后会替换掉原来的资源:<br/>
* http://localhost:8080/springmvc_return/return/return<br/>
*
* 绝对路径:
* redirect:/return<br/>
* 当前请求地址是http://localhost:8080/springmvc_return/return/hello3,对绝对路径不影响<br/>
* 绝对路径解析后是:http://localhost:8080/springmvc_return/return
*/
return "redirect:/pages/user/return.jsp";
}
在SpringMVC框架中的redirect: 这个重定向。第一个斜杠表示到http://ip:port/工程名/
显示的重定向是:redirect:
重定向也可以使用相对路径(不允许使用),和绝对路径(使用)
相对路径(不允许使用):
redirect:return
相对路径在解析的时候是要参数当次请求地址的:
当前请求路径是:http://localhost:8080/springmvc_return/return/hello3
那么相对路径解析后会替换掉当前请求的资源得到:
http://localhost:8080/springmvc_return/return/return
绝对路径(使用这一种):
redirect:/return
绝对路径在解析的时候是不参数当次请求地址的:
当前请求路径是:http://localhost:8080/springmvc_return/return/hello3
解析绝对路径得到的地址是:http://localhost:8080/springmvc_return/return
2、返回ModelAndView
【1】返回modelAndView的**默认情况**
@RequestMapping("/modelAndView1")
public ModelAndView modelAndView1() {
System.out.println("modelAndView1方法被调用了!");
// 模型和视图
// 所谓视图。就是你要跳去的页面
ModelAndView modelAndView = new ModelAndView();
// setViewName设置视图名
// 这个视图名给什么值?
// 这里给的值,跟前面返回String类型的返回值一样
// 默认设置视图名,是会跟视图解析器做前缀+视图名+后缀得到最终的转发地址。
// 然后转发
modelAndView.setViewName("return");
return modelAndView;
}
【2】显示转发
显示的转发,都不会经过视图解析器。
forward:
@RequestMapping("/modelAndView2")
public ModelAndView modelAndView2() {
System.out.println("modelAndView2方法被调用了!");
// 模型和视图
// 所谓视图。就是你要跳去的页面
ModelAndView modelAndView = new ModelAndView();
// 设置视图名<br/>
// forward:显示的转发<br/>
// forward:/pages/user/return.jsp 是绝对路径
// 这个地址最终会解析成为http://ip:port/工程名/pages/user/return.jsp
// modelAndView.setViewName("forward:/pages/user/return.jsp");
// forward:显示的转发<br/>
// forward:pages/user/return.jsp 是相对路径
// 相对路径会参照当前请求的地址:http://localhost:8080/springmvc_return/return/modelAndView2
// 解析相对路径得到:http://localhost:8080/springmvc_return/return/pages/user/return.jsp
modelAndView.setViewName("forward:pages/user/return.jsp");
return modelAndView;
}
显示的转发也分相对路径和绝对路径:
显示的转发是:
forward:
forward:后面可以是相对路径,也可以是绝对路径。(开发都是绝对路径)而且显示的转发不会经过视图解析器
相对路径(不要使用):
forward:pages/user/return.jsp
相对路径,在解析成为绝对路径的时候。会参照当前请求的地址。
如果当前请求地址是:http://localhost:8080/springmvc_return/return/hello2
解析之后得到的地址是:http://localhost:8080/springmvc_return/return/pages/user/return.jsp
绝对路径(开发只用绝对路径):
forward:/pages/user/return.jsp
当前请求地址是:http://localhost:8080/springmvc_return/return/hello2
绝对路径转得到最终地址后是:http://localhost:8080/springmvc_return/pages/user/return.jsp
【3】显示重定向
@RequestMapping("/modelAndView3")
public ModelAndView modelAndView3() {
System.out.println("这是modelAndView3方法被调用了");
// 显示的重定向
// 显示的重定向 只需要在ViewName前面写上redirect:
// 同样分为相对路径和绝对路径
// 当前是绝对路径:redirect:/pages/user/return.jsp
// 这个绝对路径解析之后是 http://ip:port/工程名/pages/user/return.jsp
// ModelAndView modelAndView = new ModelAndView("redirect:/pages/user/return.jsp");
// 这是显示重定向中的相对路径
// 相对路径每次都会参照当前次请求地址:http://localhost:8080/springmvc_return/return/modelAndView3
// 解析之后会得到:http://localhost:8080/springmvc_return/return/pages/user/return.jsp
ModelAndView modelAndView = new ModelAndView("redirect:pages/user/return.jsp");
return modelAndView;
}
3、返回void
【1】没有返回值的**默认情况**
一般在实际开发中。我们都是禁止使用如以上这种方式。使用默认的请求资源名做为默认转发的逻辑资源名。
如果有需要,都是使用String类型显示标明返回的逻辑名。也就是说以上代码应该写成为:
@RequestMapping("/void1")
public void void1() {
System.out.println("说这是void1方法被调用了");
// ? 没有返回值的方法会跳到哪里去?
// 不管结果怎么样。开发的时候,不允许使用。
// 请求地址是:http://localhost:8080/springmvc_return/return/void1
// 得到的地址是:/springmvc_return/pages/user/return/void1.jsp
// SpringMVC会把你请求的资源地址,做为视图名默认返回
}
【2】显示转发
我们使用SpringMVC开发,并不推荐在Controller控制器中直接使用Requst对象进行转发操作。
@RequestMapping("/void2")
public void void2(HttpServletRequest request,HttpServletResponse response) {
System.out.println("这是void2方法被调用了");
try {
request.getRequestDispatcher("/pages/user/return.jsp").forward(request, response);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
【3】显示重定向
@RequestMapping("/void3")
public void void3(HttpServletRequest request , HttpServletResponse response) {
System.out.println("这是void3方法被调用了");
try {
// 在void返回值的情况下。也可以显示的重定向
// 在Controller控制器中,并不推荐使用response直接重定向
response.sendRedirect(request.getContextPath() + "/pages/user/return.jsp");
} catch (IOException e) {
e.printStackTrace();
}
}
【4】直接输出响应数据
@RequestMapping("/void4")
public void void4(HttpServletResponse response) {
// 解决响应中文乱码问题
response.setContentType("text/html; charset=UTF-8");
System.out.println("这是void4方法被调用了");
Person person = new Person(1, "华仔");
Gson gson = new Gson();
String personJson = gson.toJson(person);
try {
response.getWriter().write(personJson);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
二、数据在域中的保存
1、Request对象中保存数据
/**
* 把数据保存到reqeust域中
* @param request
*/
@RequestMapping("/requestScope")
public String requestScope(HttpServletRequest request) {
request.setAttribute("requestData1", "requestValue1");
return "scope";
}
- 在方法的参数上添加request域
- 在方法体内调用setAttribute方法
2、Session域中保存数据
@RequestMapping("/sessionScope")
public String sessionScope(HttpSession session) {
session.setAttribute("sessionKey1", "sessionValue1");
return "scope";
}
3、ServletContext域中保存数据
在Controller中的代码。在Controller的中获取SerlvetContext对象有两种方法,一种是@Autowired注入,一种是通过Session获取。
@Autowired
ServletContext servletContext;
/**
* 通过HttpSession对象获取ServletContext对象
*
* @param session
* @return
*/
@RequestMapping("/servletContextScope")
public String servletContextScope(/*HttpSession session*/) {
// session.getServletContext().setAttribute("context1", "contextValue1");
servletContext.setAttribute("context1", "contextValue1");
return "scope";
}
4、Map或Model或ModelMap形式保存数据在request域中
在四个域中,我们使用最频繁的域就是request对象。往request域对象中,保存数据,还在以下的几种形式。
我们可以在Controller的方法中,添加Map类型的参数,或者是Model类型的参数。或者是ModelMap类型的参数。都可以直接用来保存域数据到Request对象中。
Map全类名是: java.util.Map
Model全类名是: org.springframework.ui.Model
ModelMap全类名是: org.springframework.ui.ModelMap
@RequestMapping("/map2Request")
public String map2Request(Map<String, Object> map) {
//把数据保存到Map中,这些数据会自动的保存到request域中
map.put("map1", "mapValue1");
map.put("map2", "mapValue2");
return "scope";
}
@RequestMapping("/model2Reqeust")
public String model2Reqeust(Model model) {
// 调用Model.addAttribute保存数据,这些数据也会最终保存到request域中
model.addAttribute("model1", "美女1");
model.addAttribute("model2", "美女2");
return "scope";
}
@RequestMapping("/modelMap2Request")
public String modelMap2Request(ModelMap modelMap) {
// 调用ModelMap.addAttribute保存数据,这些数据也会最终保存到request域中
modelMap.addAttribute("modelMap1", "modelMapValue1");
return "scope";
}
BindingAwareModelMap我们称之为隐含模型。
/**
* BindingAwareModelMap(隐含模型)
* /\
* ||
* ||
* ExtendedModelMap -------->>>>>>Model接口
* /\
* ||
* ||
* ModelMap ------->>>>>> Map接口
*
*/
@RequestMapping("/mapAndModelAndModelMap")
public String mapAndModelAndModelMap(Map<String, Object> map, Model model, ModelMap modelMap) {
map.put("map1", "value1");
model.addAttribute("model1", "value1");
modelMap.addAttribute("modelMap1", "modelValue1");
System.out.println( map.getClass().getName() );
System.out.println( model.getClass().getName() );
System.out.println( modelMap.getClass().getName() );
return "scope";
}
5、ModelAndView方式保存数据到request域中
@RequestMapping("/modelAndView2Request")
public ModelAndView modelAndView2Request() {
ModelAndView modelAndView = new ModelAndView("scope");//需要一个View,保存模型,让它跳到“scope”页面
// 保存模型数据
// 保存到ModelAndView中的数据,最终还是会保存到request域中
modelAndView.addObject("modelandView1", "modelAndViewValue1");
return modelAndView;
}
6、@SessionAttributes保存数据到Session域中
@SessionAttributes 注解可以标注在类上。它的作用是指定哪些数据可以保存到Session域中。
@SessionAttributes(value = { "key1","key2" }, types = { String.class, Book.class })
value属性,它表示把request域中key为key1,key2的键值对信息,也保存到Session中
types属性,它表示把request域中value类型为String.class或Book.class类型的键值对,也保存到Session中
@RequestMapping("/sessionAttrubute1")
public String sessionAttrubute1(Map<String, Object> map) {
map.put("key1", "value1");
map.put("key2", "value2");
map.put("int1", new Integer(1));
return "scope";
}
7、@ModelAttribute注解
@ModelAttribute这个注解可以标注在方法和参数上。
@ModelAttribute三个常见作用:
- 被标注了@ModelAttribute的方法都会在Controller的目标方法之前执行。
- 目标方法的参数(JavaBean对象)会先从隐含模型中获取值传入。
- 被标注在参数上,参数值会按照指定的key从隐含模型中获取值。
@ModelAttribute
public void beforeFun(Map<String, Object> map) {
System.out.println("beforeFun()方法被调用");
map.put("personAA", new Person(1, "我是保存在隐含模型中的Person"));
}
/**
* 目标方法中的参数会按照类型名Person然后把首字母改小写,person。然后person做为key到隐含模型中取值注入到参数中<br/>
* @return
*/
@RequestMapping("/fun")
public String fun(@ModelAttribute(name="personAA") Person person) {
System.out.println("目标方法");
System.out.println("参数Person的值是:" + person);
return "scope";
}
三、传统的增删改查
1、准备单表的数据库
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;
2、创建一个web工程
3、创建配置
jdbc.properties配置文件内容:
jdbc.user=root
jdbc.password=root
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/springmvc
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"
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 http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 加载jdbc.properties属性配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 包扫描 -->
<context:component-scan base-package="com.webcode"></context:component-scan>
<!-- 配置数据库连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
<property name="driverClass" value="${jdbc.driverClass}" />
<property name="jdbcUrl" value="${jdbc.url}" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
4、创建JavaBean对象
public class Book {
private Integer id;
private String name;
private String author;
private Integer sales;
private Integer stock;
private BigDecimal price;
5、BookDao的编写和测试
BookDao接口
public interface BookDao {
public int saveBook(Book book);
public int deleteBookById(Integer id);
public int updateBook(Book book);
public Book queryBookById(Integer id);
public List<Book> queryBooks();
}
BookDaoImpl实现
@Repository
public class BookDaoImpl implements BookDao {
@Autowired
JdbcTemplate jdbcTemplate;
@Override
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());
}
@Override
public int deleteBookById(Integer id) {
String sql = "delete from t_book where id = ?";
return jdbcTemplate.update(sql, id);
}
@Override
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());
}
@Override
public Book queryBookById(Integer id) {
String sql = "select `name` , `author` , `price` , `sales` , `stock`,`id` from t_book where id = ?";
return jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Book>(Book.class), id);
}
@Override
public List<Book> queryBooks() {
String sql = "select `name` , `author` , `price` , `sales` , `stock`,`id` from t_book";
return jdbcTemplate.query(sql, new BeanPropertyRowMapper<Book>(Book.class));
}
}
BookDao的测试
@ContextConfiguration(locations = "classpath:applicatinContext.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class BookDaoTest {
@Autowired
BookDao bookDao;
@Test
public void testSaveBook() {
bookDao.saveBook(new Book(null, "国哥读的真好!", "学生说", 100000, 1, new BigDecimal(10000)));
}
@Test
public void testDeleteBookById() {
bookDao.deleteBookById(21);
}
@Test
public void testUpdateBook() {
bookDao.updateBook(new Book(21, "国哥讲的真好!", "学生说", 100000, 1, new BigDecimal(10000)));
}
@Test
public void testQueryBookById() {
System.out.println(bookDao.queryBookById(21));
}
@Test
public void testQueryBooks() {
bookDao.queryBooks().forEach(System.out::println);
}
}
6、创建BookService以及测试
BookService的接口
public interface BookService {
public void addBook(Book book);
public void deleteBookById(Integer id);
public void updateBook(Book book);
public Book queryBookById(Integer id);
public List<Book> queryBooks();
}
BookServiceImpl实现
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookDao bookDao;
@Override
public void addBook(Book book) {
bookDao.saveBook(book);
}
@Override
public void deleteBookById(Integer id) {
bookDao.deleteBookById(id);
}
@Override
public void updateBook(Book book) {
bookDao.updateBook(book);
}
@Override
public Book queryBookById(Integer id) {
return bookDao.queryBookById(id);
}
@Override
public List<Book> queryBooks() {
return bookDao.queryBooks();
}
}
BookService的测试
@ContextConfiguration(locations = "classpath:applicatinContext.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class BookServiceTest {
@Autowired
BookService bookService;
@Test
public void testAddBook() {
bookService
.addBook(new Book(null, "国哥缺个女朋友", "学生说new一个", 100000, 10, new BigDecimal(10000)));
}
@Test
public void testDeleteBookById() {
bookService.deleteBookById(22);
}
@Test
public void testUpdateBook() {
bookService.updateBook(new Book(22, "国哥缺个男淫", "学生说", 100000, 10, new BigDecimal(10000)));
}
@Test
public void testQueryBookById() {
System.out.println(bookService.queryBookById(22));
}
@Test
public void testQueryBooks() {
bookService.queryBooks().forEach(System.out::println);
}
}
7、拷贝CRUD页面到WebContent目录下
到web.xml中去配置SpringMVC的前端控制器:
<!-- The front controller of this Spring Web application, responsible for handling all application requests -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicatinContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
配置视图解析器在applicationContext配置文件中
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/book/"/>
<property name="suffix" value=".jsp" />
</bean>
8、图书列表功能的实现
不要忘了导入两个jar包 JSTL标签库
taglibs-standard-impl-1.2.1.jar
taglibs-standard-spec-1.2.1.jar
BookController的代码:
@RequestMapping("/book")
@Controller
public class BookController {
@Autowired
private BookService bookService;
/**
* 查询全部图书
*
* @return
*/
@RequestMapping("/list")
public ModelAndView list() {
//2 转发到book/bookList.jsp页面
ModelAndView modelAndView = new ModelAndView("bookList");
//1 查询全部的图书,保存到request域中
modelAndView.addObject("bookList", bookService.queryBooks());
return modelAndView;
}
}
index.jsp添加一个进入功能的连接:
<body>
<a href="${ pageContext.request.contextPath }/book/list">图书管理</a>
</body>
修改book/bookList.jsp页面的内容:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>图书列表</title>
<%
String basePath = request.getScheme()
+ "://"
+ request.getServerName()
+ ":"
+ request.getServerPort()
+ request.getContextPath()
+ "/";
%>
<base href="<%=basePath %>" />
<style type="text/css">
table {
border: 1px blue solid;
width: 700px;
border-collapse: collapse;
}
td,th{
border: 1px green solid;
}
div.menu {
width: 700px;
text-align: right;
}
</style>
</head>
<body>
<center>
<h2>图书列表管理页面</h2>
<div class="menu"><a href="#">添加图书</a></div>
<table>
<tr bgcolor="#FF8888">
<th>书名</th>
<th>作者</th>
<th>价格</th>
<th>销量</th>
<th>库存</th>
<th>操作</th>
</tr>
<c:forEach items="${ requestScope.bookList }" var="book">
<tr>
<td>${ book.name }</td>
<td>${ book.author }</td>
<td>${ book.price }</td>
<td>${ book.sales }</td>
<td>${ book.stock }</td>
<td><a href="#">删除</a>、<a href="#">修改</a></td>
</tr>
</c:forEach>
</table>
</center>
</body>
</html>
9、图书添加功能的实现
修改bookList.jsp页面中的添加图书地址:
<div class="menu"><a href="${ pageContext.request.contextPath }/book/bookEdit.jsp">添加图书</a></div>
添加BookController中添加的方法:
@RequestMapping("/add")
public ModelAndView add(Book book) {
// 1 调用bookService保存
bookService.addBook(book);
// 2 重定向回图书列表管理页面
return new ModelAndView("redirect:/book/list");
}
修改bookEdit.jsp页面的请求地址:
<form action="${ pageContext.request.contextPath }/book/add" method="post">
在web.xml中配置解决POST乱码的Filter过滤器:
<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>
<init-param>
<param-name>forceRequestEncoding</param-name> <!-- 请求端编码 -->
<param-value>true</param-value> 《!--是否使用--》
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name> <!-- 响应端编码 -->
<param-value>true</param-value> <!-- 是否使用 -->
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name> <!-- 字符集过滤 -->
<url-pattern>/*</url-pattern> <!-- 工程名后所有访问都使用 -->
</filter-mapping>
10、图书删除功能的实现
我们需要导入js静态资源:
<script type="text/javascript" src="${ pageContext.request.contextPath }/script/jquery-1.7.2.js"></script>
解决SpringMVC无法加载静态资源问题:
我们配置的前端控制器。的拦截地址是<url-pattern>/</url-pattern>。
<!-- Map all requests to the DispatcherServlet for handling -->
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
SpringMVC的前端控制器的拦截地址和Tomcat服务器中的一个默认的Servlet程序相冲突了
现在解决请求地址冲突的方案是,添加springMVC的标配:
<!-- SpringMVC开发的标准配置 -->
<!-- 让SpringMVC支持静态资源的请求 -->
<mvc:default-servlet-handler/>
<!-- 配置SpringMVC的注解驱动,提供了SpringMVC的高级功能。 -->
<mvc:annotation-driven></mvc:annotation-driven>
修改bookList.jsp页面,添加删除的提示事件,
<a class="deleteA" href="${ pageContext.request.contextPath }/book/delete?id=${book.id}">删除</a>、
<script type="text/javascript" src="${ pageContext.request.contextPath }/script/jquery-1.7.2.js"></script>
<script type="text/javascript">
$(function(){
// 给删除绑定单击事件
$("a.deleteA").click(function(){
// 提示用户确认操作
return confirm("你确定要删除【" + $(this).parent().parent().find("td:first").text() + "】吗?");
});
});
</script>
BookController控制器的代码:
@RequestMapping("/delete")
public ModelAndView delete(Integer id) {
// 调用BookService删除图书
bookService.deleteBookById(id);
// 重定向 到图书列表管理页面
return new ModelAndView("redirect:/book/list");
}
11、图书更新功能的实现
第一步:点击【修改】连接,把需要更新的图书信息,填充到bookEdit.jsp页面
bookList.jsp页面中修改的连接地址:
<a href="${ pageContext.request.contextPath }/book/getBook?id=${book.id}">修改</a>
BookController控制器的代码:
@RequestMapping("/getBook")
public ModelAndView getBook(Integer id) {
ModelAndView modelAndView = new ModelAndView();
// 模型 是需要修改的图书===调用BookService.queryBookById
modelAndView.addObject("book", bookService.queryBookById(id));
// 设置跳转的页面
modelAndView.setViewName("bookEdit");
return modelAndView;
}
bookEdit.jsp页面输出数据:
<form action="${ pageContext.request.contextPath }/book/add" method="post">
<table>
<tr>
<td>书名</td>
<td><input name="name" type="text" value="${ requestScope.book.name }"/></td>
</tr>
<tr>
<td>作者</td>
<td><input name="author" type="text" value="${ requestScope.book.author }" /></td>
</tr>
<tr>
<td>价格</td>
<td><input name="price" type="text" value="${ requestScope.book.price }" /></td>
</tr>
<tr>
<td>销量</td>
<td><input name="sales" type="text" value="${ requestScope.book.sales }" /></td>
</tr>
<tr>
<td>库存</td>
<td><input name="stock" type="text" value="${ requestScope.book.stock }"/></td>
</tr>
<tr>
<td align="center" colspan="2">
<input type="submit" />
</td>
</tr>
</table>
</form>
第二步:提交数据给服务器确认修改
BookController中的代码:
@RequestMapping("/update")
public ModelAndView update(Book book) {
//保存修改
bookService.updateBook(book);
//跳到图书列表管理页面
return new ModelAndView("redirect:/book/list");
}
bookEdit.jsp修改页面:
<form action="${ pageContext.request.contextPath }/book/${ empty param.id ? 'add':'update'}" method="post">
<input type="hidden" name="id" value="${ requestScope.book.id }"/>
<table>
<tr>
<td>书名</td>
<td><input name="name" type="text" value="${ requestScope.book.name }"/></td>
</tr>
<tr>
<td>作者</td>
<td><input name="author" type="text" value="${ requestScope.book.author }" /></td>
</tr>
<tr>
<td>价格</td>
<td><input name="price" type="text" value="${ requestScope.book.price }" /></td>
</tr>
<tr>
<td>销量</td>
<td><input name="sales" type="text" value="${ requestScope.book.sales }" /></td>
</tr>
<tr>
<td>库存</td>
<td><input name="stock" type="text" value="${ requestScope.book.stock }"/></td>
</tr>
<tr>
<td align="center" colspan="2">
<input type="submit" />
</td>
</tr>
</table>
</form>