SpringMVC与Spring综合小案例RestfulCRUD

一、前言

        关于这个CRUD的小案例的编写因为忙于应对学校课程与考试拖了一段时间,现在总结复习一下全部过程,加深印象。

二、关于CRUD小案例的环境搭建

     1、首先创建好一个web项目。在WebContent/WEB-INF/lib下导入相应jar包,因为我是Spring和SpringMVC综合使用的,所以先导入了

commons-logging-1.2.jar、spring-aop-4.2.0.RELEASE.jar、spring-beans-4.2.0.RELEASE.jar、spring-context-4.2.0.RELEASE.jar、spring-core-4.2.0.RELEASE.jar、spring-expression-4.2.0.RELEASE.jar、spring-jdbc-4.2.0.RELEASE.jar、spring-orm-4.2.0.RELEASE.jar、spring-tx-4.2.0.RELEASE.jar、spring-web-4.2.0.RELEASE.jar、spring-webmvc-4.2.0.RELEASE.jar,这些框架包。

    2、写配置。直接在项目下创建一个源目录conf,然后创建一个springmvc-servlet.xml的配置文件,一个applicationContext.xml的配置文件,把springmvc和spring的配置分开写。我的项目结构如下SpringMVC与Spring综合小案例RestfulCRUD_第1张图片

       2.1 下面准备写配置文件。

             首先在web项目的web.xml中添加前端控制器配置,web.xml文件一般在WEB-INF下,没有就直接找到Server项目下的web.xml拷过来,留下头部,多余的可以全删掉,其实在web项目创建时是可以勾选自动创建的。还是写配置吧。

在web.xml中添加前端控制器DispatcherServlet


	
	
		springDispatcherServlet
		org.springframework.web.servlet.DispatcherServlet
		
			contextConfigLocation
             
			classpath:springmvc-servlet.xml
		
		1
	

	
	
		springDispatcherServlet
		/
	

写完这个前端控制器之后莫急,目前还只是把SpringMVC的配置文件加载了还有Spring的配置文件没有加载。这个时候需要用到

contextConfigLocation来加载spring的配置文件,不然最后运行时会找不到资源,在使用ClassPathXmlApplicationContext("applicationContext.xml")获取ioc容器时报出Exception in thread "main" java.lang.NoClassDefFoundError: org.springframework.beans.FatalBeanException异常。

 
  
    org.springframework.web.context.ContextLoaderListener
  
  
  
    contextConfigLocation
    classpath:applicationContext.xml
  

      2.2 一次性解决中文乱码问题,在web.xml中添加SpringMVC提供的Filter---->CharacterEncodingFilter


	
		CharacterEncodingFilter
		org.springframework.web.filter.CharacterEncodingFilter
		
            
			encoding
			UTF-8
		
		
            
			forceEncoding
			true
		
	
	
		CharacterEncodingFilter
		/*
	

       2.3 web.xml暂时配置这么多了,接下来是springmvc-servlet.xml的配置,在SpringMVC的配置文件中,按照当前的需求只需要开启包扫描和配置一个视图解析器用于响应地址的拼接就行了


	
	
	
		
		
		
	

        2.4 由于是连接的SqlServer数据库所以我用到了外部配置文件

        首先还是导入支持数据库连接的包:c3p0-0.9.5.2.jar,mchange-commons-java-0.2.12.jar,mssql-jdbc-6.4.0.jre8.jar,在c3p0的新版本中这两个都必须要,导完包后就是新建一个外部文件dbconfig.properties,具体内容为

SpringMVC与Spring综合小案例RestfulCRUD_第2张图片

就是配置数据库连接的一些基本信息。然后在spring的配置文件applicationContext.xml中配置数据源,同时打开包扫描,将数据连接源给spring提供的JdbcTemplate管理,这个是用来操作数据库的。


	
	
	
	
	
		
		
		
		
	
	
	
		
		

        2.5 因为这个CRUD小案例使用的是Rect风格,所以还需要再web.xml中添加一个配置


	
		HiddenHttpMethodFilter
		org.springframework.web.filter.HiddenHttpMethodFilter
	
	
		HiddenHttpMethodFilter
		/*
	

         2.6 数据库sql文件

--使用的数据库表创建语句

use testEmployee
create table employee(
 employeid int primary key identity(1,1),
 id int unique,
 lastName varchar(40),
 email varchar(50),
 genden int
 )
 alter table employee add departmentid int
 alter table employee
 add constraint FK_Departmentid FOREIGN KEY(departmentid) REFERENCES Department(id)
 create table Department(
 departmentid int identity(1,1),
 id int primary key,
 departmentName varchar(40)
 )

         2.7 基础环境搭建基本结束了

三、建立包结构

         3.1如图

 SpringMVC与Spring综合小案例RestfulCRUD_第3张图片

         3.2  EmployeeController.java文件是用来处理请求控制的,EmployeeDao.java是员工类的CRUD操作类,同理DepartmentDao.java是部门类的CRUD操作类,MyJdbcTemplate.java这个类很关键,是获取ioc容器中配置的数据库连接管理对象的。entity实体包中的分别是员工、部门bean。

四、具体步骤

        4.1 做一个简略的index.jsp,作为整个web项目的首页,在浏览器请求index.jsp的时候显示全部员工信息。在这个地方直接使得index.jsp页面加载就转发请求/emps给后台。在index.jsp中只使用jstl标签的请求转发到后台处理就行了,也就是给springmvc去处理请求。

        4.2 先把EmployeeController.java类添加@Controller注解使得它能够被ioc扫描到。然后添加能够处理“/emps”请求的方法

@Autowired
	EmployeeDao employeeDao;
	@Autowired
	DepartmentDao departmentDao;
	/**
	 * 
	 * Title: allEmployee
	 * Description: 处理初始页面的请求,进入员工列表页面
	 * @return 返回员工列表页面的地址
	 */
	@RequestMapping("/emps")
	public String allEmployee(Model model) {
		System.out.println("初始化完成,开始查询所有员工数据····");
		/**查询到所有用户信息,添加到请求域中*/
		List searchAllEmployee = employeeDao.searchAllEmployee();
		model.addAttribute("emps", searchAllEmployee);
		System.out.println("跳转到员工页面···");
		return "listEmployee";
	}

   代码中的@RequestMapping("/emps")是标识此方法能够处理“/emps”请求。参数Model model能够将元素添加到请求域中,在jsp页面可以获取到。我显示利用employeeDao查询了所有的员工数据封装成了集合返回然后加入到请求域中,最后返回响应页面的页面名,在视图解析器处拼接好完整的地址为/WEB-INF/pages/listEployee.jsp。注意EmployeeDao.java是要添加@Repository注解保证其能被ioc容器扫描到,DepartmentDao.java也是一样。

查询所有员工的方法:

/**
	 * 
	 * Title: searchAllEmployee
	 * Description: 查询员工所有数据,并封装成一个list集合返回
	 * @return 返回员工集合
	 */
	public List searchAllEmployee(){
		String sql = "select * from employee";
		//查询到的数据封装成一个list集合返回
		List employeeList = MyJdbcTemplate.getInstance().query(sql,new BeanPropertyRowMapper<>(Employee.class));
		System.out.println("成功返回查询的结果····");
		for(Employee s:employeeList) {
			/**获取部门所有数据*/
			List searchAllDepartment = departmentDao.searchAllDepartment();
			for(int a=0;a

因为是直接从员工表上查询的数据通过JdbcTemplate自动封装成employee对象的,所以员工对象的部门id只是id,部门属性为null,所以又查询了部门信息用作对比,把员工对象的部门赋值。后面的

        Employee employee = employeeList.get(employeeList.size() - 1);
        /**设置当前id为已有id,然后再增加员工时id加一*/
        Employee.autoId = employee.getId();

      这两句是为了实现员工添加时id的自增,检查出数据库中的员工id最后一个是多少然后加1给作为新增员工的id

好像忘了把employee类的代码贴出来了

package com.feilonkji.entity;

/**
 * 
 * @ClassName: Employee
 * @Description: TODO 员工实体类
 * @author zr
 * @date 2020年4月14日
 * @version V1.8
 */
public class Employee {
	public static int autoId;
	//员工id
	private Integer id;
	//员工姓名
	private String lastName;
	//员工邮箱
	private String email;
	//员工性别,1表示male,0表示female
	private Integer gender;
	//员工所在部门id
	private Integer departmentId;
	//部门对象
	private Department department;
	public Employee() {
		
	}
	public Employee(Integer id, String lastName, String email, Integer gender, Department department) {
		super();
		this.id = id;
		this.lastName = lastName;
		this.email = email;
		this.gender = gender;
		this.department = department;
	}
	public Integer getId() {
		return id;
	}
	public  void setId(Integer id) {
		this.id = id;
	}
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public Integer getGender() {
		return gender;
	}
	public void setGender(Integer gender) {
		this.gender = gender;
	}

	public Integer getDepartmentId() {
		return departmentId;
	}
	public void setDepartmentId(Integer departmentId) {
		this.departmentId = departmentId;
	}
	
	public Department getDepartment() {
		return department;
	}
	public void setDepartment(Department department) {
		this.department = department;
	}
	@Override
	public String toString() {
		return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender
				+ ", departmentId=" + departmentId + ", department=" + department + "]";
	}

	
	
}

       4.3  当员工集合放到请求域中的时候,就可以在员工展示页面获取显示了。新建listEployee.jsp

      在其中利用el表达式和jstl标签遍历员工集合,当然用这个必须要导入jar包的:jstl.jar、standard.jar,这两个包需要在创建index.jsp时就要导入。


<%pageContext.setAttribute("ctp", request.getContextPath()); %>

员工列表

ID lastName email gender departmentName EDIT DELETE
${emp.id} ${emp.lastName} ${emp.email} ${emp.gender == 1?"男":"女"} ${emp.department.departmentName} update delete
添加员工

使用了标签来进行遍历员工集合的信息。

效果图如下:SpringMVC与Spring综合小案例RestfulCRUD_第4张图片

员工展示列表就完成了。

      4.4 接下来添加员工,确定一下添加员工的页面,新建addEmployee.jsp页面用来作为员工信息添加页面。顺便提一句我的页面是存放在WebContent/WEB-INF/pages/下。

添加员工页面:SpringMVC与Spring综合小案例RestfulCRUD_第5张图片。哈哈超级简单的页面,就一个form表单,但是也满足需求了。

因为在下拉菜单中显示部门信息,所以我做了一个过度处理。有处理方法把部门信息存放到请求域中后在转发到员工添加页面。

       首先是添加员工使用了a标签发送toaddpage请求。然后在EmployeeController.java类中添加请求处理的相应方法。

/**
	 * 
	 * Title: toAddPage
	 * Description: 处理请求,去员工添加页面
	 * @return
	 */
	@RequestMapping("/toaddpage")
	public String toAddPage(Model model) {
		System.out.println("开始进入员工添加页面····");
		/**查询到所有的部门信息添加到请求域中*/
		List searchAllDepartment = departmentDao.searchAllDepartment();
		model.addAttribute("departments",searchAllDepartment);
		model.addAttribute("employee",new Employee(12,"李四","[email protected]",0,new Department()));
		System.out.println("进入员工添加页面····");
		return "addEmployee";
	}

这个toAdPage(Model model)方法就是做过度处理。先将所有部门信息添加到请求域中保证jsp页面能够获取信息,然后再响应跳转到真正的员工添加页面addEmployee.jsp。方法中的model.addAttribute("employee",new Employee(12,"李四","[email protected]",new Department())),先不用管,这个是后面使用springmvc提供的标签库配合回显数据用的测试。

        之后便是到了addEmployee.jsp页面了,图示效果上面已经发过了,来看看代码。

	<%--设置项目的绝对路径 --%>
	<%pageContext.setAttribute("ctp",request.getContextPath());%>
	

员工添加

lastName:
email:
gender:
男: 女:
dept:

总的来讲就是一个form表单,然后就是下拉选项框了, name:
email:
gender: 男: 女: dept:

首先还是要在jsp页面添加标签资源<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

主要作用还是其中这个modelAttribute其实也可以不写,但是就会出现一个问题,就是在请求处理方法那里添加到请求域中的员工对象就没啥用了,因为它会默认去找一个叫commond的元素,这个modelAttribute其实就是改掉默认回显的元素的key名称。如果没有添加commond这个元素的话会报异常的。然后其中的path属性就相当于原生标签中的name属性。这个标签就有自动遍历的功能,itmes是要遍历的对象,itemLabel是遍历后显示在页面上的内容的对象的属性,itemValue则是对应显示内容的要提价的对象的属性,这个可能有点拗口,具体理解还是要实践。在这里还存在着一个问题,就是在修改提交之后,因为我是全部信息都可以修改,然后提交后自动封装成员工对象后每一个对象都有新值,如果当员工姓名不能修改时那就必须要有一个过渡操作了,这也是为什么我上面的处理方法中员工对象参数会加一个@ModelAttribute("employee")的注解了,这个是表示这个参数要先从隐含模型中先取值,然后再封装,也就保证了当修改提交的信息不全时,也不至于为null值。使用@ModelAttribute注解的方法会先再所有的方法运行前执行完毕。在方法的参数上使用required=false是设置请求可以不带请求参数,以至于不会报异常。

       @ModelAttribute
	public void myModelAttribute(@RequestParam(value="id",required=false)Integer id,Model model) {
		if(id != null) {
			Employee searchEmployee = employeeDao.searchEmployee(id);
			model.addAttribute("employee",searchEmployee);
		}
	}

      4.6  最后是删除了,删除操作有一个要注意的点,因为也是在员工列表页面的table表中,但是又要使用delete请求方式单纯的使用a标签是行不通过的,只能通过form表单来改请求方式,最后我还是给删除标签添加了a标签然后绑定了点击事件,禁掉了默认跳转行为。在这里添加了jquery到项目中,SpringMVC与Spring综合小案例RestfulCRUD_第8张图片。然后在员工列表做出了如下操作

员工列表

ID lastName email gender departmentName EDIT DELETE
${emp.id} ${emp.lastName} ${emp.email} ${emp.gender == 1?"男":"女"} ${emp.department.departmentName} update delete
添加员工

删除绑定了一个点击事件。在外面放了一个form表单更改请求方式为DELETE,在script中获取点击的对应的请求路径赋值给表单的action,然后提交。又有一个注意的点,如果仅仅是这样操作是会报异常的找不到jquery.js文件,因为这个文件是静态资源文件,在web.xml时添加了前端控制器,拦截除了.jsp页面请求之外的一切请求,所有会找不到jquery.js文件,这个时候就需要在springmvc-servlet.xml中添加两个语句分别是:


	
	
	
	

这两条语句都必须加上。才能保证动态,静态资源都能访问。

在EmployeeController.java中添加删除的请求处理方法:

/**
	 * 
	 * Title: deleEmp
	 * Description: 删除处理
	 * @param id
	 * @return
	 */
	@RequestMapping(value="/emp/{id}",method=RequestMethod.DELETE)
	public String deleEmp(@PathVariable("id")Integer id) {
		employeeDao.remove(id);
		return "redirect:/emps";
	}
	@Override
	public boolean remove(Integer id) {
		// TODO Auto-generated method stub
		String sql = "delete from employee where id=?";
		MyJdbcTemplate.getInstance().update(sql,id);
		return true;
	}

删除后重定向到员工列表页面。至此基本功能全部完成

五、总结

        这次案例对spring,springmvc的具体使用应该囊括了70%左右。在一些组合的用法上还是有许多不足,磕磕绊绊走了很多弯路,索性是完成了。这一次的复习还可以。后续还会继续学习使用。如果有不正确的地方还请大佬指正。

你可能感兴趣的:(复习日记,java,spring,web)