目录
项目准备:
数据库:mysql
服务器:tomcat
开发工具:eclipse
技术框架:spring+springMVC+mybatis+maven
项目功能:员工信息的增删改差,部门信息的增删改查,员工报销单创建修改提交,经理审核,总经理审核,财务打款登操作
员工密码修改,文件上传,分页等功能
1:Spring项目案例
项目功能模块如下:
表结构:
建表sql如下:
//Table: 报销单表
create table claim_voucher
(
id int not null auto_increment null COMMENT '报销编号',
cause varchar(100) null COMMENT '报销原因',
create_sn char(5) null COMMENT '创建人',
create_time datetime null COMMENT '创建时间',
next_deal_sn char(5) null COMMENT '待处理人',
total_amount double null COMMENT '报销总金额',
status varchar(20) null COMMENT '报销单状态',
primary key (id)
);
select
//Table: 报销单明细表
create table claim_voucher_item
(
id int not null auto_increment null COMMENT '编号',
claim_voucher_id int null COMMENT '报销单编号',
item varchar(20) null COMMENT '费用类型',
amount double null COMMENT '金额',
comment varchar(100) null COMMENT '描述',
primary key (id)
);
//Table: 处理记录表
create table deal_record
(
id int not null auto_increment null COMMENT '编号',
claim_voucher_id int null COMMENT '报销单',
deal_sn char(5) null COMMENT '处理人',
deal_time datetime null COMMENT '处理时间',
deal_way varchar(20) null COMMENT '处理类型',
deal_result varchar(20) null COMMENT '处理结果',
comment varchar(100) null COMMENT '备注',
primary key (id)
);
// Table: 部门表
create table department
(
sn char(5) not null COMMENT '编号',
name varchar(20) COMMENT '部门名称',
address varchar(100) COMMENT '部门地址',
primary key (sn)
);
// Table: 员工表
create table employee
(
sn char(5) not null COMMENT '员工主键',
password varchar(20) null COMMENT '密码',
name varchar(20) null COMMENT '姓名',
department_sn char(5) null COMMENT '所属部门',
post varchar(20) null COMMENT '职务',
filepath varchar(200) null COMMENT '附件地址',
primary key (sn)
);
create table test1
(
id int not null auto_increment COMMENT '主键',
name varchar(20) null COMMENT '姓名',
password varchar(20) null COMMENT '姓名',
primary key (id)
);
2:开始创建项目
maven主项目是OA:
OA _DAO(模型层MVC中的model,该模块是三层架构的dao层,负责实体bean与数据的映射,并且与数据交互,整合了mybatis和spring)
OA _BIZ(模型层MVC中的controller层,该模块是三层架构的service层,负责业务逻辑spring的事务控制,主要调用不同的dao层的数据库交互方法,整合了mybatis和spring)
OA _WEB(模型层MVC中的controller层,该模块是三层架构的controller层,负责与前段jsp页面数据交互,并且将业务产生的数据返回给jsp,主要调用不同的dao层的数据库交互方法,整合了mybatis和spring)
JSP页面是MVC中的view视图层
OA父项目的pom配置了子项目坐标
3:OA_DAO子项目结构
用员工表举例:
员工表 建表sql如下:
create table employee
(
sn char(5) not null COMMENT '员工主键',
password varchar(20) null COMMENT '密码',
name varchar(20) null COMMENT '姓名',
department_sn char(5) null COMMENT '所属部门',
post varchar(20) null COMMENT '职务',
filepath varchar(200) null COMMENT '附件地址',
primary key (sn)
);
部门表建表sql如下:
create table department
(
sn char(5) not null COMMENT '编号',
name varchar(20) COMMENT '部门名称',
address varchar(100) COMMENT '部门地址',
primary key (sn)
);
package com.thit.dao;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.sun.org.glassfish.gmbal.ParameterNames;
import com.thit.entity.Employee;
/**
* @author 79027
* 员工信息持久化等方法
*/
@Repository
public interface EmployeeDao {
//插入员工
public void insert(Employee d);
//修改员工
public void update(Employee d);
//根据员工id修改员工的登录密码
public void updatepass(@Param("sn") String sn,@Param("password") String pass);
//根据id修改员工
public void delete(String id);
//查询全部员工
public List<Employee> selectAll();
//根据id查询
public Employee selectByid(String id);
//根据职位和部门查询员工
public List<Employee> selectBydepartAndpost(@Param("dsn") String deparent_sn,
@Param("post")String post);
//手动分页查询
public List<Employee> selectAll_FENYE(@Param("pagenum") int pagenum,@Param("pagesize") int pagesize);
//查询员工表的总行数
public int selectCount();
}
对用的员工实体省略get和set方法:
public class Employee {
private String sn;// 员工主键
private String password;// 密码
private String name;// 姓名
private String department_sn;// 所属部门
private String post;// 职务
private String filepath;// '附件地址
private Department department;//员工所在部门信息
然后是对用的mapper映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--命名空间定义成接口名 -->
<mapper namespace="com.thit.dao.EmployeeDao">
<resultMap type="com.thit.entity.Employee" id="Employee">
<id column="sn" property="sn" javaType="String" />
<result column="password" property="password" javaType="String"/>
<result column="name" property="name" javaType="String"/>
<result column="department_sn" property="department_sn" javaType="String"/>
<result column="post" property="post" javaType="String"/>
<result column="filepath" property="filepath" javaType="String"/>
<!--根据员工查询员工的部门信息 -->
<association property="department" javaType="com.thit.entity.Department">
<id column="sn2" property="sn" javaType="String"/>
<result column="name2" property="name" javaType="String"/>
<result column="address2" property="address" javaType="String"/>
</association>
</resultMap>
<!--主键自增使用此属性 useGeneratedKeys="true" -->
<insert id="insert" parameterType="Employee" useGeneratedKeys="true">
insert into Employee(sn,password, name,department_sn,post,filepath)
values(#{sn},#{password},#{name},#{department_sn},#{post},#{filepath})
</insert>
<delete id="delete" parameterType="String">
delete from Employee where sn=#{sn}
</delete>
<update id="update" parameterType="Employee">
update Employee set
name=#{name},
department_sn=#{department_sn},
post=#{post},
filepath=#{filepath}
where sn=#{sn}
</update>
<update id="updatepass" parameterType="String">
update Employee set
password=#{password}
where sn=#{sn}
</update>
<select id="selectByid" parameterType="String"
resultMap="Employee">
select a.*,b.sn as sn2,b.name as name2,b.address as address2 from employee a LEFT JOIN department b on a.department_sn=b.sn
where a.sn=#{sn}
</select>
<select id="selectBydepartAndpost" parameterType="String"
resultMap="Employee">
select a.*,b.sn as sn2,b.name as name2,b.address as address2 from employee a LEFT JOIN department b on a.department_sn=b.sn
where 1=1
<if test="dsn!=null">
and a.department_sn=#{dsn}
</if>
<if test="post!=null">
and a.post=#{post}
</if>
</select>
<select id="selectAll" resultMap="Employee">
select a.*,b.sn as sn2,b.name as name2,b.address as address2 from employee a LEFT JOIN department b on a.department_sn=b.sn
</select>
<select id="selectCount" resultType="int">
select count(*) from employee
</select>
<select id="selectAll_FENYE" resultMap="Employee">
select * from employee limit #{pagenum},#{pagesize}
</select>
</mapper>
最后是spring_dao.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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--开启自动扫描 -->
<context:component-scan
base-package="com.thit.*"></context:component-scan>
<!--外部数据源 -->
<!-- 1.配置jdbc文件 -->
<!-- classpath和classpath*区别: classpath:只会到你的class路径中查找找文件。 classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找。
注意: 用classpath*:需要遍历所有的classpath,所以加载速度是很慢的;因此,在规划的时候,应该尽可能规划好资源文件所在的路径,尽量避免使用classpath*。 -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath:jdbc.properties" />
</bean>
<!-- 数据源配置 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"
value="${jdbc_driverClassName}"></property>
<property name="url" value="${jdbc_url}"></property>
<property name="username" value="${jdbc_username}"></property>
<property name="password" value="${jdbc_password}"></property>
</bean>
<!--mybatis和spring整合的 sqlsessionFactory配置 spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<!-- (类型 别名 包) 在mybatis映射文件中无需调用全称com.thit.entity 只需要直接写类名 相当于<typeAliases>
<package name="com.thit.entity"/> </typeAliases> -->
<property name="typeAliasesPackage" value="com.thit.entity"></property>
<property name="mapperLocations" value="classpath:mapper/*.xml"></property>
<!-- <property name="mapperLocations" value="classpath*:**/*Dao.xml"></property> -->
<!-- pagepagehelper新增配置mybatis的拦截器-->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<!-- 这里的几个配置主要演示如何使用,如果不理解,一定要去掉下面的配置 -->
<property name="properties">
<value>
helperDialect=mysql
<!-- reasonable=true
supportMethodsArguments=true
params=count=countSql
autoRuntimeDialect=true -->
</value>
</property>
</bean>
</array>
</property>
</bean>
<!-- mybatis和spring整合的 映射接口配置 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- DAO接口所在包名,Spring会自动查找其下的类 , 自动扫描了所有的XxxxMapper.xml对应的mapper接口文件, 只要Mapper接口类和Mapper映射文件对应起来就可以了 -->
<property name="basePackage" value="com.thit.dao"></property>
<!-- 此处用value关联 -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
</beans>
4:OA_BIZ子项目结构
员工表的service接口如下:
public interface EmployeeService {
public void insert(Employee d);
public void update(Employee d);
public void delete(String id);
public List<Employee> selectAll();
public Employee selectByid(String id);
public PageUtil selectAll_FENYE(int pagenum,int pagesize);
}
接口实现类
package com.thit.biz.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.thit.biz.EmployeeService;
import com.thit.dao.EmployeeDao;
import com.thit.entity.Employee;
import com.thit.tool.PageUtil;
@Service
public class EmployeeServiceImpl implements EmployeeService{
@Autowired
private EmployeeDao employeeDao;
@Override
public void insert(Employee d) {
// TODO Auto-generated method stub
//设置默认密码
d.setPassword("000000");
employeeDao.insert(d);
}
@Override
public void update(Employee d) {
// TODO Auto-generated method stub
employeeDao.update(d);
}
@Override
public void delete(String id) {
// TODO Auto-generated method stub
employeeDao.delete(id);
}
@Override
public List<Employee> selectAll() {
// TODO Auto-generated method stub
return employeeDao.selectAll();
}
@Override
public Employee selectByid(String id) {
// TODO Auto-generated method stub
return employeeDao.selectByid(id);
}
@Override
public PageUtil selectAll_FENYE(int pagenum,int pagesize) {
// TODO Auto-generated method stub
//查询总行数
int count=employeeDao.selectCount();
//创建page实体信息
PageUtil page=new PageUtil(pagenum,pagesize,count);
List<Employee> ee=employeeDao.selectAll_FENYE(page.getStartIndex(), pagesize);
page.setRecords(ee);
return page;
}
}
spring_biz.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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<import resource="classpath:spring_dao.xml"/>
<!--开启自动扫描 -->
<context:component-scan base-package="com.thit.*"></context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- 事务管理配置 -->
<bean id="txmanager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--通知 -->
<tx:advice id="txAdvice" transaction-manager="txmanager">
<tx:attributes>
<!--方法为只读 -->
<tx:method name="select*" read-only="true"/>
<tx:method name="get*" read-only="true"/>
<tx:method name="search*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<!--开启事务 -->
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="pointcutId" expression="execution(* com.thit.biz.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcutId"/>
</aop:config>
</beans>
pom配置主要为spring事务依赖和dao包的依赖
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.thit</groupId>
<artifactId>OA</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>OA_BIZ</artifactId>
<packaging>jar</packaging>
<dependencies>
<!-- 依赖dao -->
<dependency>
<groupId>com.thit</groupId>
<artifactId>OA_DAO</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- spring事务 依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${Spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${Spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${Spring-version}</version>
</dependency>
</dependencies>
</project>
5:OA_WEN子项目结构
首先来看员工controller
package com.thit.controller;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.thit.biz.DepartmentService;
import com.thit.biz.EmployeeService;
import com.thit.entity.Department;
import com.thit.entity.Employee;
import com.thit.tool.PageUtil;
@Controller
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@Autowired
private DepartmentService departmentService;
/**
* @param d
* @return
* 添加方法跳转到添加页面,在添加页面添加数据提交到真正的添加方法
*/
@RequestMapping("/to_add")
public String toAdd(HttpServletRequest request) {
//在此之前需要查询出来部门信息,
List<Department> dd= departmentService.selectAll();
request.setAttribute("dd",dd);
return "employee_add";
}
/**
* @param files
* @param d
* @param request
* @return
* 第四部:files需要跟from的表单name值相同,并且用@RequestParam注入参数
* 并且for循环MultipartFile解析得到不同的文件
*/
@RequestMapping("/add")
public String add(@RequestParam("files") MultipartFile[] files,Employee d,HttpServletRequest request) {
String a=Thread.currentThread().getContextClassLoader().getResource(".").getPath();
System.out.println(a);
String b=Thread.currentThread().getContextClassLoader().getResource("/").getPath();
System.out.println(b);
String c=this.getClass().getClassLoader().getResource(".").getPath();
System.out.println(c);
String d1=this.getClass().getClassLoader().getResource("/").getPath();
System.out.println(d1);
String e=this.getClass().getClassLoader().getResource("").getPath();
System.out.println(e);
String projectpath=request.getServletContext().getRealPath("");
System.out.println("项目路径:"+projectpath);
System.out.println("项目路径:"+request.getServletContext().getRealPath("/upload1/"));
this.getClass().getClassLoader().getResource("").getPath();
for (MultipartFile myfile : files) {
System.out.println("文件长度: " + myfile.getSize());
System.out.println("文件类型: " + myfile.getContentType());
System.out.println("文件输入框name的值: " + myfile.getName());
System.out.println("文件原名: " + myfile.getOriginalFilename());
System.out.println("========================================");
//保存文件 ,request.getServletContext().getRealPath得到项目服务器路径 拼接/upload/
saveFile(myfile,request.getServletContext().getRealPath("/upload/"));
}
String department_sn=request.getParameter("department_sn");
System.out.println("department_sn:"+department_sn);
System.out.println("部门实体:"+d);
employeeService.insert(d);
return "redirect:selectAll1";
}
private void saveFile(MultipartFile myfile,String path) {
// TODO Auto-generated method stub
try {
String savePath = path + myfile.getOriginalFilename();
//复制方法将文件
myfile.transferTo(new File(savePath));
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* @return
* 修改方法跳转到修改页面,在修改页面修改数据提交到真正的修改方法
*/
@RequestMapping("/to_update")
public String toUpdate(String sn,HttpServletRequest request) {
List<Department> dd= departmentService.selectAll();
Employee ee=employeeService.selectByid(sn);
request.setAttribute("dd",dd);
request.setAttribute("ee",ee);
return "employee_update";
}
@RequestMapping("/update")
public String update(Employee d) {
System.out.println("修改用员工:"+d);
employeeService.update(d);
return "redirect:selectAll1";
}
@RequestMapping("/remove")
public String remove(@RequestParam(value="sn") String id){
employeeService.delete(id);
return "redirect:selectAll1";
}
@RequestMapping("/selectAll")
public String selectAll(Map<String, Object> map){
map.put("list", employeeService.selectAll());
return "employee_list";
}
/**
* @return
* PageHelper分页方法 在sql不用写limit条件
* 很下面的手动分页存在一个即可 页面找的请求路径是 @RequestMapping("/selectAll1")
*/
@RequestMapping("/selectAlldasdasfsad")
public ModelAndView selectAll1(){
//pagehelper通过拦截Executor对象的query方法 将查询进行拦截
//从1开始
Page page=PageHelper.startPage(1, 5);
System.out.println("输出page:"+page.toString());
ModelAndView andView=new ModelAndView();
//只有紧跟在 PageHelper.startPage 方法后的第一个 Mybatis 的查询(Select)方法会被分页。
//只能拦截第一次查询,如果需要第二次查询则需要重新启动PageHelper.startPage
List<Employee> dd=employeeService.selectAll();
//第二次查询
//PageHelper.startPage(0, 10);
//List<Employee> dd1=employeeService.selectAll();
//PageInfo用来爆包装page
PageInfo pageInfo = page.toPageInfo();
// //显示长度
// System.out.println("页面显示长度:"+page.getPageSize());
// //显示页码
// System.out.println("当前页码:"+page.getPageNum());
// //总行数
// System.out.println("总行数:"+page.getTotal());
// System.out.println("是否是第一页:"+pageInfo.getNavigateFirstPage());
// System.out.println("总页数"+pageInfo.getPages());
// for (int a : pageInfo.getNavigatepageNums()) {
// System.out.println("导航页数:"+a);
// }
andView.addObject("list", dd);
andView.addObject("pagehelper", pageInfo);
andView.setViewName("employee_list");
return andView;
}
/**
* 手动分页方法
* @param pagenum 第几页
* @param pagesize 页面显示行数
* @return
*
*/
@RequestMapping("/selectAll1")
public ModelAndView selectAll_FENYE(Integer pagenum,Integer pagesize){
//创建分页对象
if(pagenum==null||pagenum.equals("")) {
pagenum=1;
}
if(pagesize==null||pagesize.equals("")) {
pagesize=5;
}
ModelAndView andView=new ModelAndView();
//只有紧跟在 PageHelper.startPage 方法后的第一个 Mybatis 的查询(Select)方法会被分页。
PageUtil page=employeeService.selectAll_FENYE(pagenum, pagesize);
andView.addObject("list",page.getRecords());
andView.addObject("page", page);
andView.setViewName("employee_list");
return andView;
}
@RequestMapping("/selectByid")
public Employee selectByid(String id){
return employeeService.selectByid(id);
}
@RequestMapping("/index")
public String index(Department d,HttpServletRequest request) {
String sn=request.getParameter("sn");
String name=request.getParameter("name");
String selestname=request.getParameter("selestname");
String[] test=request.getParameterValues("test");
for(String t :test) {
System.out.println("test:"+t);
}
System.out.println("sn:"+sn);
System.out.println("name:"+name);
System.out.println("name:"+selestname);
System.out.println("test:"+test);
System.out.println("实体:"+d);
return null;
}
}
spring_web.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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<import resource="classpath:spring_biz.xml"/>
<context:component-scan base-package="com.thit.*"></context:component-scan>
<!--文件上传第二步:注意:CommonsMultipartResolver的id是固定不变的,一定是multipartResolver,不可修改 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上传总文件大小限制,单位为字节-10Mb -->
<property name="maxUploadSize" value="10485760"></property>
<!-- 跟maxUploadSize差不多,不过maxUploadSizePerFile是限制每个上传文件的大小,
而maxUploadSize是限制总的上传文件大小 蛋单位是K 单个文件不超过1兆-->
<property name="maxUploadSizePerFile" value="1048576"></property>
<!-- 请求的编码格式 -->
<property name="defaultEncoding" value="utf-8"></property>
</bean>
<!-- 设置一个简单的异常解析器,当文件上传超过大小限制时跳转 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView" value="error"/>
</bean>
<!-- 是spring MVC为@Controllers分发请求所必须的, 扩充了注解驱动,可以将请求参数绑定到控制器参数 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 静态servlet -->
<mvc:default-servlet-handler/>
<!--视图解析器 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--WEB-INF下的页面不能直接访问 只能通过内部跳转 -->
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
<!-- <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
--> </bean>
<mvc:interceptors>
<mvc:interceptor>
<!--通配符配置 /**代表所有路径-->
<mvc:mapping path="/**"/>
<!-- 某一些请求除外 -->
<!-- <mvc:exclude-mapping path=""/> -->
<!-- 拦截器实体类 -->
<bean class="com.thit.global.LoginInterceptor"></bean>
</mvc:interceptor>
<!-- 接着可以配置多个mvc的过滤器 -->
</mvc:interceptors>
</beans>
然后是web的pom配置:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.thit</groupId>
<artifactId>OA</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>OA_WEB</artifactId>
<packaging>war</packaging>
<dependencies>
<!-- 依赖biz -->
<dependency>
<groupId>com.thit</groupId>
<artifactId>OA_BIZ</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- jstl依赖 servlet依赖 和springMVC依赖-->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${Spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${Spring-version}</version>
</dependency>
<!--第一步引入jar springMVC的文件上传依赖jar和io包 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<!-- <dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency> -->
</dependencies>
</project>
然后是项目最后的web.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--利用过滤器拦截request请求编码格式 -->
<!-- 编码过滤器 -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.png</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.ico</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.gif</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
<filter>
<filter-name>Encoding_filter</filter-name>
<filter-class>com.thit.global.EncodingFilter</filter-class>
<init-param>
<param-name>Encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Encoding_filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 方法一:这种方式默认读取WEB-INF下的(servlet-name)+(-servlet.xml) springmvc-servlet.xml并且名字是固定的 -->
<!-- <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern>
</servlet-mapping> -->
<!-- 方法二:初始化参数命名空间 namespace 必须配置文件在放入在web-inf目录下 -->
<!-- <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param> <param-name>namespace</param-name> <param-value>springmvc-servlet2</param-value>
</init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern> </servlet-mapping> -->
<!-- 方法三:初始化contextConfigLocation,将配置文件放到任意目录下 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- <param-value>WEB-INF/classes/springmvc/springmvc.xml</param-value> -->
<param-value>classpath:springmvc/spring_web.xml</param-value>
</init-param>
<!-- 如果值为正整数或者0时,表示容器在应用启动时就加载并初始化这个servlet,值越小, servlet的优先级越高,就越先被加载。
值相同时,容器就会自己选择顺序来加载。 -->
<!-- <load-on-startup>1</load-on-startup> -->
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 其中/和/*的区别: < url-pattern > / </ url-pattern > 不会匹配到*.jsp,即:*.jsp不会进入spring的
DispatcherServlet类 。 弊端:会导致静态文件(jpg,js,css)被拦截后不能正常显示。 想实现REST风格,事情就是麻烦一些。后面有解决办法还算简单。
< url-pattern > /* </ url-pattern > 会匹配*.jsp, 拦截/*,这是一个错误的方式,请求可以走到Action中,
但转到jsp时再次被拦截,不能访问到jsp。
-->
</web-app>
以上就是这个项目员工操作的主要逻辑,以为项目含有的功能包含员工添加修改删除,部门的创建修改删除和报销单信息的创建修改提交审核等功能,代码量比较大,不一一列举
6:项目总结和源码下载
在这项目中有很多功能,通过这些功能的编码 ,本人学习到一下几个点
项目总结
1:熟悉maven多级项目的创建
2:熟悉使用spring和mabtis和springMVC的整合
3:ssm整合的思想和各种注解的使用
4:熟悉使用spring事务配置原理,mybatis的mapper.xml
5:熟悉springMVC的底层原理。以及servlet和controller的对比
6:springMVC的编码过滤器的使用
7:springMVC的登录拦截器权限验证的使用
8:springMVCfileupload文件上传使用
9:手动分页的使用
10:mybatis拦截器pagehelper分页的方便性
11:定时任务的使用
源码附上:
链接:https://pan.baidu.com/s/1Zr2MHETiegtfMViVotKrfA 密码:8ysx