該demo使用技術及環境:ssm+maven+bootstrap+jsp+mysql+idea+jdk1.8javascript
需求:客戶管理,實現客戶列表分頁顯示以下圖
css
數據庫環境:html
數據庫與表:
客戶表前端
字典表:[設計初衷 -- 將頁面不少定義好且無需更改的字符串統一在字典表管理,優化數據庫]html5
pom.xml -- 引入所需jarjava
思考:整合:ssm+maven+mysql,須要哪些jar?mysql
數據庫層:Mysql數據庫鏈接驅動,mybatis相關jar,mybatis與spring整合須要的包jquery
<!-- mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.3</version> </dependency> <!--spring和mybatis整合--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.2.1</version> </dependency> <!--驅動--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> <scope>runtime</scope> </dependency> <!--鏈接池--> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency>
spring管理(已包含springmvc)web
<properties> <spring.version>4.2.4.RELEASE</spring.version> <slf4j.version>1.6.6</slf4j.version> <log4j.version>1.2.12</log4j.version> </properties> <dependencies> <!-- spring ++start++ --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <!-- springmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.7</version> </dependency>
JSON相關ajax
<!--json--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.4.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.4.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.4.2</version> </dependency>
日誌相關
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> </dependency>
其餘[若是使用idea開發,無自帶的jstl標籤庫,需導入如下Jar座標]
<dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <!--jsp引入,後面自定義分頁標籤會使用--> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency>
tomcat插件
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.5.1</version> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <!-- 指定端口 --> <port>9090</port> <!-- 請求路徑 --> <path>/autoErp</path> <!-- uri編碼 --> <uriEncoding>utf-8</uriEncoding> </configuration> </plugin> </plugins> <!--注意!!!!!!!若是用的是IDEA開發,需配上該項,不然默認不會將mybatis的xml配置文件編譯到target中--> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build>
項目初始結構
項目三層建包結構和配置文件
mapper層:
mybatis配置文件[只需提供約束頭,裏面內容不用寫] mapper配置文件(接口.xml),寫sql語句. spring整合mapper配置文件 spring-mapper.xml
以下:
SQL
SELECT c.cust_id, c.cust_name, a.dict_item_name as cust_source, b.dict_item_name as cust_industry, d.dict_item_name as cust_level, c.cust_mobile, c.cust_phone FROM t_customer c LEFT OUTER JOIN t_basedict a ON c.cust_source = a.dict_id LEFT OUTER JOIN t_basedict b ON c.cust_industry = b.dict_id LEFT OUTER JOIN t_basedict d ON c.cust_level = d.dict_id;
編寫sqlMapConfig.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> </configuration>
編寫 CustomerMapper接口
分析:
QueryVo -- POJO類
public class QueryVo { private Integer cust_id; private String cust_name; private String cust_source; //來源 private String cust_industry;//行業 private String cust_level; //級別 private String cust_mobil; private String cust_phone; private Integer index;//分頁開始 private Integer rows;//數據條數 //getter and setter method... }
CustomerMapper中添加方法
public interface CustomerMapper { /** * 查詢客戶列表 * @param vo 條件對象 * @return 庫戶列表 */ public List<QueryVo> getCustomerList(QueryVo vo); }
配置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.xingc.example.mapper.CustomerMapper"> <select id="getCustomerList" parameterType="com.xingc.example.pojo.QueryVo" resultType="com.xingc.example.pojo.QueryVo"> SELECT c.cust_id, c.cust_name, a.dict_item_name AS cust_source, b.dict_item_name AS cust_industry, d.dict_item_name AS cust_level, c.cust_mobile, c.cust_phone FROM t_customer c LEFT OUTER JOIN t_basedict a ON c.cust_source = a.dict_id LEFT OUTER JOIN t_basedict b ON c.cust_industry = b.dict_id LEFT OUTER JOIN t_basedict d ON c.cust_level = d.dict_id <where> <if test="cust_name != null and cust_name != ''"> and c.custname LIKE '%${cust_name}%' </if> <if test="cust_source != null and cust_source != ''"> and cust_source = #{cust_source} </if> <if test="cust_industry != null and cust_industry != ''"> and cust_industry = #{cust_industry} </if> <if test="cust_level != null and cust_level != ''"> and cust_level = #{cust_level} </if> </where> limit #{index},#{rows} </select> </mapper>
添加db.propertis和log4j.properties配置文件
db.properties:數據庫鏈接的基礎配置//數據庫,用戶名,密碼等 log4j.properties:LOG日誌所需配置
db.properties
driverClass=com.mysql.jdbc.Driver url=jdbc:mysql:///ssm ##注意!!!!!!!!這個user除了username做爲變量名外均可以使用,但若是使用username,將會和系統中的username衝突,形成數據庫沒法鏈接成功. user=root password=
log4j.propertis
##設置日誌記錄到控制檯的方式 log4j.appender.s=org.apache.log4j.ConsoleAppender log4j.appender.s.Target=System.out log4j.appender.s.layout=org.apache.log4j.PatternLayout log4j.appender.s.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n ##設置日誌記錄到文件的方式 log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File=mylog.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n ##日誌輸出的級別,以及配置記錄方案 log4j.rootLogger=info, s
編寫spring-mapper.xml文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd"> <!--開啓註解--> <context:component-scan base-package="com.xingc.example"/> <!--引入外部配置propertis文件--> <context:property-placeholder location="classpath:db.properties"/> <!--數據庫鏈接池,這裏使用c3p0鏈接池--> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${driverClass}"/> <property name="jdbcUrl" value="${url}"/> <property name="user" value="${user}"/> <property name="password" value="${password}"/> </bean> <!--spring來管理mybatis的session工廠--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="configLocation" value="classpath:sqlMapConfig.xml"/> <!--使用包掃描即無需指定具體的xml文件,所以註釋--> <!--<property name="mapperLocations"> <array> <value>com/xingc/example/mapper/CustomerMapper.xml</value> </array> </property>--> </bean> <!--包掃描,全部mapper,此時spring將會管理mapper根據xml生成對應的代理類,取代理對象只須要使用@Autowired註解便可--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.xingc.example.mapper"></property> </bean> </beans>
測試走一波
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:spring-mapper.xml"}) public class CustomerMapperTest { @Autowired private CustomerMapper customerMapper; @Test public void test(){ QueryVo vo = new QueryVo(); vo.setIndex(0); vo.setRows(3); //查詢第一頁的三條記錄 List<QueryVo> customerList = customerMapper.getCustomerList(vo); System.out.println("\n+++結果數量: "+customerList.size()); System.out.println("\n+++結果顯示: "+customerList); } }
測試結果
至此,mapper測試成功,開發基本完成[單一列表顯示功能]
在service/pom.xml中添加mapper層的jar依賴
<dependencies> <dependency> <groupId>com.xingc.example</groupId> <artifactId>mapper</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>
module結構
編寫spring-service.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd"> <!--須要配置的內容:事務[若是使用註解式申明事務,徹底能夠省略該配置,只需在須要事務的類或方法中配置@Transactional便可]--> <!--事務管理bean--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!--前提是將mapper層的spring-mapper.xml也一塊兒加載,不然該鏈接池沒法使用,[web.xml中需同時加載spring-mapper.xml文件]--> <property name="dataSource" ref="dataSource"/> </bean> <!--事務--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="save*" propagation="REQUIRED"/> <tx:method name="udpate*" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> <tx:method name="select*" read-only="true"/> <tx:method name="get*" read-only="true"/> </tx:attributes> </tx:advice> <!--加強切面--> <aop:config> <aop:pointcut id="myPoint" expression="execution(* com.xingc.example.service.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="myPoint"/> </aop:config> </beans>
編寫客戶業務邏輯接口
public interface CustomerService { /** * 查詢客戶列表 * @param vo 條件對象 * @return 庫戶列表 */ public List<QueryVo> getCustomerList(QueryVo vo); }
編寫客戶業務邏輯實現
//注意:使用該註解的前提是已經配置了 <context:component-scan base-package="com.xingc.example"/> @Service("customerService") public class CustomerServiceImpl implements CustomerService { @Autowired private CustomerMapper customerMapper; @Override public List<QueryVo> getCustomerList(QueryVo vo) { return customerMapper.getCustomerList(vo); } }
測試再來一波
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath*:spring-*.xml"}) public class CustomerServiceTest { @Autowired private CustomerService customerService; @Test public void test() { QueryVo vo = new QueryVo(); vo.setIndex(0); vo.setRows(3); //查詢第一頁的三條記錄 List<QueryVo> customerList = customerService.getCustomerList(vo); System.out.println("\n+++結果數量: " + customerList.size()); System.out.println("\n+++結果顯示: " + customerList); } }
結果
因爲考慮到前端頁面須要對客戶列表進行分頁,所以這裏的業務邏輯須要修改
添加分頁實體
public class Page<T> { private int total; private int page; private int size; private List<T> rows; public int getTotal() { return total; } public void setTotal(int total) { this.total = total; } public int getPage() { return page; } public void setPage(int page) { this.page = page; } public int getSize() { return size; } public void setSize(int size) { this.size = size; } public List<T> getRows() { return rows; } public void setRows(List<T> rows) { this.rows = rows; } }
修改後的實現類和接口
public interface CustomerService { /** * 查詢客戶列表 * @param vo 條件對象 * @return 庫戶列表 */ public Page<Customer> getCustomerList(QueryVo vo, Integer page, Integer rows); }
實現
@Service("customerService") public class CustomerServiceImpl implements CustomerService { @Autowired private CustomerMapper customerMapper; @Override public Page<Customer> getCustomerList(QueryVo vo, Integer page, Integer rows) { page = page == null ? page = 1 : page; rows = rows == null ? rows = 8 : rows; //分頁處理 vo.setIndex((page - 1) * rows); vo.setRows(rows); //得到數據庫查出來的對象 List<QueryVo> list = customerMapper.getCustomerList(vo); //循環封裝 Page p = new Page(); p.setPage(page); p.setSize(rows); //總條數 int total = customerMapper.getCount(vo); p.setTotal(total); List<Customer> customers = new ArrayList<>(); Customer customer = null; for(QueryVo v : list){ customer = new Customer(); customer.setCust_id(v.getCust_id()); customer.setCust_name(v.getCust_name()); customer.setCust_source(v.getCust_source()); customer.setCust_industry(v.getCust_industry()); customer.setCust_level(v.getCust_level()); customer.setCust_mobile(v.getCust_mobil()); customer.setCust_phone(v.getCust_phone()); customers.add(customer); } p.setRows(customers); return p; } }
springmvc.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/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 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> <!--開啓註解--> <context:component-scan base-package="com.xingc.example"/> <!--默認使用springmvc的各類映射器/適配器等--> <mvc:annotation-driven/> <!--靜態資源映射--> <mvc:resources mapping="/css/**" location="/css/"/> <mvc:resources mapping="/js/**" location="/js/"/> <mvc:resources mapping="/fonts/**" location="/fonts/"/> <!--試圖解析器配置[解析xontroller的邏輯視圖爲物理視圖,就是去哪裏找jsp]--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp"/> <property name="suffix" value=".jsp"/> </bean> </beans>
web.xml配置
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <!--spring--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:spring-*.xml</param-value> </context-param> <!--監聽器--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!--springmvc--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--加載配置--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:springmvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
controller編寫
@Controller @RequestMapping("/cust/") public class CustomerController { @Autowired private CustomerService customerService; @RequestMapping("/getCustomerList") public String getCustomerList(QueryVo vo,Integer page,Integer rows,Model model) { Page<Customer> p = customerService.getCustomerList(vo, page, rows); model.addAttribute("page",p); return "customer"; } }
測試
說明:到這裏,ssm配置及基本環境搭建完成,數據成功查出.列表顯示後臺部分完結,再看一下此時的項目結構
說明:在這裏使用自定義標籤的方式定義分頁工具欄[和jstl標籤是一個道理]
首先,建立jsp自定義標籤,步驟以下
定義一個標籤類
/** * 顯示格式 上一頁 1 2 3 4 5 下一頁 */ public class NavigationTag extends TagSupport { static final long serialVersionUID = 2372405317744358833L; /** * request 中用於保存Page<E> 對象的變量名,默認爲「page」 */ private String bean = "page"; /** * 分頁跳轉的url地址,此屬性必須 */ private String url = null; /** * 顯示頁碼數量 */ private int number = 5; @Override public int doStartTag() throws JspException { JspWriter writer = pageContext.getOut(); HttpServletRequest request = (HttpServletRequest) pageContext.getRequest(); Page page = (Page)request.getAttribute(bean); if (page == null) return SKIP_BODY; url = resolveUrl(url, pageContext); try { //計算總頁數 int pageCount = page.getTotal() / page.getSize(); if (page.getTotal() % page.getSize() > 0) { pageCount++; } writer.print("<nav><ul class=\"pagination\">"); //顯示「上一頁」按鈕 if (page.getPage() > 1) { String preUrl = append(url, "page", page.getPage() - 1); preUrl = append(preUrl, "rows", page.getSize()); writer.print("<li><a href=\"" + preUrl + "\">上一頁</a></li>"); } else { writer.print("<li class=\"disabled\"><a href=\"#\">上一頁</a></li>"); } //顯示當前頁碼的前2頁碼和後兩頁碼 //若1 則 1 2 3 4 5, 若2 則 1 2 3 4 5, 若3 則1 2 3 4 5, //若4 則 2 3 4 5 6 ,若10 則 8 9 10 11 12 int indexPage = (page.getPage() - 2 > 0)? page.getPage() - 2 : 1; for(int i=1; i <= number && indexPage <= pageCount; indexPage++, i++) { if(indexPage == page.getPage()) { writer.print( "<li class=\"active\"><a href=\"#\">"+indexPage+"<span class=\"sr-only\">(current)</span></a></li>"); continue; } String pageUrl = append(url, "page", indexPage); pageUrl = append(pageUrl, "rows", page.getSize()); writer.print("<li><a href=\"" + pageUrl + "\">"+ indexPage +"</a></li>"); } //顯示「下一頁」按鈕 if (page.getPage() < pageCount) { String nextUrl = append(url, "page", page.getPage() + 1); nextUrl = append(nextUrl, "rows", page.getSize()); writer.print("<li><a href=\"" + nextUrl + "\">下一頁</a></li>"); } else { writer.print("<li class=\"disabled\"><a href=\"#\">下一頁</a></li>"); } writer.print("</nav>"); } catch (IOException e) { e.printStackTrace(); } return SKIP_BODY; } private String append(String url, String key, int value) { return append(url, key, String.valueOf(value)); } /** * 爲url 參加參數對兒 * * @param url * @param key * @param value * @return */ private String append(String url, String key, String value) { if (url == null || url.trim().length() == 0) { return ""; } if (url.indexOf("?") == -1) { url = url + "?" + key + "=" + value; } else { if(url.endsWith("?")) { url = url + key + "=" + value; } else { url = url + "&" + key + "=" + value; } } return url; } /** * 爲url 添加翻頁請求參數 * * @param url * @param pageContext * @return * @throws javax.servlet.jsp.JspException */ private String resolveUrl(String url, javax.servlet.jsp.PageContext pageContext) throws JspException{ //UrlSupport.resolveUrl(url, context, pageContext) Map params = pageContext.getRequest().getParameterMap(); for (Object key:params.keySet()) { if ("page".equals(key) || "rows".equals(key)) continue; Object value = params.get(key); if (value == null) continue; if (value.getClass().isArray()) { url = append(url, key.toString(), ((String[])value)[0]); } else if (value instanceof String) { url = append(url, key.toString(), value.toString()); } } return url; } /** * @return the bean */ public String getBean() { return bean; } /** * @param bean the bean to set */ public void setBean(String bean) { this.bean = bean; } /** * @return the url */ public String getUrl() { return url; } /** * @param url the url to set */ public void setUrl(String url) { this.url = url; } public void setNumber(int number) { this.number = number; } }
建立對應tld文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> <taglib> <tlib-version>2.0</tlib-version> <jsp-version>1.2</jsp-version> <short-name>common</short-name> <uri>http://xingc.com.cn/common/</uri> <display-name>Common Tag</display-name> <description>Common Tag library</description> <tag> <name>page</name> <tag-class>com.xingc.example.utils.NavigationTag</tag-class> <body-content>JSP</body-content> <description>create navigation for paging</description> <attribute> <name>bean</name> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>number</name> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>url</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
使用時,只須要引入 uri="http://xingc.com.cn/common/" 便可使用該標籤
JSP頁面customer.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false"%> <%@ page trimDirectiveWhitespaces="true" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="xingc" uri="http://xingc.com.cn/common/" %> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content=""> <title>客戶列表-BootCRM</title> <!-- 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"> <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script> <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script> <![endif]--> </head> <body> <div id="wrapper"> <!-- Navigation --> <nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="index.html">BOOT客戶管理系統 v2.0</a> </div> <!-- /.navbar-header --> <ul class="nav navbar-top-links navbar-right"> <li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#"> <i class="fa fa-envelope fa-fw"></i> <i class="fa fa-caret-down"></i> </a> <ul class="dropdown-menu dropdown-messages"> <li><a href="#"> <div> <strong>令狐沖</strong> <span class="pull-right text-muted"> <em>昨天</em> </span> </div> <div>今天晚上向大哥找我吃飯,討論一下去梅莊的事...</div> </a></li> <li class="divider"></li> <li><a class="text-center" href="#"> <strong>查看所有消息</strong> <i class="fa fa-angle-right"></i> </a></li> </ul> <!-- /.dropdown-messages --></li> <!-- /.dropdown --> <li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#"> <i class="fa fa-tasks fa-fw"></i> <i class="fa fa-caret-down"></i> </a> <ul class="dropdown-menu dropdown-tasks"> <li><a href="#"> <div> <p> <strong>任務 1</strong> <span class="pull-right text-muted">完成40%</span> </p> <div class="progress progress-striped active"> <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width: 40%"> <span class="sr-only">完成40%</span> </div> </div> </div> </a></li> <li class="divider"></li> <li><a href="#"> <div> <p> <strong>任務 2</strong> <span class="pull-right text-muted">完成20%</span> </p> <div class="progress progress-striped active"> <div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100" style="width: 20%"> <span class="sr-only">完成20%</span> </div> </div> </div> </a></li> <li class="divider"></li> <li><a class="text-center" href="#"> <strong>查看全部任務</strong> <i class="fa fa-angle-right"></i> </a></li> </ul> <!-- /.dropdown-tasks --></li> <!-- /.dropdown --> <li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#"> <i class="fa fa-bell fa-fw"></i> <i class="fa fa-caret-down"></i> </a> <ul class="dropdown-menu dropdown-alerts"> <li><a href="#"> <div> <i class="fa fa-comment fa-fw"></i> 新回覆 <span class="pull-right text-muted small">4分鐘以前</span> </div> </a></li> <li class="divider"></li> <li><a href="#"> <div> <i class="fa fa-envelope fa-fw"></i> 新消息 <span class="pull-right text-muted small">4分鐘以前</span> </div> </a></li> <li class="divider"></li> <li><a href="#"> <div> <i class="fa fa-tasks fa-fw"></i> 新任務 <span class="pull-right text-muted small">4分鐘以前</span> </div> </a></li> <li class="divider"></li> <li><a href="#"> <div> <i class="fa fa-upload fa-fw"></i> 服務器重啓 <span class="pull-right text-muted small">4分鐘以前</span> </div> </a></li> <li class="divider"></li> <li><a class="text-center" href="#"> <strong>查看全部提醒</strong> <i class="fa fa-angle-right"></i> </a></li> </ul> <!-- /.dropdown-alerts --></li> <!-- /.dropdown --> <li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#"> <i class="fa fa-user fa-fw"></i> <i class="fa fa-caret-down"></i> </a> <ul class="dropdown-menu dropdown-user"> <li><a href="#"><i class="fa fa-user fa-fw"></i> 用戶設置</a></li> <li><a href="#"><i class="fa fa-gear fa-fw"></i> 系統設置</a></li> <li class="divider"></li> <li><a href="login.html"><i class="fa fa-sign-out fa-fw"></i> 退出登陸</a></li> </ul> <!-- /.dropdown-user --></li> <!-- /.dropdown --> </ul> <!-- /.navbar-top-links --> <div class="navbar-default sidebar" role="navigation"> <div class="sidebar-nav navbar-collapse"> <ul class="nav" id="side-menu"> <li class="sidebar-search"> <div class="input-group custom-search-form"> <input type="text" class="form-control" placeholder="查詢內容..."> <span class="input-group-btn"> <button class="btn btn-default" type="button"> <i class="fa fa-search" style="padding: 3px 0 3px 0;"></i> </button> </span> </div> <!-- /input-group --> </li> <li><a href="customer.action" class="active"><i class="fa fa-edit fa-fw"></i> 客戶管理</a></li> <li><a href="salevisit.action"><i class="fa fa-dashboard fa-fw"></i> 客戶拜訪</a></li> </ul> </div> <!-- /.sidebar-collapse --> </div> <!-- /.navbar-static-side --> </nav> <div id="page-wrapper"> <div class="row"> <div class="col-lg-12"> <h1 class="page-header">客戶管理</h1> </div> <!-- /.col-lg-12 --> </div> <!-- /.row --> <div class="panel panel-default"> <div class="panel-body"> <form class="form-inline" action="${pageContext.request.contextPath }/customer/list.action" method="get"> <div class="form-group"> <label for="customerName">客戶名稱</label> <input type="text" class="form-control" id="customerName" value="${custName }" name="custName"> </div> <div class="form-group"> <label for="customerFrom">客戶來源</label> <select class="form-control" id="customerFrom" placeholder="客戶來源" name="custSource"> <option value="">--請選擇--</option> <c:forEach items="${fromType}" var="item"> <option value="${item.dict_id}"<c:if test="${item.dict_id == custSource}"> selected</c:if>>${item.dict_item_name }</option> </c:forEach> </select> </div> <div class="form-group"> <label for="custIndustry">所屬行業</label> <select class="form-control" id="custIndustry" name="custIndustry"> <option value="">--請選擇--</option> <c:forEach items="${industryType}" var="item"> <option value="${item.dict_id}"<c:if test="${item.dict_id == custIndustry}"> selected</c:if>>${item.dict_item_name }</option> </c:forEach> </select> </div> <div class="form-group"> <label for="custLevel">客戶級別</label> <select class="form-control" id="custLevel" name="custLevel"> <option value="">--請選擇--</option> <c:forEach items="${levelType}" var="item"> <option value="${item.dict_id}"<c:if test="${item.dict_id == custLevel}"> selected</c:if>>${item.dict_item_name }</option> </c:forEach> </select> </div> <button type="submit" class="btn btn-primary">查詢</button> </form> </div> </div> <div class="row"> <div class="col-lg-12"> <div class="panel panel-default"> <div class="panel-heading">客戶信息列表</div> <!-- /.panel-heading --> <table class="table table-bordered table-striped"> <thead> <tr> <th>ID</th> <th>客戶名稱</th> <th>客戶來源</th> <th>客戶所屬行業</th> <th>客戶級別</th> <th>固定電話</th> <th>手機</th> <th>操做</th> </tr> </thead> <tbody> <c:forEach items="${page.rows}" var="row"> <tr> <td>${row.cust_id}</td> <td>${row.cust_name}</td> <td>${row.cust_source}</td> <td>${row.cust_industry}</td> <td>${row.cust_level}</td> <td>${row.cust_phone}</td> <td>${row.cust_mobile}</td> <td> <a href="#" class="btn btn-primary btn-xs" data-toggle="modal" data-target="#customerEditDialog" onclick="editCustomer(${row.cust_id})">修改</a> <a href="#" class="btn btn-danger btn-xs" onclick="deleteCustomer(${row.cust_id})">刪除</a> </td> </tr> </c:forEach> </tbody> </table> <div class="col-md-12 text-right"> <itcast:page url="${pageContext.request.contextPath }/customer/list.action"/> </div> <!-- /.panel-body --> </div> <!-- /.panel --> </div> <!-- /.col-lg-12 --> </div> </div> <!-- /#page-wrapper --> </div> <!-- 客戶編輯對話框 --> <div class="modal fade" id="customerEditDialog" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> <h4 class="modal-title" id="myModalLabel">修改客戶信息</h4> </div> <div class="modal-body"> <form class="form-horizontal" id="edit_customer_form"> <input type="hidden" id="edit_cust_id" name="cust_id"/> <div class="form-group"> <label for="edit_customerName" class="col-sm-2 control-label">客戶名稱</label> <div class="col-sm-10"> <input type="text" class="form-control" id="edit_customerName" placeholder="客戶名稱" name="cust_name"> </div> </div> <div class="form-group"> <label for="edit_customerFrom" style="float:left;padding:7px 15px 0 27px;">客戶來源</label> <div class="col-sm-10"> <select class="form-control" id="edit_customerFrom" placeholder="客戶來源" name="cust_source"> <option value="">--請選擇--</option> <c:forEach items="${fromType}" var="item"> <option value="${item.dict_id}"<c:if test="${item.dict_id == custSource}"> selected</c:if>>${item.dict_item_name }</option> </c:forEach> </select> </div> </div> <div class="form-group"> <label for="edit_custIndustry" style="float:left;padding:7px 15px 0 27px;">所屬行業</label> <div class="col-sm-10"> <select class="form-control" id="edit_custIndustry" name="cust_industry"> <option value="">--請選擇--</option> <c:forEach items="${industryType}" var="item"> <option value="${item.dict_id}"<c:if test="${item.dict_id == custIndustry}"> selected</c:if>>${item.dict_item_name }</option> </c:forEach> </select> </div> </div> <div class="form-group"> <label for="edit_custLevel" style="float:left;padding:7px 15px 0 27px;">客戶級別</label> <div class="col-sm-10"> <select class="form-control" id="edit_custLevel" name="cust_level"> <option value="">--請選擇--</option> <c:forEach items="${levelType}" var="item"> <option value="${item.dict_id}"<c:if test="${item.dict_id == custLevel}"> selected</c:if>>${item.dict_item_name }</option> </c:forEach> </select> </div> </div> <div class="form-group"> <label for="edit_linkMan" class="col-sm-2 control-label">聯繫人</label> <div class="col-sm-10"> <input type="text" class="form-control" id="edit_linkMan" placeholder="聯繫人" name="cust_linkman"> </div> </div> <div class="form-group"> <label for="edit_phone" class="col-sm-2 control-label">固定電話</label> <div class="col-sm-10"> <input type="text" class="form-control" id="edit_phone" placeholder="固定電話" name="cust_phone"> </div> </div> <div class="form-group"> <label for="edit_mobile" class="col-sm-2 control-label">移動電話</label> <div class="col-sm-10"> <input type="text" class="form-control" id="edit_mobile" placeholder="移動電話" name="cust_mobile"> </div> </div> <div class="form-group"> <label for="edit_zipcode" class="col-sm-2 control-label">郵政編碼</label> <div class="col-sm-10"> <input type="text" class="form-control" id="edit_zipcode" placeholder="郵政編碼" name="cust_zipcode"> </div> </div> <div class="form-group"> <label for="edit_address" class="col-sm-2 control-label">聯繫地址</label> <div class="col-sm-10"> <input type="text" class="form-control" id="edit_address" placeholder="聯繫地址" name="cust_address"> </div> </div> </form> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">關閉</button> <button type="button" class="btn btn-primary" onclick="updateCustomer()">保存修改</button> </div> </div> </div> </div> <!-- /#wrapper --> <!-- jQuery --> <script src="<%=basePath%>js/jquery.min.js"></script> <!-- Bootstrap Core JavaScript --> <script src="<%=basePath%>js/bootstrap.min.js"></script> <!-- Metis Menu Plugin JavaScript --> <script src="<%=basePath%>js/metisMenu.min.js"></script> <!-- DataTables JavaScript --> <script src="<%=basePath%>js/jquery.dataTables.min.js"></script> <script src="<%=basePath%>js/dataTables.bootstrap.min.js"></script> <!-- Custom Theme JavaScript --> <script src="<%=basePath%>js/sb-admin-2.js"></script> <script type="text/javascript"> function editCustomer(id) { $.ajax({ type: "get", url: "<%=basePath%>customer/edit.action", data: {"id": id}, success: function (data) { $("#edit_cust_id").val(data.cust_id); $("#edit_customerName").val(data.cust_name); $("#edit_customerFrom").val(data.cust_source) $("#edit_custIndustry").val(data.cust_industry) $("#edit_custLevel").val(data.cust_level) $("#edit_linkMan").val(data.cust_linkman); $("#edit_phone").val(data.cust_phone); $("#edit_mobile").val(data.cust_mobile); $("#edit_zipcode").val(data.cust_zipcode); $("#edit_address").val(data.cust_address); } }); } function updateCustomer() { $.post("<%=basePath%>customer/update.action", $("#edit_customer_form").serialize(), function (data) { alert("客戶信息更新成功!"); window.location.reload(); }); } function deleteCustomer(id) { if (confirm('確實要刪除該客戶嗎?')) { $.post("<%=basePath%>customer/delete.action", {"id": id}, function (data) { alert("客戶刪除更新成功!"); window.location.reload(); }); } } </script> </body> </html>
測試結果
客戶列表成功顯示
我如今正在學ssm框架,水平不夠,若是有什麼bug,還請見諒,原本打算寫一下條件查詢和修改,刪除等功能的,但到這裏發現本身寫了不少,就不贅述了.由於環境搭建好後,別的功能就相對簡單一些.