SpringMVC(二)返回值设置、数据在域中的保存与SpringMVC案例

个人博客网: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";
	}
  1. 在方法的参数上添加request域
  2. 在方法体内调用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.classBook.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三个常见作用:

  1. 被标注了@ModelAttribute的方法都会在Controller的目标方法之前执行。
  2. 目标方法的参数(JavaBean对象)会先从隐含模型中获取值传入。
  3. 被标注在参数上,参数值会按照指定的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"><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页面中修改的连接地址:

<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>
posted @ 2019-11-04 17:00  维宇空灵  阅读(276)  评论(0编辑  收藏  举报