SSSP整合&&分页&&CRUD

来源:互联网 发布:top域名有价值吗 编辑:程序博客网 时间:2024/06/01 12:53

简介

Spring、SpringMVC、SpringData、JPA的整合的一个例子
实现:
1. SpringMVC、Spring、SpringData\JPA 整合完成 CRUD、翻页
2. 基于Restful 风格
3. 使用 JPA 二级缓存
4. 使用 @ResponseBody 注解完成 Ajax

整合文件配置

先上一张配好后的截图
这里写图片描述这里写图片描述

1. Web.xml配置

  1. 配置了Spring的核心监听器
  2. 配置字符编码过滤器
  3. 配置 SpringMVCDispatcherServlet
  4. 配置可以把 POST请求转为 DELETEPOST请求的HiddenHttpMethodFilter
  5. 配置 OpenEntityManagerInViewFilter. 解决懒加载异常的问题
<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5"     xmlns="http://java.sun.com/xml/ns/javaee"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  <display-name></display-name>   <!-- 1. 配置 Spring 的核心监听器 -->  <listener>    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  </listener>  <!-- 配置spring的applicationContext.xml -->  <context-param>        <param-name>contextConfigLocation</param-name>        <param-value>classpath:applicationContext.xml</param-value>  </context-param>  <!-- 2. 配置字符编码过滤器,必须在所有的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>  </filter>  <filter-mapping>        <filter-name>CharacterEncodingFilter</filter-name>        <url-pattern>/*</url-pattern>  </filter-mapping>    <!-- 3. 配置 SpringMVC 的DispatcherServlet -->  <servlet>        <servlet-name>DispatcherServlet</servlet-name>        <servlet-class>org.springframework.web.servlet.DispatcherServlet </servlet-class>        <init-param>            <param-name>contextConfigLocation</param-name>            <param-value>/WEB-INF/springDispatcherServlet-servlet.xml</param-value>        </init-param>        <load-on-startup>1</load-on-startup>    </servlet>    <servlet-mapping>        <servlet-name>DispatcherServlet</servlet-name>        <url-pattern>/</url-pattern>    </servlet-mapping>    <!-- 4. 配置可以把 POST 请求转为 DELETE 或 POST 请求 -->    <filter>        <filter-name>HiddenHttpMethodFilter</filter-name>        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>    </filter>    <filter-mapping>        <filter-name>HiddenHttpMethodFilter</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>      <!-- 5. 配置 OpenEntityManagerInViewFilter. 可以解决懒加载异常的问题 -->    <filter>        <filter-name>OpenEntityManagerInViewFilter</filter-name>        <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>    </filter>    <filter-mapping>        <filter-name>OpenEntityManagerInViewFilter</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>  <welcome-file-list>    <welcome-file>index.jsp</welcome-file>  </welcome-file-list></web-app>

2.配置数据源jdbc.properties

jdbc.user=rootjdbc.password=123456jdbc.driverClass=com.mysql.jdbc.Driverjdbc.url=jdbc\:mysql\://127.0.0.1\:3306/sssp

3. 配置JPA的二级缓存配置文件ehcache.xml

ehcache.xml:

<ehcache>    <!-- Sets the path to the directory where cache .data files are created.         If the path is a Java System Property it is replaced by         its value in the running VM.         The following properties are translated:         user.home - User's home directory         user.dir - User's current working directory         java.io.tmpdir - Default temp file path -->    <diskStore path="java.io.tmpdir"/>    <!--Default Cache configuration. These will applied to caches programmatically created through        the CacheManager.        The following attributes are required for defaultCache:        maxInMemory       - Sets the maximum number of objects that will be created in memory        eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element                            is never expired.        timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used                            if the element is not eternal. Idle time is now - last accessed time        timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used                            if the element is not eternal. TTL is now - creation time        overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache                            has reached the maxInMemory limit.        -->    <defaultCache        maxElementsInMemory="10000"        eternal="false"        timeToIdleSeconds="120"        timeToLiveSeconds="120"        overflowToDisk="true"        />    <!--Predefined caches.  Add your cache configuration settings here.        If you do not have a configuration for your cache a WARNING will be issued when the        CacheManager starts        The following attributes are required for defaultCache:        name              - Sets the name of the cache. This is used to identify the cache. It must be unique.        maxInMemory       - Sets the maximum number of objects that will be created in memory        eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element                            is never expired.        timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used                            if the element is not eternal. Idle time is now - last accessed time        timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used                            if the element is not eternal. TTL is now - creation time        overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache                            has reached the maxInMemory limit.        -->    <!-- Sample cache named sampleCache1        This cache contains a maximum in memory of 10000 elements, and will expire        an element if it is idle for more than 5 minutes and lives for more than        10 minutes.        If there are more than 10000 elements it will overflow to the        disk cache, which in this configuration will go to wherever java.io.tmp is        defined on your system. On a standard Linux system this will be /tmp"        -->    <cache name="sampleCache1"        maxElementsInMemory="10000"        eternal="false"        timeToIdleSeconds="300"        timeToLiveSeconds="600"        overflowToDisk="true"        />    <!-- Sample cache named sampleCache2        This cache contains 1000 elements. Elements will always be held in memory.        They are not expired. -->    <cache name="sampleCache2"        maxElementsInMemory="1000"        eternal="true"        timeToIdleSeconds="0"        timeToLiveSeconds="0"        overflowToDisk="false"        /> -->    <!-- Place configuration for your caches following --></ehcache>

4. 配置Spring的配置文件applicationContext.xml

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"    xmlns:tx="http://www.springframework.org/schema/tx"    xmlns:jpa="http://www.springframework.org/schema/data/jpa"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">        <!-- 1. 配置自动扫描的包 -->        <context:component-scan base-package="com.bart.sssp">            <!-- 过滤SpringMVC的注解不扫描 -->            <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>            <context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>        </context:component-scan>        <!-- 2. 配置数据源 -->        <context:property-placeholder location="classpath:jdbc.properties"/>        <!-- C3P0连接池 -->        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">            <property name="user" value="${jdbc.user}"></property>            <property name="password" value="${jdbc.password}"></property>            <property name="driverClass" value="${jdbc.driverClass}"></property>            <property name="jdbcUrl" value="${jdbc.url}"></property>        </bean>        <!-- 3. 配置 JPA 的EntityManagerFactory -->        <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">             <property name="dataSource" ref="dataSource" />            <!-- 3.1 配置 JPA 提供商的适配器. 可以通过内部 bean 的方式来配置 -->            <property name="jpaVendorAdapter">                <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean>            </property>            <!-- 3.2 配置实体类所在的包 -->            <property name="packagesToScan" value="com.bart.sssp" />            <!-- 3.3 配置 JPA 的基本属性 -->            <property name="jpaProperties">                <props>                    <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>                    <!-- Hibernate 基本属性 -->                    <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>                    <prop key="hibernate.show_sql">true</prop>                    <prop key="hibernate.format_sql">true</prop>                    <prop key="hibernate.hbm2ddl.auto">update</prop>                    <!-- 二级缓存相关 -->                    <prop key="hibernate.cache.use_second_level_cache">true</prop>                    <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>                    <prop key="hibernate.cache.use_query_cache">true</prop>                </props>            </property>            <property name="sharedCacheMode" value="ENABLE_SELECTIVE"></property>        </bean>        <!-- 4. 配置事务管理 -->        <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">            <property name="entityManagerFactory" ref="entityManagerFactory"></property>        </bean>        <!-- 5. 配置支持注解的事务 -->        <tx:annotation-driven transaction-manager="transactionManager"/>        <!-- 6. 配置 SpringData -->        <!-- 加入 jpa 的命名空间 -->        <!-- base-package: 扫描 Repository Bean 所在的 package -->         <jpa:repositories base-package="com.bart.sssp"            entity-manager-factory-ref="entityManagerFactory">        </jpa:repositories></beans>

5. 配置SpringMVC的配置文件springDispatcherServlet-servlet.xml

注意,该配置文件必须放在/WEB-INF/目录下,web.xml在加载的时候会主动加载该配置文件
springDispatcherServlet-servlet.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:mvc="http://www.springframework.org/schema/mvc"    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd        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.0.xsd">    <!-- 1. 配置自动扫描的包 -->    <context:component-scan base-package="com.bart.sssp" use-default-filters="false">        <!-- 这两个注解交给SpringMVC管理,其他的交给 IOC 容器 -->        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>        <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>    </context:component-scan>    <!-- 2. 配置视图解析器 -->    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">        <property name="prefix" value="/WEB-INF/views/"/>        <property name="suffix" value=".jsp"/>    </bean>    <mvc:default-servlet-handler/>    <mvc:annotation-driven></mvc:annotation-driven></beans>

6. 创建entity

6.1 Employee.java

package com.bart.sssp.entity;import java.util.Date;import javax.persistence.Entity;import javax.persistence.FetchType;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.ManyToOne;import javax.persistence.Table;import javax.persistence.Temporal;import javax.persistence.TemporalType;import org.springframework.format.annotation.DateTimeFormat;@Table(name="SSSP_EMPLOYEES")@Entitypublic class Employee {    private Integer id;    private String lastName;    private String email;    @DateTimeFormat(pattern="yyyy-MM-dd")    private Date birth;    private Date createTime;    private Department department;    @GeneratedValue    @Id    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;    }    @Temporal(TemporalType.DATE)    public Date getBirth() {        return birth;    }    public void setBirth(Date birth) {        this.birth = birth;    }    @Temporal(TemporalType.TIMESTAMP)    public Date getCreateTime() {        return createTime;    }    public void setCreateTime(Date createTime) {        this.createTime = createTime;    }    @JoinColumn(name="DEPARTMENT_ID")    @ManyToOne(fetch=FetchType.LAZY)    public Department getDepartment() {        return department;    }    public void setDepartment(Department department) {        this.department = department;    }}

6.2Department.java

package com.bart.sssp.entity;import javax.persistence.Cacheable;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.Table;@Cacheable(true)//设置二级缓存@Table(name="SSSP_DEPARTMENTS")@Entitypublic class Department {    private Integer id;    private String departmentName;    @GeneratedValue    @Id    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    public String getDepartmentName() {        return departmentName;    }    public void setDepartmentName(String departmentName) {        this.departmentName = departmentName;    }}

7. Repository配置

7.1 EmployeeRepository

package com.bart.sssp.repository;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.data.jpa.repository.Query;import org.springframework.data.repository.query.Param;import com.bart.sssp.entity.Employee;public interface EmployeeRepository extends JpaRepository<Employee,Integer>{    //自定义查询方法    @Query("from Employee e where e.lastName=:lastName")    public Employee getByName(@Param("lastName")String lastName);}

7.2 DepartmentRepository

package com.bart.sssp.repository;import java.util.List;import javax.persistence.QueryHint;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.data.jpa.repository.Query;import org.springframework.data.jpa.repository.QueryHints;import com.bart.sssp.entity.Department;public interface DepartmentRepository extends JpaRepository<Department,Integer>{    //配置二级缓存    @QueryHints(value={@QueryHint(name=org.hibernate.ejb.QueryHints.HINT_CACHEABLE,value="true")})    @Query("from Department d")    public List<Department> getAll();}

8. Service

8.1 EmployeeService

package com.bart.sssp.service;import java.util.Date;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.domain.Page;import org.springframework.data.domain.PageRequest;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import com.bart.sssp.entity.Employee;import com.bart.sssp.repository.EmployeeRepository;@Servicepublic class EmployeeService {    @Autowired    private EmployeeRepository employeeRepository;    @Transactional    public void delete(Integer id){        employeeRepository.delete(id);    }    @Transactional    public Employee getById(Integer id){        return employeeRepository.findOne(id);    }    @Transactional    public Employee getByName(String lastName) {        return employeeRepository.getByName(lastName);    }    //保存    @Transactional    public void save(Employee employee){        //当id为空表示新添加的,set创建时间        if(employee.getId() == null){            employee.setCreateTime(new Date());        }        employeeRepository.saveAndFlush(employee);    }    @Transactional(readOnly=true)    public Page<Employee> getPage(Integer pageNo,Integer pageSize){        PageRequest pageRequest= new PageRequest(pageNo-1,pageSize);        Page<Employee>page = employeeRepository.findAll(pageRequest);        return page;    }}

8.2 DepartmentService

package com.bart.sssp.service;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import com.bart.sssp.entity.Department;import com.bart.sssp.repository.DepartmentRepository;@Servicepublic class DepartmentService {    @Autowired    private DepartmentRepository departmentRepository;    @Transactional(readOnly=true)    public List<Department> getAll(){        return departmentRepository.getAll();    }}

9. Handler

package com.bart.sssp.handler;import java.util.Map;import javax.persistence.Id;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.domain.Page;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.ModelAttribute;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.ResponseBody;import com.bart.sssp.entity.Employee;import com.bart.sssp.service.DepartmentService;import com.bart.sssp.service.EmployeeService;@Controllerpublic class EmployeeHandler {    @Autowired    private EmployeeService employeeService;    @Autowired    private DepartmentService departmentService;    @RequestMapping(value="/emp/{id}",method=RequestMethod.DELETE)    public String delete(@PathVariable(value="id")Integer id){        employeeService.delete(id);        return "redirect:/emps";    }    /**  @ModelAttribute      *  当传进来的有id的时候表示是编辑操作,提前把employee放到值栈(Map)中     *  修改department之后,因为在Map中的employee中的departmentId还指向     *  旧的departmentId,的那是hibernate是不允许直接修改主键id的     *  所以在放入Map之前应该先置空     */    @ModelAttribute    public void getEmployee(@RequestParam(value="id",required=false) Integer id,            Map<String, Object> map){        if(id!=null){           Employee employee = employeeService.getById(id);           employee.setDepartment(null);           map.put("employee",employee);        }    }    /**     * 保存编辑     * @param employee     * @return     */    @RequestMapping(value="/emp/{id}",method=RequestMethod.PUT)    public String update(Employee employee){        employeeService.save(employee);        return "redirect:/emps";    }    /**     * 进入编辑界面     * @param id     * @param map     * @return     */    @RequestMapping(value="/emp/{id}",method=RequestMethod.GET)    public String input(@PathVariable("id")Integer id,Map<String,Object>map){        map.put("employee", employeeService.getById(id));        map.put("departments", departmentService.getAll());        return "input";    }    /**     * Ajax验证用户名是否已使用     * @param lastName     * @return     */    @ResponseBody//内容或对象作为 HTTP 响应正文返回     @RequestMapping(value="ajaxValidateLastName",method=RequestMethod.POST)    public String ajaxValidateLastName(@RequestParam(value="lastName",required=true)String lastName){        if(employeeService.getByName(lastName)!=null){            return "1";        }else {            return "0";        }    }    /**     * 添加新员工保存     * @param employee     * @return     */    @RequestMapping(value="/emp",method=RequestMethod.POST)    public String save(Employee employee){        employeeService.save(employee);        return "redirect:/emps";    }    /**     * input.jsp 添加     * @param map     * @return     */    @RequestMapping(value="/emp",method=RequestMethod.GET)    public String input(Map<String , Object>map){        //用于回显,相当于struts2的prepare方法,在值栈放入Employee对象         map.put("departments", departmentService.getAll());        map.put("employee", new Employee());        return "input";    }    /**     * 分页列出所有的employee     * @param pageStr     * @param map     * @return     */    @RequestMapping("/emps")    public String list(@RequestParam(value="pageNo",required=false,defaultValue="1")            String pageNoStr,Map<String, Object>map){        int pageNo = 1;        try {            //对传进来的pageNoStr 进行校验            pageNo=Integer.parseInt(pageNoStr);            if(pageNo<1)               pageNo=1;        } catch (Exception e) {}        Page<Employee>page = employeeService.getPage(pageNo,5);        map.put("page", page);        return "list";    }}

10.测试类

package com.bart.sssp.test;import java.sql.SQLException;import java.util.ArrayList;import java.util.Date;import java.util.List;import javax.persistence.EntityManager;import javax.persistence.EntityManagerFactory;import javax.persistence.Query;import javax.sql.DataSource;import org.hibernate.ejb.QueryHints;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.bart.sssp.entity.Department;import com.bart.sssp.entity.Employee;import com.bart.sssp.repository.EmployeeRepository;public class TestSSSP {    private ApplicationContext context = null;    private EmployeeRepository employeeRepository=null;    private EntityManagerFactory entityManagerFactory;    {        context = new ClassPathXmlApplicationContext("applicationContext.xml");        employeeRepository = context.getBean(EmployeeRepository.class);        entityManagerFactory = context.getBean(EntityManagerFactory.class);    }    //测试getByName查询    @Test    public void testGetByName(){        System.out.println(employeeRepository.getByName("aa").getLastName());    }    //测试二级缓存Jpa    @Test    public void testJpaSecondLevelCache(){        String jpql = "from Department d";        EntityManager entityManager = entityManagerFactory.createEntityManager();        Query query = entityManager.createQuery(jpql);        List<Department> departments = query.setHint(QueryHints.HINT_CACHEABLE, true).getResultList();        entityManager.close();        entityManager = entityManagerFactory.createEntityManager();        query = entityManager.createQuery(jpql);        departments = query.setHint(QueryHints.HINT_CACHEABLE, true).getResultList();        entityManager.close();    }    //测试插入数据    @Test    public void testInsert(){        List<Employee>list = new ArrayList<Employee>();        for(int i='a';i<='z';i++){            Employee employee = new Employee();            employee.setLastName((char)i+""+(char)i);            employee.setEmail((char)i+""+(char)i+"@163.com");            employee.setBirth(new Date());            employee.setCreateTime(new Date());            list.add(employee);        }        employeeRepository.save(list);    }    //测试数据库连接池    @Test    public void testDataSource() throws SQLException{        DataSource dataSource = context.getBean(DataSource.class);        System.out.println(dataSource.getConnection());    }}

11. jsp页面

11.1 list.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %><%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <base href="<%=basePath%>">    <title>My JSP 'index.jsp' starting page</title>    <meta http-equiv="pragma" content="no-cache">    <meta http-equiv="cache-control" content="no-cache">    <meta http-equiv="expires" content="0">        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">    <meta http-equiv="description" content="This is my page">    <script type="text/javascript" src="<%=request.getContextPath()%>/scripts/jquery-1.9.1.min.js"></script>    <script type="text/javascript" >        $(function(){            $(".delete").click(function(){                var lsatName = $(this).next(":hidden").val();                var flg = confirm("确定要删除"+lsatName+"吗?");                if(flg){                    var url = $(this).attr("href");                    $("#form").attr("action",url);                    $("#form").submit();                }              return false;            })        })    </script>  </head>  <body>    <!-- 放置一个隐藏的form用来把delete请求发送过去 -->    <form:form action="" method="POST" id="form">        <input type="hidden" name="_method" value="DELETE"/>    </form:form>    <c:if test="${page == null || page.numberOfElements ==0 }">        没有数据~    </c:if>    <c:if test="${page != null && page.numberOfElements > 0 }">        <table border="1" cellpadding="10" cellspacing="0">            <tr>                <th>ID</th>                <th>LastName</th>                <th>Email</th>                <th>Birth</th>                <th>CreateTime</th>                <th>Department</th>                <th>Delete</th>                <th>Edit</th>            </tr>            <c:forEach items="${page.content}" var="emp">            <tr>                <td>${emp.id}</td>                <td>${emp.lastName }</td>                <td>${emp.email }</td>                <td>                    <fmt:formatDate value="${emp.birth}" pattern="yyyy-MM-dd"/>                </td>                <td>                    <fmt:formatDate value="${emp.createTime}" pattern="yyyy-MM-dd hh:mm:ss"/>                </td>                <td>${emp.department.departmentName}</td>                <td>                <a href="${pageContext.request.contextPath}/emp/${emp.id}" class="delete">Delete</a>                <input type="hidden" id="lastName" value="${emp.lastName}"/>                </td>                <td><a href="${pageContext.request.contextPath}/emp/${emp.id}">Edit</a></td>            <tr>            </c:forEach>            <tr>                <td colspan="8">                总共${page.totalElements}条记录&nbsp                总共${page.totalPages}页&nbsp                当前为第${page.number+1}页&nbsp                <c:if test="${(page.number+1) != 1}">                <a href="<%=request.getContextPath()%>/emps?pageNo=1">首&nbsp页</a>&nbsp                      <a href="<%=request.getContextPath()%>/emps?pageNo=${page.number+1-1}">上一页</a>&nbsp                      </c:if>                <c:if test="${(page.number+1) != (page.totalPages)}">                <a href="<%=request.getContextPath()%>/emps?pageNo=${page.number+1+1}">下一页</a>&nbsp                      <a href="<%=request.getContextPath()%>/emps?pageNo=${page.totalPages}">尾&nbsp页</a>&nbsp                      </c:if>                </td>            </tr>        </table>    </c:if>  </body></html>

11.2 input.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <base href="<%=basePath%>">    <title>My JSP 'index.jsp' starting page</title>    <meta http-equiv="pragma" content="no-cache">    <meta http-equiv="cache-control" content="no-cache">    <meta http-equiv="expires" content="0">        <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">    <meta http-equiv="description" content="This is my page">    <script type="text/javascript" src="<%=request.getContextPath()%>/scripts/jquery-1.9.1.min.js"></script>    <script type="text/javascript" >        $(function(){            $("#lastName").change(function(){                var lastName = $(this).val();                lastName = $.trim(lastName);                 $(this).val(lastName);                var $this = $(this);                $this.nextAll("font").remove();                //如果修改的后的lastName和之前的一样就不发送Ajax请求               var oldLastName = $("#_oldLastName").val();                oldLastName = $.trim(oldLastName);                if(oldLastName !="" && oldLastName != "" && oldLastName == lastName){                    $this.after("<font color='green'>名字可用</font>");                    return;                }               //Ajax                if(lastName!=""){                    var url = "${pageContext.request.contextPath}/ajaxValidateLastName";                    var args = {"lastName":lastName,"time":new Date()};                    $.post(url,args,function(data){                    if(data == "1"){                            $this.after("<font color='red'>名字不可用</font>");                        }else if(data == "0"){                            $this.after("<font color='green'>名字可用</font>");                        }else{                            alert("系统错误,请刷新,重试!");                        }                      });                }else {                   alert("lastName 不能为空");                   $(this).val("");                   $this.focus();                     }            });        })    </script>  </head>  <body>        <c:set value="${pageContext.request.contextPath }/emp" var="url"/>        <!-- 当id不为空表示是在编辑 提交的action必须改变为 PUT 请求 -->        <c:if test="${employee.id != null }">            <c:set value="${pageContext.request.contextPath }/emp/${employee.id}" var="url"/>        </c:if>        <form:form action="${url}" methd="POST" modelAttribute="employee">        <c:if test="${employee.id != null }">            <input type="hidden" id="_oldLastName" value="${employee.lastName}"/>            <form:hidden path="id"/>            <input type="hidden" name="_method" value="PUT"/>        </c:if>         LastName:<form:input path="lastName" id="lastName"/><br>            Email:<form:input path="email"/><br>            Birth:<form:input path="birth"/><br>            Department:<form:select path="department.id" items="${departments}"                 itemLabel="departmentName" itemValue="id"/><br>            <input type="submit" value="提交"/>           </form:form>  </body></html>

11.3 index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  <body>    <a href="<%=request.getContextPath()%>/emps">lis all</a><br><br>    <a href="<%=request.getContextPath()%>/emp">add emp</a><br><br>  </body></html>

效果

  1. 浏览器输入http://localhost:8088/A02-SSSP/
    这里写图片描述
  2. 测试add emp
    • 测试Ajax的查询功能,当用户名存在提示“用户名不可用”否则提示“用户名可用”
      这里写图片描述这里写图片描述
    • 点击提交保存,并且重定向到emps的list
      这里写图片描述
  3. 测试edit
    在/emps界面选择一个employee点击edit,这里以LastName为”bb”为例:
    这里写图片描述
    可以看到有回显,并且在修改如果修改的用户名和之前的一样不用再进行Ajax请求了
  4. 测试delete
    还是以用户”bb”为例,当点击delete的时候提示是否删除用户,并提示该用户的用户名
    如果点击“是”,则删除“否”不作任何操作
    这里写图片描述
1 0
原创粉丝点击