zoukankan      html  css  js  c++  java
  • 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;
    				 700px;
    				border-collapse: collapse;
    			}
    			td,th{
    				border: 1px green solid;
    			}
    			div.menu {
    				 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>
  • 相关阅读:
    2.17NOIP模拟赛(by hzwer) T2 小奇的序列
    2.17NOIP模拟赛(by hzwer) T1 小奇挖矿
    题解【洛谷P3662】[USACO17FEB]Why Did the Cow Cross the Road II S
    题解【CF886B】Vlad and Cafes
    题解【CJOJ1070/UVA】嵌套矩形
    题解 【CF381A】 Sereja and Dima
    何时使用UI层的智能表单技术
    开机加电到系统打开究竟发生了什么?(1)
    asp.net MVC 常见安全问题及解决方案
    HDU 4422 The Little Girl who Picks Mushrooms【水题】
  • 原文地址:https://www.cnblogs.com/wushaopei/p/11793030.html
Copyright © 2011-2022 走看看