关山难越,谁悲失路之人;萍水相逢,尽是他乡之客。
百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程教程 > 技术文章 > 正文

Spring框架学习第七天

guanshanw 2023-09-12 10:39 41 浏览 0 评论

1.拦截器概述

Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并做相应的处理。例如通过拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等

要使用Spring MVC中的拦截器,就需要对拦截器类进行定义和配置。通常拦截器类可以通过两种方式来定义。一种是通过实现HandlerInterceptor接口,或继承HandlerInterceptor接口的实现类(如HandlerInterceptorAdapter)来定义;另一种是通过实现WebRequestInterceptor接口,或继承WebRequestInterceptor接口的实现类来定义。

以实现HandlerInterceptor接口的定义方式为例,自定义拦截器类的代码如下所示。

public class CustomInterceptor implements HandlerInterceptor{

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception

{

return false;

}

@Override

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

}

@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

}

}

· preHandler()方法:该方法会在控制器方法前执行,其返回值表示是否中断后续操作。当其返回值为true时,表示继续向下执行;当其返回值为false时,会中断后续的所有操作(包括调用下一个拦截器和控制器类中的方法执行等)。

· postHandle()方法:该方法会在控制器方法调用之后,且解析视图之前执行。可以通过此方法对请求域中的模型和视图做出进一步的修改。

· afterCompletion()方法:该方法会在整个请求完成,即视图渲染结束之后执行。可以通过此方法实现一些资源清理、记录日志信息等工作。

拦截器的配置

<! -- 配置拦截器 -->

<mvc:interceptors>

<! --使用bean直接定义在<mvc:interceptors>下面的Interceptor将拦截所有请求-->

<bean class="com.itheima.interceptor.CustomInterceptor"/>

<! -- 拦截器1-->

<mvc:interceptor>

<! -- 配置拦截器作用的路径 -->

<mvc:mapping path="/**"/>

<! -- 配置不需要拦截器作用的路径 -->

<mvc:exclude-mapping path=""/>

<! -- 定义在<mvc:interceptor>下面的,表示对匹配路径的请求才进行拦截-->

<bean class="com.itheima.interceptor.Interceptor1" />

</mvc:interceptor>

<! -- 拦截器2-->

<mvc:interceptor>

<mvc:mapping path="/hello"/> <bean class="com.itheima.interceptor.Interceptor2" />

</mvc:interceptor>

... </mvc:interceptors>

在上述代码中,<mvc:interceptors>元素用于配置一组拦截器,其子元素<bean>中定义的是全局拦截器,它会拦截所有的请求;而<mvc:interceptor>元素中定义的是指定路径的拦截器,它会对指定路径下的请求生效。<mvc:interceptor>元素的子元素<mvc:mapping>用于配置拦截器作用的路径,该路径在其属性path中定义。如上述代码中path的属性值“/**”表示拦截所有路径,“/hello”表示拦截所有以“/hello”结尾的路径。如果在请求路径中包含不需要拦截的内容,还可以通过<mvc:exclude-mapping>元素进行配置。

需要注意的是,<mvc:interceptor>中的子元素必须按照上述代码的配置顺序进行编写,即<mvc:mapping … />→<mvc:exclude-mapping … />→<bean … />的顺序,否则文件会报错。

举例如下——

package com.itheima.interceptor;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;

import org.springframework.web.servlet.ModelAndView;

/**

* 实现了HandlerInterceptor接口的自定义拦截器类

*/

public class CustomInterceptor implements HandlerInterceptor {

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

throws Exception {

System.out.println("CustomInterceptor...preHandle");

// 对拦截的请求进行放行处理

return true;

}

@Override

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,

ModelAndView modelAndView) throws Exception {

System.out.println("CustomInterceptor...postHandle");

}

@Override

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)

throws Exception {

System.out.println("CustomInterceptor...afterCompletion");

}

}

程序先执行拦截器类中的preHandle()方法,然后执行了控制器中的Hello()方法,最后分别执行了拦截器类中的postHandle()方法和afterCompletion()方法。

配置多个拦截器

当有多个拦截器同时工作时,它们的preHandle()方法会按照配置文件中拦截器的配置顺序执行,而它们的postHandle()方法和afterCompletion()方法则会按照配置顺序的反序执行。

在配置文件springmvc-config.xml中的<mvc:interceptors>元素内配置上面所定义的两个拦截器,配置代码如下所示

<! -- 拦截器1-->

<mvc:interceptor>

<! -- 配置拦截器作用的路径 -->

<mvc:mapping path="/**" />

<! -- 定义在<mvc:interceptor>下面的表示匹配指定路径的请求才进行拦截的 -->

<bean class="com.itheima.interceptor.Interceptor1" />

</mvc:interceptor>

<! -- 拦截器2-->

<mvc:interceptor>

<mvc:mapping path="/hello" />

<bean class="com.itheima.interceptor.Interceptor2" />

</mvc:interceptor>


2.应用案例——实现用户登录权限验证拦截器如下

package com.itheima.interceptor;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.HandlerInterceptor;

import org.springframework.web.servlet.ModelAndView;

import com.itheima.po.User;

/**

* 登录拦截器

*/

public class LoginInterceptor implements HandlerInterceptor {

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

throws Exception {

// 获取请求的URL

String url = request.getRequestURI();

// URL:除了login.jsp是可以公开访问的,其他的URL都进行拦截控制

if (url.indexOf("/login") >= 0) {

return true;

}

// 获取Session

HttpSession session = request.getSession();

User user = (User) session.getAttribute("USER_SESSION");

// 判断Session中是否有用户数据,如果有,则返回true,继续向下执行

if (user != null) {

return true;

}

// 不符合条件的给出提示信息,并转发到登录页面

request.setAttribute("msg", "您还没有登录,请先登录!");

request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);

return false;

}

@Override

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,

ModelAndView modelAndView) throws Exception {

}

@Override

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)

throws Exception {

}

}

2.SSM框架整合

1.整合环境搭建

由于Spring MVC是Spring框架中的一个模块,所以Spring MVC与Spring之间不存在整合的问题,只要引入相应JAR包就可以直接使用。因此SSM框架的整合就只涉及Spring与MyBatis的整合,以及Spring MVC与MyBatis的整合。

2.准备所需JAR包,如图所示


3.编写配置文件

1)在Eclipse中,创建Web项目,将整合所需的JAR包添加到项目的lib目录中,并发布到类路径下。

2)在项目下,创建一个名为config的源文件夹(Source Folder),在该文件夹中分别创建数据库常量配置文件db.properties、Spring配置文件applicationContext.xml以及MyBatis的配置文件mybatis-config.xml。这三个配置文件的实现代码如下

db.properties

jdbc.driver=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://localhost:3306/boot_crm?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC

jdbc.username=root

jdbc.password=root

jdbc.maxTotal=30

jdbc.maxIdle=10

jdbc.initialSize=5

applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:mvc="http://www.springframework.org/schema/mvc"

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-4.3.xsd

http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-4.3.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-4.3.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

<!--读取db.properties -->

<context:property-placeholder location="classpath:db.properties"/>

<!-- 配置数据源 -->

<bean id="dataSource"

class="org.apache.commons.dbcp2.BasicDataSource">

<!--数据库驱动 -->

<property name="driverClassName" value="${jdbc.driver}" />

<!--连接数据库的url -->

<property name="url" value="${jdbc.url}" />

<!--连接数据库的用户名 -->

<property name="username" value="${jdbc.username}" />

<!--连接数据库的密码 -->

<property name="password" value="${jdbc.password}" />

<!--最大连接数 -->

<property name="maxTotal" value="${jdbc.maxTotal}" />

<!--最大空闲连接 -->

<property name="maxIdle" value="${jdbc.maxIdle}" />

<!--初始化连接数 -->

<property name="initialSize" value="${jdbc.initialSize}" />

</bean>

<!-- 事务管理器 -->

<bean id="transactionManager" class=

"org.springframework.jdbc.datasource.DataSourceTransactionManager">

<!-- 数据源 -->

<property name="dataSource" ref="dataSource" />

</bean>

<!-- 通知 -->

<tx:advice id="txAdvice" transaction-manager="transactionManager">

<tx:attributes>

<!-- 传播行为 -->

<tx:method name="save*" propagation="REQUIRED" />

<tx:method name="insert*" propagation="REQUIRED" />

<tx:method name="add*" propagation="REQUIRED" />

<tx:method name="create*" propagation="REQUIRED" />

<tx:method name="delete*" propagation="REQUIRED" />

<tx:method name="update*" propagation="REQUIRED" />

<tx:method name="find*" propagation="SUPPORTS"

read-only="true" />

<tx:method name="select*" propagation="SUPPORTS"

read-only="true" />

<tx:method name="get*" propagation="SUPPORTS"

read-only="true" />

</tx:attributes>

</tx:advice>

<!-- 切面 -->

<aop:config>

<aop:advisor advice-ref="txAdvice"

pointcut="execution(* com.itheima.core.service.*.*(..))" />

</aop:config>

<!-- 配置 MyBatis的工厂 -->

<bean class="org.mybatis.spring.SqlSessionFactoryBean">

<!-- 数据源 -->

<property name="dataSource" ref="dataSource" />

<!-- 配置MyBatis的核心配置文件所在位置 -->

<property name="configLocation"

value="classpath:mybatis-config.xml" />

</bean>

<!-- 接口开发,扫描 com.itheima.core.dao包 ,写在此包下的接口即可被扫描到 -->

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">

<property name="basePackage" value="com.itheima.core.dao" />

</bean>


<!-- 配置扫描@Service注解 -->

<context:component-scan base-package="com.itheima.core.service"/>

</beans>


mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

<!-- 别名定义 -->

<typeAliases>

<package name="com.itheima.core.po" />

</typeAliases>

</configuration>

由于在Spring中已经配置了数据源信息以及mapper接口文件扫描器,所以在MyBatis的配置文件中只需要根据POJO类路径进行别名配置即可。

在实际开发时,为了避免Spring配置文件中的信息过于臃肿,通常会将Spring配置文件中的信息按照不同的功能分散在多个配置文件中。例如可以将事务配置放置在名称为applicationContext-transaction.xml的文件中,将数据源等信息放置在名称为applicationContext-db.xml的文件中等。这样,在web.xml中配置加载Spring文件信息时,只需通过applicationContext-*.xml的方式即可自动加载全部配置文件。

3) 在config文件夹中,创建Spring MVC的配置文件springmvc-config.xml

springmvc-config.xml

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:mvc="http://www.springframework.org/schema/mvc"

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-4.3.xsd

http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-4.3.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-4.3.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">

<!-- 加载属性文件 -->

<context:property-placeholder

location="classpath:resource.properties" />

<!-- 配置扫描器 -->

<context:component-scan

base-package="com.itheima.core.web.controller" />

<!-- 注解驱动:配置处理器映射器和适配器 -->

<mvc:annotation-driven />

<!--配置静态资源的访问映射,此配置中的文件,将不被前端控制器拦截 -->

<mvc:resources location="/js/" mapping="/js/**" />

<mvc:resources location="/css/" mapping="/css/**" />

<mvc:resources location="/fonts/" mapping="/fonts/**" />

<mvc:resources location="/images/" mapping="/images/**" />

<!-- 配置视图解释器ViewResolver -->

<bean id="jspViewResolver" class=

"org.springframework.web.servlet.view.InternalResourceViewResolver">

<property name="prefix" value="/WEB-INF/jsp/" />

<property name="suffix" value=".jsp" />

</bean>


<!-- 配置拦截器 -->

<mvc:interceptors>

<mvc:interceptor>

<mvc:mapping path="/**" />

<bean class="com.itheima.core.interceptor.LoginInterceptor" />

</mvc:interceptor>

</mvc:interceptors>

</beans>

springmvc-config.xml主要配置了用于扫描@Controller注解的包扫描器、注解驱动器以及视图解析器。

(4)在web.xml中,配置Spring的文件监听器、编码过滤器以及Spring MVC的前端控制器等信息

web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns="http://xmlns.jcp.org/xml/ns/javaee"

xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee

http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"

id="WebApp_ID" version="3.1">

<!-- 配置加载Spring文件的监听器-->

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>classpath:applicationContext.xml</param-value>

</context-param>

<listener>

<listener-class>

org.springframework.web.context.ContextLoaderListener

</listener-class>

</listener>

<!-- 编码过滤器 -->

<filter>

<filter-name>encoding</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>

</filter>

<filter-mapping>

<filter-name>encoding</filter-name>

<url-pattern>*.action</url-pattern>

</filter-mapping>

<!-- 配置Spring MVC前端核心控制器 -->

<servlet>

<servlet-name>crm</servlet-name>

<servlet-class>

org.springframework.web.servlet.DispatcherServlet

</servlet-class>

<init-param>

<param-name>contextConfigLocation</param-name>

<param-value>classpath:springmvc-config.xml</param-value>

</init-param>

<!-- 配置服务器启动后立即加载Spring MVC配置文件 -->

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>crm</servlet-name>

<url-pattern>*.action</url-pattern>

</servlet-mapping>

<!-- 系统默认页面 -->

<welcome-file-list>

<welcome-file>index.jsp</welcome-file>

</welcome-file-list>

</web-app>

4.整合测试

(1)在src目录下,创建一个com.itheima.po包,并在包中创建持久化类Customer

package com.itheima.core.po;

import java.io.Serializable;

import java.util.Date;

/**

* 客户持久化类

*/

public class Customer implements Serializable {

private static final long serialVersionUID = 1L;

private Integer cust_id; // 客户编号

private String cust_name; // 客户名称

private Integer cust_user_id; // 负责人id

private Integer cust_create_id; // 创建人id

private String cust_source; // 客户信息来源

private String cust_industry; // 客户所属行业

private String cust_level; // 客户级别

private String cust_linkman; // 联系人

private String cust_phone; // 固定电话

private String cust_mobile; // 移动电话

private String cust_zipcode; // 邮政编码

private String cust_address; // 联系地址

private Date cust_createtime; // 创建时间

private Integer start; // 起始行

private Integer rows; // 所取行数


public String getCust_zipcode() {

return cust_zipcode;

}

public void setCust_zipcode(String cust_zipcode) {

this.cust_zipcode = cust_zipcode;

}

public String getCust_address() {

return cust_address;

}

public void setCust_address(String cust_address) {

this.cust_address = cust_address;

}

public Integer getStart() {

return start;

}

public void setStart(Integer start) {

this.start = start;

}

public Integer getRows() {

return rows;

}

public void setRows(Integer rows) {

this.rows = rows;

}

public Integer getCust_id() {

return cust_id;

}

public void setCust_id(Integer cust_id) {

this.cust_id = cust_id;

}

public String getCust_name() {

return cust_name;

}

public void setCust_name(String cust_name) {

this.cust_name = cust_name;

}

public Integer getCust_user_id() {

return cust_user_id;

}

public void setCust_user_id(Integer cust_user_id) {

this.cust_user_id = cust_user_id;

}

public Integer getCust_create_id() {

return cust_create_id;

}

public void setCust_create_id(Integer cust_create_id) {

this.cust_create_id = cust_create_id;

}

public String getCust_source() {

return cust_source;

}

public void setCust_source(String cust_source) {

this.cust_source = cust_source;

}

public String getCust_industry() {

return cust_industry;

}

public void setCust_industry(String cust_industry) {

this.cust_industry = cust_industry;

}

public String getCust_level() {

return cust_level;

}

public void setCust_level(String cust_level) {

this.cust_level = cust_level;

}

public String getCust_linkman() {

return cust_linkman;

}

public void setCust_linkman(String cust_linkman) {

this.cust_linkman = cust_linkman;

}

public String getCust_phone() {

return cust_phone;

}

public void setCust_phone(String cust_phone) {

this.cust_phone = cust_phone;

}

public String getCust_mobile() {

return cust_mobile;

}

public void setCust_mobile(String cust_mobile) {

this.cust_mobile = cust_mobile;

}

public Date getCust_createtime() {

return cust_createtime;

}

public void setCust_createtime(Date cust_createtime) {

this.cust_createtime = cust_createtime;

}

}

(2)在src目录下,创建一个com.itheima.dao包,并在包中创建接口文件CustomerDao以及对应的映射文件CustomerDao.xml

CustomerDao

package com.itheima.core.dao;

import java.util.List;

import com.itheima.core.po.Customer;

/**

* Customer接口

*/

public interface CustomerDao {

// 客户列表

public List<Customer> selectCustomerList(Customer customer);

// 客户数

public Integer selectCustomerListCount(Customer customer);


// 创建客户

public int createCustomer(Customer customer);

// 通过id查询客户

public Customer getCustomerById(Integer id);

// 更新客户信息

public int updateCustomer(Customer customer);

// 删除客户

int deleteCustomer (Integer id);

}

CustomerDao.xml

<?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.itheima.core.dao.CustomerDao">

<!--SQL片段 -->

<sql id="selectCustomerListWhere">

<where>

<if test="cust_name != null" >

cust_name like "%"#{cust_name}"%"

</if>

<if test="cust_source != null" >

and cust_source = #{cust_source}

</if>

<if test="cust_industry != null" >

and cust_industry = #{cust_industry}

</if>

<if test="cust_level != null" >

and cust_level = #{cust_level}

</if>

</where>

</sql>

<!-- 查询客户列表 -->

<select id="selectCustomerList" parameterType="customer"

resultType="customer">

SELECT

cust_id,

cust_name,

cust_user_id,

cust_create_id,

b.dict_item_name cust_source,

c.dict_item_name cust_industry,

d.dict_item_name cust_level,

cust_linkman,

cust_phone,

cust_mobile,

cust_createtime

FROM

customer a

LEFT JOIN (

SELECT

dict_id,

dict_item_name

FROM

base_dict

WHERE

dict_type_code = '002'

) b ON a.cust_source = b.dict_id

LEFT JOIN (

SELECT

dict_id,

dict_item_name

FROM

base_dict

WHERE

dict_type_code = '001'

) c ON a.cust_industry = c.dict_id

LEFT JOIN (

SELECT

dict_id,

dict_item_name

FROM

base_dict

WHERE

dict_type_code = '006'

) d ON a.cust_level = d.dict_id

<include refid="selectCustomerListWhere"/>

<!-- 执行分页查询 -->

<if test="start !=null and rows != null">

limit #{start},#{rows}

</if>

</select>

<!-- 查询客户总数 -->

<select id="selectCustomerListCount" parameterType="customer"

resultType="Integer">

select count(*) from customer

<include refid="selectCustomerListWhere"/>

</select>


<!-- 添加客户 -->

<insert id="createCustomer" parameterType="customer">

insert into customer(

cust_name,

cust_user_id,

cust_create_id,

cust_source,

cust_industry,

cust_level,

cust_linkman,

cust_phone,

cust_mobile,

cust_zipcode,

cust_address,

cust_createtime

)

values(#{cust_name},

#{cust_user_id},

#{cust_create_id},

#{cust_source},

#{cust_industry},

#{cust_level},

#{cust_linkman},

#{cust_phone},

#{cust_mobile},

#{cust_zipcode},

#{cust_address},

#{cust_createtime}

)

</insert>

<!-- 根据id获取客户信息 -->

<select id="getCustomerById" parameterType="Integer"

resultType="customer">

select * from customer where cust_id = #{id}

</select>

<!-- 更新客户 -->

<update id="updateCustomer" parameterType="customer">

update customer

<set>

<if test="cust_name!=null">

cust_name=#{cust_name},

</if>

<if test="cust_user_id!=null">

cust_user_id=#{cust_user_id},

</if>

<if test="cust_create_id!=null">

cust_create_id=#{cust_create_id},

</if>

<if test="cust_source!=null">

cust_source=#{cust_source},

</if>

<if test="cust_industry!=null">

cust_industry=#{cust_industry},

</if>

<if test="cust_level!=null">

cust_level=#{cust_level},

</if>

<if test="cust_linkman!=null">

cust_linkman=#{cust_linkman},

</if>

<if test="cust_phone!=null">

cust_phone=#{cust_phone},

</if>

<if test="cust_mobile!=null">

cust_mobile=#{cust_mobile},

</if>

<if test="cust_zipcode!=null">

cust_zipcode=#{cust_zipcode},

</if>

<if test="cust_address!=null">

cust_address=#{cust_address},

</if>

<if test="cust_createtime!=null">

cust_createtime=#{cust_createtime},

</if>

</set>

where cust_id=#{cust_id}

</update>

<!-- 删除客户 -->

<delete id="deleteCustomer" parameterType="Integer">

delete from customer where cust_id=#{id}

</delete>

</mapper>

(3)在src目录下,创建一个com.itheima.service包,然后在包中创建接口文件CustomerService,并在CustomerService中定义通过id查询客户的方法

CustomerService

package com.itheima.core.service;

import com.itheima.common.utils.Page;

import com.itheima.core.po.Customer;

public interface CustomerService {

// 查询客户列表

public Page<Customer> findCustomerList(Integer page, Integer rows,

String custName,String custSource,

String custIndustry,String custLevel);


public int createCustomer(Customer customer);


// 通过id查询客户

public Customer getCustomerById(Integer id);

// 更新客户

public int updateCustomer(Customer customer);

// 删除客户

public int deleteCustomer(Integer id);

}

(4)在src目录下,创建一个com.itheima.service.impl包,并在包中创建CustomerService接口的实现类CustomerServiceImpl

CustomerServiceImpl

package com.itheima.core.service.impl;

import java.util.List;

import org.apache.commons.lang3.StringUtils;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

import com.itheima.common.utils.Page;

import com.itheima.core.dao.CustomerDao;

import com.itheima.core.po.Customer;

import com.itheima.core.service.CustomerService;

/**

* 客户管理

*/

@Service("customerService")

@Transactional

public class CustomerServiceImpl implements CustomerService {

// 声明DAO属性并注入

@Autowired

private CustomerDao customerDao;

// 客户列表

public Page<Customer> findCustomerList(Integer page, Integer rows,

String custName, String custSource,String custIndustry,

String custLevel) {

// 创建客户对象

Customer customer = new Customer();

// 判断客户名称

if(StringUtils.isNotBlank(custName)){

customer.setCust_name(custName);

}

// 判断客户信息来源

if(StringUtils.isNotBlank(custSource)){

customer.setCust_source(custSource);

}

// 判断客户所属行业

if(StringUtils.isNotBlank(custIndustry)){

customer.setCust_industry(custIndustry);

}

// 判断客户级别

if(StringUtils.isNotBlank(custLevel)){

customer.setCust_level(custLevel);

}

// 当前页

customer.setStart((page-1) * rows) ;

// 每页数

customer.setRows(rows);

// 查询客户列表

List<Customer> customers =

customerDao.selectCustomerList(customer);

// 查询客户列表总记录数

Integer count = customerDao.selectCustomerListCount(customer);

// 创建Page返回对象

Page<Customer> result = new Page<>();

result.setPage(page);

result.setRows(customers);

result.setSize(rows);

result.setTotal(count);

return result;

}

/**

* 创建客户

*/

@Override

public int createCustomer(Customer customer) {

return customerDao.createCustomer(customer);

}

/**

* 通过id查询客户

*/

@Override

public Customer getCustomerById(Integer id) {

Customer customer = customerDao.getCustomerById(id);

return customer;

}

/**

* 更新客户

*/

@Override

public int updateCustomer(Customer customer) {

return customerDao.updateCustomer(customer);

}

/**

* 删除客户

*/

@Override

public int deleteCustomer(Integer id) {

return customerDao.deleteCustomer(id);

}


}

@Service注解来标识业务层的实现类,使用了@Transactional注解来标识类中的所有方法都纳入Spring的事务管理,并使用@Autowired注解将CustomerDao接口对象注入到本类中,然后在本类的查询方法中调用了CustomerDao对象的查询客户方法

5)在src目录下,创建一个com.itheima.controller包,并在包中创建用于处理页面请求的控制器类CustomerController

CustomerController

package com.itheima.core.web.controller;

import java.sql.Timestamp;

import java.util.Date;

import java.util.List;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.ResponseBody;

import com.itheima.common.utils.Page;

import com.itheima.core.po.BaseDict;

import com.itheima.core.po.Customer;

import com.itheima.core.po.User;

import com.itheima.core.service.BaseDictService;

import com.itheima.core.service.CustomerService;

/**

* 客户管理控制器类

*/

@Controller

public class CustomerController {

// 依赖注入

@Autowired

private CustomerService customerService;

@Autowired

private BaseDictService baseDictService;

// 客户来源

@Value("${customer.from.type}")

private String FROM_TYPE;

// 客户所属行业

@Value("${customer.industry.type}")

private String INDUSTRY_TYPE;

// 客户级别

@Value("${customer.level.type}")

private String LEVEL_TYPE;

/**

* 客户列表

*/

@RequestMapping(value = "/customer/list.action")

public String list(@RequestParam(defaultValue="1")Integer page,

@RequestParam(defaultValue="10")Integer rows,

String custName, String custSource, String custIndustry,

String custLevel, Model model) {

// 条件查询所有客户

Page<Customer> customers = customerService

.findCustomerList(page, rows, custName,

custSource, custIndustry,custLevel);

model.addAttribute("page", customers);

// 客户来源

List<BaseDict> fromType = baseDictService

.findBaseDictByTypeCode(FROM_TYPE);

// 客户所属行业

List<BaseDict> industryType = baseDictService

.findBaseDictByTypeCode(INDUSTRY_TYPE);

// 客户级别

List<BaseDict> levelType = baseDictService

.findBaseDictByTypeCode(LEVEL_TYPE);

// 添加参数

model.addAttribute("fromType", fromType);

model.addAttribute("industryType", industryType);

model.addAttribute("levelType", levelType);

model.addAttribute("custName", custName);

model.addAttribute("custSource", custSource);

model.addAttribute("custIndustry", custIndustry);

model.addAttribute("custLevel", custLevel);

return "customer";

}


/**

* 创建客户

*/

@RequestMapping("/customer/create.action")


public @ResponseBody String customerCreate(Customer customer,HttpSession session) {

// 获取Session中的当前用户信息

User user = (User) session.getAttribute("USER_SESSION");

// 将当前用户id存储在客户对象中

customer.setCust_create_id(user.getUser_id());

// 创建Date对象

Date date = new Date();

// 得到一个Timestamp格式的时间,存入mysql中的时间格式“yyyy/MM/dd HH:mm:ss”

Timestamp timeStamp = new Timestamp(date.getTime());

customer.setCust_createtime(timeStamp);

// 执行Service层中的创建方法,返回的是受影响的行数

int rows = customerService.createCustomer(customer);

if(rows > 0){

return "OK";

}else{

return "FAIL";

}

}

/**

* 通过id获取客户信息

*/

@RequestMapping("/customer/getCustomerById.action")


public @ResponseBody Customer getCustomerById(Integer id) {

Customer customer = customerService.getCustomerById(id);

return customer;

}

/**

* 更新客户

*/

@RequestMapping("/customer/update.action")


public @ResponseBody String customerUpdate(Customer customer) {

int rows = customerService.updateCustomer(customer);

if(rows > 0){

return "OK";

}else{

return "FAIL";

}

}

/**

* 删除客户

*/

@RequestMapping("/customer/delete.action")


public @ResponseBody String customerDelete(Integer id) {

int rows = customerService.deleteCustomer(id);

if(rows > 0){

return "OK";

}else{

return "FAIL";

}

}

}

先使用了Spring的注解@Controller来标识控制器类,然后通过@Autowired注解将CustomerService接口对象注入到本类中,最后编写了一个根据id查询客户详情的方法findCustomerById(),该方法会将获取的客户详情返回到视图名为customer的jsp页面中。

(6)在WEB-INF目录下,创建一个jsp文件夹,在该文件夹下创建一个用于展示客户详情的页面文件customer.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<%@ page trimDirectiveWhitespaces="true"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<%@ taglib prefix="itheima" uri="http://itheima.com/common/"%>

<%

String path = request.getContextPath();

String basePath = request.getScheme() + "://" + request.getServerName()

+ ":" + request.getServerPort() + path + "/";

%>

<!DOCTYPE HTML>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>客户管理-BootCRM</title>

<!-- 引入css样式文件 -->

<!-- Bootstrap Core CSS -->

<link href="<%=basePath%>css/bootstrap.min.css" rel="stylesheet" />

<!-- MetisMenu CSS -->

<link href="<%=basePath%>css/metisMenu.min.css" rel="stylesheet" />

<!-- DataTables CSS -->

<link href="<%=basePath%>css/dataTables.bootstrap.css" rel="stylesheet" />

<!-- Custom CSS -->

<link href="<%=basePath%>css/sb-admin-2.css" rel="stylesheet" />

<!-- Custom Fonts -->

<link href="<%=basePath%>css/font-awesome.min.css" rel="stylesheet" type="text/css" />

<link href="<%=basePath%>css/boot-crm.css" rel="stylesheet" type="text/css" />

</head>

<body>

<table border=1>

<tr> <td>编号</td> <td>名称</td> <td>职业</td> <td>电话</td> </tr>

<tr> <td>${customer.id}</td><td>${customer.username}</td> <td>${customer.jobs}</td> <td>${customer.phone}</td> </tr>

</table>

</body>

</html>

编写了一个用于展示客户信息的表格,表格会通过EL表达式来获取后台控制层返回的客户信息。

WEB-INF中需建立js,css,images,fonts,jsp等文件夹。

相关推荐

七条简单命令让您玩转Git
七条简单命令让您玩转Git

凭借着出色的协作能力、快速部署效果与代码构建辅助作用,Git已经得到越来越多企业用户的青睐。除了用于开发商业及消费级应用之外,众多科学及政府机构也开始尝试使用这...

2023-10-07 12:14 guanshanw

基本完整的关于Git分支branch的操作
基本完整的关于Git分支branch的操作

Git使用背景项目中要用到dev或者其他分支开发完代码,需要将该分支合并到master的需求操作步骤下面以dev名称为lex为分支名为例来操作一遍客户端操作:...

2023-10-07 12:14 guanshanw

Git 进阶(合并与变基)
Git 进阶(合并与变基)

在Git中整合来自不同分支的修改主要有两种方法:合并(merge)以及变基(rebase)合并(merge)merge流程图merge的原理是找到这两个分...

2023-10-07 12:13 guanshanw

Git学习笔记 003 Git进阶功能 part5 合并(第一部分)

合并(merge)是很常用的操作。尤其是一个庞大的很多人参与开发的企业级应用。一般会设定一个主分支,和多个副分支。在副分支开发完成后,合并到主分支中。始终保持主分支是一个完整的,稳定的最新状态的分支。...

非标题党,三张图帮你理解git merge和git rebase的区别
非标题党,三张图帮你理解git merge和git rebase的区别

初始场景:基于正常的开发分支修改几个小bug,然后在合并到开发分支上。gitmergegitcheckoutfeaturegitmergeho...

2023-10-07 12:13 guanshanw

git 初次使用(01)
git 初次使用(01)

先从github上克隆代码下来:使用vscode克隆代码如下图,填写上github仓库地址:vscode有时候克隆代码速度比较慢,可以用命令行方式克隆gitc...

2023-10-07 12:12 guanshanw

Git 远程操作

4.Git远程操作命令说明gitremote远程版本库操作gitfetch从远程获取版本库gitpull下载远程代码并合并gitpush上传远程代码并合并4.1远程版本库操作gitre...

Git常用命令-总结
Git常用命令-总结

创建git用户$gitconfig--globaluser.name"YourName"$gitconfig--globaluser.em...

2023-10-07 12:12 guanshanw

git中删除从别人clone下来项目的git信息,并修改为自己的分支

如果你从别人的Git存储库中克隆了一个项目,并想要删除与该存储库相关的Git信息,并将其修改为你自己的分支,则可以执行以下步骤:使用gitclone命令克隆存储库:gitclone<u...

git系列-回滚和放弃本地修改

回滚历史提交就是reset的功能。这种情况是已经提交远程仓库,需要回滚到之前的提交。gitreset--hardcommitId//注:强制提交后,当前版本后面的提交版本将会删掉!gi...

GIT使用小技巧大全
GIT使用小技巧大全

在大型软件工程的开发过程中,版本控制是无法绕过去的;目前来说,最火的版本控制软件就是GIT了。早两年SVN比较火,不过被大神linus喷了几次后,就日落西山了,...

2023-10-07 12:11 guanshanw

git相关命令-上
git相关命令-上

这些命令都是看了文档后,个人觉得比较有用的一些,展示给大家。回到远程仓库的状态抛弃本地所有的修改,回到远程仓库的状态。gitfetch--all&...

2023-10-07 12:10 guanshanw

Git命令行接口:掌握Git的必备技能
Git命令行接口:掌握Git的必备技能

Git是一款强大的分布式版本控制工具,它支持命令行界面操作。熟练掌握Git命令行接口,是开发者使用Git的必备技能之一。在这篇文章中,我们将介绍Git命令行接口...

2023-10-07 12:10 guanshanw

Git命令详解
Git命令详解

相信各位小伙伴们应该都对git有一些了解,毕竟作为代码管理的神器,就算不是IT行业的小伙伴肯定也或多或少的听说过一些。今天就来和小伙伴们分享一下自己总结的常用命...

2023-10-07 12:10 guanshanw

工作7年收集到的git命令
工作7年收集到的git命令

概念git中的术语解释:仓库也叫版本库(repository)stage:暂存区,add后会存到暂存区,commit后提交到版本库git安装linux...

2023-10-07 12:10 guanshanw

取消回复欢迎 发表评论: