Personnel Management System
1. Create a project
1.1 Create projects using reverse engineering
Automatically generate entity class bean s, mapper interfaces, and mapping files
1.2 pom.xml Writing Import Dependency
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!-- Spring--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.5</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.5</version> </dependency> <!-- section--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.6</version> </dependency> <!-- springmvc--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.5</version> </dependency> <!-- fastjson--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.75</version> </dependency> <!-- jackson-databind--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.12.4</version> </dependency> <!-- mybatis--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.2</version> </dependency> <!-- mybatis-spring--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.6</version> </dependency> <!-- lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> </dependency> <!-- data base--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.23</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.3</version> </dependency> <!-- servlet api You can use native servlet--> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- paging--> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.2.0</version> </dependency> <!--shiro-spring--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.6.0</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> <!-- spring-aspects--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.3.5</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.7.1</version> </dependency> <dependency> <groupId>jspapi</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> </dependency> </dependencies> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> <filtering>true</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> <filtering>true</filtering> </resource> </resources> </build>
1.2 Configuration File Writing
1.2.1 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:mybatis="http://mybatis.org/schema/mybatis-spring" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <!--1.Configure Component Scan,Main Scan service and mapper package--> <context:component-scan base-package="com.hrf.service,com.hrf.mapper"/> <!-- 2.Introducing an external property file--> <context:property-placeholder location="classpath*:jdbc.properties"/> <!-- 3.Configure Data Source--> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <!-- 4.To configure sqlsessionFactory--> <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 4.1 Configure Data Source--> <property name="dataSource" ref="dataSource"/> <!-- 4.4 Load Settings--> <property name="configuration"> <bean class="org.apache.ibatis.session.Configuration"> <property name="mapUnderscoreToCamelCase" value="true"/> <property name="logImpl" value="org.apache.ibatis.logging.log4j.Log4jImpl"/> </bean> </property> <!-- 4.5 Plug-in Paging Plug-in--> <property name="plugins"> <list> <bean class="com.github.pagehelper.PageInterceptor"/> </list> </property> <!-- 4.2 Define Alias--> <property name="typeAliasesPackage" value="com.hrf.bean"/> <!-- 4.2 Load mybatis Core Profile configLocation--> <!-- <property name="configLocation" value="classpath:mybatis-config.xml"/>--> <!-- 4.3 Load mapper Configuration file inside--> <property name="mapperLocations" value="classpath*:com/hrf/mapper/*.xml"/> </bean> <!-- 5.search mapper Mapping interface--> <mybatis:scan base-package="com.hrf.mapper"/> <!-- 6.transaction management--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 7.Transaction Face Configuration--> <tx:advice id="transactionInterceptor" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*"/> </tx:attributes> </tx:advice> <!-- 8.Association of transaction facets with entry points--> <aop:config proxy-target-class="true"> <aop:pointcut id="p" expression="execution(* com.hrf.service.*.*(..))"/> <aop:advisor advice-ref="transactionInterceptor" pointcut-ref="p"/> </aop:config> </beans>
1.2.2 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" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <!--1.Component Scan,Mainly scan controller--> <context:component-scan base-package="com.hrf.controller"/> <!-- 2.Open Notes--> <mvc:annotation-driven> <!-- If fastjson Return json Data needs to continue configuration--> <mvc:message-converters> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="defaultCharset" value="utf-8"/> </bean> </mvc:message-converters> </mvc:annotation-driven> <!-- 3.Configure View Parser--> <!-- <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">--> <!-- <property name="prefix" value="/"/>--> <!-- <property name="suffix" value=".jsp"/>--> <!-- </bean>--> <!-- <mvc:view-resolvers>--> <!-- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">--> <!-- <property name="prefix" value="/"/>--> <!-- <property name="suffix" value=".jsp"/>--> <!-- </bean>--> <!-- </mvc:view-resolvers>--> <!-- 4.Processing static resources--> <mvc:default-servlet-handler></mvc:default-servlet-handler> <!-- Specify Use Cglib As AOP Dynamic Proxy Implementation --> <aop:config proxy-target-class="true"/> <!-- open Shiro Permission Annotation Support --> <!-- <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">--> <!-- <property name="securityManager" ref="securityManager"/>--> <!-- </bean>--> <!-- Handle Annotation Check Permission Page Error Exception --> <!-- Define exceptions that need special handling, using class or full path names as key,Exception Page Name as Value --> <!-- <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">--> <!-- <property name="exceptionMappings"> <props>--> <!-- <prop key="org.apache.shiro.authz.UnauthorizedException">/forbidden.jsp</prop>--> <!-- <prop key="org.apache.shiro.authz.AuthorizationException">/forbidden.jsp</prop>--> <!-- </props>--> <!-- </property>--> <!-- </bean>--> </beans>
1.2.3 jdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/hrmanagement?serverTimeZone=UTC jdbc.username=root jdbc.password=0429
1.2.4 log4j.properties
# Global Log Configuration log4j.rootLogger=ERROR, stdout # MyBatis Log Configuration log4j.logger.com.hrf.mapper=TRACE # console output log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
1.3 Integration with the Web (Writing of web.xml)
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- Set Welcome Page--> <welcome-file-list> <welcome-file>/WEB-INF/jsp/loginForm.jsp</welcome-file> </welcome-file-list> <!-- Configure filters--> <filter> <filter-name>code</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> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>code</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- Configure Central Processor--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- binding springmvc--> <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> <!-- Spring Context Listener Configuration Listener--> <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> <!-- shiro Filter--> <!-- <filter>--> <!-- <filter-name>shiroFilter</filter-name>--> <!-- <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>--> <!-- </filter>--> <!-- <filter-mapping>--> <!-- <filter-name>shiroFilter</filter-name>--> <!-- <url-pattern>/*</url-pattern>--> <!-- <dispatcher>REQUEST</dispatcher>--> <!-- <dispatcher>FORWARD</dispatcher>--> <!-- </filter-mapping>--> <!-- Set Session Configuration session-timeout 5 Minute--> <!-- <session-config>--> <!-- <session-timeout>5</session-timeout>--> <!-- </session-config>--> </web-app>
Note: Set the default welcome page, loginForm.jsp, to log in and see the code above.
1.4 Import Tool Class
1.4.1 Paging Label
package com.hrf.util; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; /** * Paging Label */ public class PagerTag extends SimpleTagSupport { /** Define placeholder constants in request URL s */ private static final String TAG = "{0}"; /** CurrentPage */ private int pageIndex; /** Number of displays per page */ private int pageSize; /** Total number of records */ private int recordCount; /** Request URL page.action?pageIndex={0}*/ private String submitUrl; /** style */ private String style = "sabrosus"; /** Define total pages */ private int totalPage = 0; /** Referencing a custom label on a page triggers a label processing class */ @Override public void doTag() throws JspException, IOException { /** Define it as stitching the end result */ StringBuilder res = new StringBuilder(); /** Define the page number in the middle of its stitching */ StringBuilder str = new StringBuilder(); /** Judging the total number of records */ if (recordCount > 0){ //1499 / 15 = 100 /** Paging labels need to be displayed to calculate how many pages the total number of pages needs to be divided */ totalPage = (this.recordCount - 1) / this.pageSize + 1; /** a label is not required to determine the previous or next page */ if (this.pageIndex == 1){ // home page str.append("<span class='disabled'>Previous page</span>"); /** Calculate the middle page number */ this.calcPage(str); /** Next page does not require a label */ if (this.pageIndex == totalPage){ /** Only one page */ str.append("<span class='disabled'>next page</span>"); }else{ String tempUrl = this.submitUrl.replace(TAG, String.valueOf(pageIndex + 1)); str.append("<a href='"+ tempUrl +"'>next page</a>"); } }else if (this.pageIndex == totalPage){ // End Page String tempUrl = this.submitUrl.replace(TAG, String.valueOf(pageIndex - 1)); str.append("<a href='"+ tempUrl +"'>Previous page</a>"); /** Calculate the middle page number */ this.calcPage(str); str.append("<span class='disabled'>next page</span>"); }else{ // Middle String tempUrl = this.submitUrl.replace(TAG, String.valueOf(pageIndex - 1)); str.append("<a href='"+ tempUrl +"'>Previous page</a>"); /** Calculate the middle page number */ this.calcPage(str); tempUrl = this.submitUrl.replace(TAG, String.valueOf(pageIndex + 1)); str.append("<a href='"+ tempUrl +"'>next page</a>"); } /** Stitch together other information */ res.append("<table width='100%' align='center' style='font-size:13px;' class='"+ style +"'>"); res.append("<tr><td style='COLOR: #0061de; MARGIN-RIGHT: 3px; PADDING-TOP: 2px; TEXT-DECORATION: none'>" + str.toString()); res.append(" Jump To <input style='text-align: center;BORDER-RIGHT: #aaaadd 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #aaaadd 1px solid; PADDING-LEFT: 5px; PADDING-BOTTOM: 2px; MARGIN: 2px; BORDER-LEFT: #aaaadd 1px solid; COLOR: #000099; PADDING-TOP: 2px; BORDER-BOTTOM: #aaaadd 1px solid; TEXT-DECORATION: none' type='text' size='2' id='pager_jump_page_size'/>"); res.append(" <input type='button' style='text-align: center;BORDER-RIGHT: #dedfde 1px solid; PADDING-RIGHT: 6px; BACKGROUND-POSITION: 50% bottom; BORDER-TOP: #dedfde 1px solid; PADDING-LEFT: 6px; PADDING-BOTTOM: 2px; BORDER-LEFT: #dedfde 1px solid; COLOR: #0061de; MARGIN-RIGHT: 3px; PADDING-TOP: 2px; BORDER-BOTTOM: #Dedfde 1px solid; TEXT-DECORATION: none'value='ok' id='pager_ Jump_ Btn'/>'; res.append("</td></tr>"); res.append("<tr align='center'><td style='font-size:13px;'><tr><td style='COLOR: #0061de; MARGIN-RIGHT: 3px; PADDING-TOP: 2px; TEXT-DECORATION: none'>"); /** Number of start bars */ int startNum = (this.pageIndex - 1) * this.pageSize + 1; /** Number of end bars */ int endNum = (this.pageIndex == this.totalPage) ? this.recordCount : this.pageIndex * this.pageSize; res.append("In total<font color='red'>"+ this.recordCount +"</font>Bar records, currently displayed"+ startNum +"-"+ endNum +"Records."); res.append("</td></tr>"); res.append("</table>"); res.append("<script type='text/javascript'>"); res.append(" document.getElementById('pager_jump_btn').onclick = function(){"); res.append(" var page_size = document.getElementById('pager_jump_page_size').value;"); res.append(" if (!/^[1-9]\\d*$/.test(page_size) || page_size < 1 || page_size > "+ this.totalPage +"){"); res.append(" alert('Please enter[1-"+ this.totalPage +"]Page number between!');"); res.append(" }else{"); res.append(" var submit_url = '" + this.submitUrl + "';"); res.append(" window.location = submit_url.replace('"+ TAG +"', page_size);"); res.append(" }"); res.append("}"); res.append("</script>"); }else{ res.append("<table align='center' style='font-size:13px;'><tr><td style='COLOR: #0061de; MARGIN-RIGHT: 3px; PADDING-TOP: 2px; TEXT-DECORATION: none'>Total <font color='red'>0</font>records, currently displaying 0-0 records. </ Td></tr></table>"; } this.getJspContext().getOut().print(res.toString()); } /** Method of calculating intermediate page number */ private void calcPage(StringBuilder str) { /** Judging Total Pages */ if (this.totalPage <= 11){ /** Show all page numbers at once */ for (int i = 1; i <= this.totalPage; i++){ if (this.pageIndex == i){ /** CurrentPage */ str.append("<span class='current'>"+ i +"</span>"); }else{ String tempUrl = this.submitUrl.replace(TAG, String.valueOf(i)); str.append("<a href='"+ tempUrl +"'>"+ i +"</a>"); } } }else{ /** Near Home Page */ if (this.pageIndex <= 8){ for (int i = 1; i <= 10; i++){ if (this.pageIndex == i){ /** CurrentPage */ str.append("<span class='current'>"+ i +"</span>"); }else{ String tempUrl = this.submitUrl.replace(TAG, String.valueOf(i)); str.append("<a href='"+ tempUrl +"'>"+ i +"</a>"); } } str.append("..."); String tempUrl = this.submitUrl.replace(TAG, String.valueOf(this.totalPage)); str.append("<a href='"+ tempUrl +"'>"+ this.totalPage +"</a>"); } /** Near End Page */ else if (this.pageIndex + 8 >= this.totalPage){ String tempUrl = this.submitUrl.replace(TAG, String.valueOf(1)); str.append("<a href='"+ tempUrl +"'>1</a>"); str.append("..."); for (int i = this.totalPage - 10; i <= this.totalPage; i++){ if (this.pageIndex == i){ /** CurrentPage */ str.append("<span class='current'>"+ i +"</span>"); }else{ tempUrl = this.submitUrl.replace(TAG, String.valueOf(i)); str.append("<a href='"+ tempUrl +"'>"+ i +"</a>"); } } } /** In the middle */ else{ String tempUrl = this.submitUrl.replace(TAG, String.valueOf(1)); str.append("<a href='"+ tempUrl +"'>1</a>"); str.append("..."); for (int i = this.pageIndex - 4; i <= this.pageIndex + 4; i++){ if (this.pageIndex == i){ /** CurrentPage */ str.append("<span class='current'>"+ i +"</span>"); }else{ tempUrl = this.submitUrl.replace(TAG, String.valueOf(i)); str.append("<a href='"+ tempUrl +"'>"+ i +"</a>"); } } str.append("..."); tempUrl = this.submitUrl.replace(TAG, String.valueOf(this.totalPage)); str.append("<a href='"+ tempUrl +"'>"+ this.totalPage +"</a>"); } } } /** setter Method */ public void setPageIndex(int pageIndex) { this.pageIndex = pageIndex; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public void setRecordCount(int recordCount) { this.recordCount = recordCount; } public void setSubmitUrl(String submitUrl) { this.submitUrl = submitUrl; } public void setStyle(String style) { this.style = style; } }
1.4.2 Authentication Code Related
package com.hrf.util; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Arrays; import java.util.Random; import javax.imageio.ImageIO; public class VerifyCodeUtils { //With Algerian fonts, you need to install fonts if they are not available on the system. Fonts are capitalized, with 1,0,i,o characters removed and W characters taken up too wide public static final String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVXYZ"; private static Random random = new Random(); /** * Generate Authentication Code with System Default Character Source * @param verifySize Authentication code length * @return */ public static String generateVerifyCode(int verifySize){ return generateVerifyCode(verifySize, VERIFY_CODES); } /** * Generate Authentication Code with Specified Source * @param verifySize Authentication code length * @param sources Authentication Code Character Source * @return */ public static String generateVerifyCode(int verifySize, String sources){ if(sources == null || sources.length() == 0){ sources = VERIFY_CODES; } int codesLen = sources.length(); Random rand = new Random(System.currentTimeMillis()); StringBuilder verifyCode = new StringBuilder(verifySize); for(int i = 0; i < verifySize; i++){ verifyCode.append(sources.charAt(rand.nextInt(codesLen-1))); } return verifyCode.toString(); } /** * Generate a random validation code file and return the validation code value * @param w * @param h * @param outputFile * @param verifySize * @return * @throws IOException */ public static String outputVerifyImage(int w, int h, File outputFile, int verifySize) throws IOException{ String verifyCode = generateVerifyCode(verifySize); outputImage(w, h, outputFile, verifyCode); return verifyCode; } /** * Output random authenticator picture stream and return the authenticator value * @param w * @param h * @param os * @param verifySize * @return * @throws IOException */ public static String outputVerifyImage(int w, int h, OutputStream os, int verifySize) throws IOException{ String verifyCode = generateVerifyCode(verifySize); outputImage(w, h, os, verifyCode); return verifyCode; } /** * Generate the specified Authentication Code image file * @param w * @param h * @param outputFile * @param code * @throws IOException */ public static void outputImage(int w, int h, File outputFile, String code) throws IOException{ if(outputFile == null){ return; } File dir = outputFile.getParentFile(); if(!dir.exists()){ dir.mkdirs(); } try{ outputFile.createNewFile(); FileOutputStream fos = new FileOutputStream(outputFile); outputImage(w, h, fos, code); fos.close(); } catch(IOException e){ throw e; } } /** * Output Specified Authentication Code Picture Stream * @param w * @param h * @param os * @param code * @throws IOException */ public static void outputImage(int w, int h, OutputStream os, String code) throws IOException{ int verifySize = code.length(); BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Random rand = new Random(); Graphics2D g2 = image.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); Color[] colors = new Color[5]; Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN, Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.YELLOW }; float[] fractions = new float[colors.length]; for(int i = 0; i < colors.length; i++){ colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)]; fractions[i] = rand.nextFloat(); } Arrays.sort(fractions); g2.setColor(Color.GRAY);// Set border color g2.fillRect(0, 0, w, h); Color c = getRandColor(200, 250); g2.setColor(c);// Set Background Color g2.fillRect(0, 2, w, h-4); //Draw interference lines Random random = new Random(); g2.setColor(getRandColor(160, 200));// Set the color of the line for (int i = 0; i < 20; i++) { int x = random.nextInt(w - 1); int y = random.nextInt(h - 1); int xl = random.nextInt(6) + 1; int yl = random.nextInt(12) + 1; g2.drawLine(x, y, x + xl + 40, y + yl + 20); } // add noise float yawpRate = 0.05f;// Noise Rate int area = (int) (yawpRate * w * h); for (int i = 0; i < area; i++) { int x = random.nextInt(w); int y = random.nextInt(h); int rgb = getRandomIntColor(); image.setRGB(x, y, rgb); } shear(g2, w, h, c);// Twist the picture g2.setColor(getRandColor(100, 160)); int fontSize = h-4; Font font = new Font("Algerian", Font.PLAIN, fontSize); g2.setFont(font); char[] chars = code.toCharArray(); for(int i = 0; i < verifySize; i++){ //AffineTransform affine = new AffineTransform(); //affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, h/2); //g2.setTransform(affine); g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, h/2 + fontSize/2 - 10); } g2.dispose(); ImageIO.write(image, "jpg", os); } private static Color getRandColor(int fc, int bc) { if (fc > 255) fc = 255; if (bc > 255) bc = 255; int r = fc + random.nextInt(bc - fc); int g = fc + random.nextInt(bc - fc); int b = fc + random.nextInt(bc - fc); return new Color(r, g, b); } private static int getRandomIntColor() { int[] rgb = getRandomRgb(); int color = 0; for (int c : rgb) { color = color << 8; color = color | c; } return color; } private static int[] getRandomRgb() { int[] rgb = new int[3]; for (int i = 0; i < 3; i++) { rgb[i] = random.nextInt(255); } return rgb; } private static void shear(Graphics g, int w1, int h1, Color color) { shearX(g, w1, h1, color); shearY(g, w1, h1, color); } private static void shearX(Graphics g, int w1, int h1, Color color) { int period = random.nextInt(2); boolean borderGap = true; int frames = 1; int phase = random.nextInt(2); for (int i = 0; i < h1; i++) { double d = (double) (period >> 1) * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames); g.copyArea(0, i, w1, 1, (int) d, 0); if (borderGap) { g.setColor(color); g.drawLine((int) d, i, 0, i); g.drawLine((int) d + w1, i, w1, i); } } } private static void shearY(Graphics g, int w1, int h1, Color color) { int period = random.nextInt(40) + 10; // 50; boolean borderGap = true; int frames = 20; int phase = 7; for (int i = 0; i < w1; i++) { double d = (double) (period >> 1) * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames); g.copyArea(i, 0, 1, h1, 0, (int) d); if (borderGap) { g.setColor(color); g.drawLine(i, (int) d, i, 0); g.drawLine(i, (int) d + h1, i, h1); } } } }
1.4.3 Paged PageModel
package com.hrf.util; import java.io.Serializable; public class PageModel implements Serializable{ private Integer pageIndex=1; private Integer pageSize=6; private Integer recordCount; public Integer getPageIndex() { return pageIndex; } public void setPageIndex(Integer pageIndex) { this.pageIndex = pageIndex; } public Integer getPageSize() { return pageSize; } public void setPageSize(Integer pageSize) { this.pageSize = pageSize; } public Integer getRecordCount() { return recordCount; } public void setRecordCount(Integer recordCount) { this.recordCount = recordCount; } public PageModel() { super(); } public PageModel(Integer pageIndex, Integer pageSize, Integer recordCount) { super(); this.pageIndex = pageIndex; this.pageSize = pageSize; this.recordCount = recordCount; } }
Paging may not be used, but a paging plugin is required
2. Write project code
2.1 Create a controller layer
2.2 Create service layer
3. Implementation of user login module
3.1 UserLoginController implementation, using shiro
package com.hrf.controller; import com.hrf.bean.User; import com.hrf.service.UserLoginService; import com.hrf.util.VerifyCodeUtils; import com.sun.org.apache.regexp.internal.RE; import lombok.extern.slf4j.Slf4j; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.*; import org.apache.shiro.subject.Subject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import java.util.List; @Controller @Slf4j public class UserLoginController { @Autowired private UserLoginService userLoginService; // 1. Check the verification code @RequestMapping("/checkCode") public void checkCode(String num, HttpSession session, HttpServletResponse response) throws IOException { ServletOutputStream outputStream = response.getOutputStream(); int w = 200, h = 80; String code = VerifyCodeUtils.generateVerifyCode(4); session.setAttribute("code",code); VerifyCodeUtils.outputImage(w, h, outputStream, code); outputStream.close(); } // 2. Log on @RequestMapping("/login") public String login(String loginname,String password, String user_input_verifyCode,Model model,HttpSession session) throws Exception { // If the username and password are not empty, call shiro to verify that the username and password are correct if (loginname==null||("").equals(loginname)){ model.addAttribute("msg","Login name cannot be empty"); throw new Exception("User name cannot be empty"); } if (password==null||("").equals(password)){ model.addAttribute("msg","Password cannot be empty"); throw new Exception("Password cannot be empty"); } // if (user_input_verifyCode==null||("").equals(user_input_verifyCode)){ // model.addAttribute("msg", "Authentication code cannot be empty"); // throw new Exception("Authentication code cannot be empty"); // } // Encapsulate username and password as token objects UsernamePasswordToken token = new UsernamePasswordToken(loginname, password); // shiro verify login success try{ // shiro login Subject subject = SecurityUtils.getSubject(); subject.login(token); // Query user based on loginname User user_session = userLoginService.findUserByLoginname(loginname); session.setAttribute("user_session",user_session); // Jump to the successful login page return "/jsp/index.jsp"; }catch (UnknownAccountException e){ // Logon failed, print exception information log.error("user name does not exist"); }catch (LockedAccountException e){ log.error("Account Locked"); }catch (IncorrectCredentialsException e){ log.error("Password error"); }catch (AuthenticationException e) { // Other authentication exceptions log.error("Logon Failure"); } model.addAttribute("msg","User name or password error!"); // Return to the login page return "/jsp/loginForm.jsp"; } // 3. Home page display @RequestMapping("/welcome") public String welcome(){ return "/jsp/welcome.jsp"; } // 4. User registration @RequestMapping("/register/registCode") public String registCode(){ System.out.println("User registration"); return "/jsp/regist.jsp"; } // 5. Retrieve your password @RequestMapping("/password/repassword") public String repassword(){ System.out.println("Retrieve password!"); return "/jsp/findPwd.jsp"; } @RequestMapping("/logOut") public String logOut(HttpSession session){ // Remove user from session session.removeAttribute("user_session"); // Invalidate session session.invalidate(); // Return to the login page return "/jsp/loginForm.jsp"; } }
3.2 Customize realm classes, authenticate, authorize
package com.hrf.util; import com.hrf.bean.User; import com.hrf.service.UserLoginService; import lombok.extern.slf4j.Slf4j; import org.apache.shiro.authc.*; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.crypto.hash.Md5Hash; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; /* Custom Authentication Class */ @Slf4j public class MyRealm extends AuthorizingRealm { @Autowired private UserLoginService userLoginService; @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { log.debug("Start Authorization---------"); //Get the current logged on user identity String loginname = (String)principalCollection.getPrimaryPrincipal(); //Associate database tables to find user-specific roles, permissions menus // Analog data SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.addRole("admin"); return info; // return null; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { log.debug("Start Authentication...."); //Authentication Method UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; //Get User Identity String loginname = (String)token.getPrincipal(); // Get password credentials //4. Get the credential password char[] cs = (char[]) token.getCredentials(); String password = String.valueOf(cs); //First parameter source code Second parameter salt salt Third parameter iteration number Md5Hash password1 = new Md5Hash(password,loginname,5); System.out.println(password1); //Analog data, only username equals admin, assuming the user exists User user = userLoginService.findUserByLoginname(loginname); if (user!=null) { return new SimpleAuthenticationInfo(loginname, user.getPassword(), ByteSource.Util.bytes(loginname), getName()); } return null; } }
Note: how shiro works
1. Shiro Running Process
For example, a login process:
1. Call Subject.login(token) to log in first, and he will delegate it to SecurityManager
2. SecurityManager is responsible for the real authentication logic; It delegates authentication to Authenticator;
3. Authenticator passes the corresponding token into Realm, obtains authentication information from Realm, returns authentication failure if not, and continues if not.
2. Describe the Shiro certification process
1. The application code calls the Subject.login method to pass the created AutohenticationToken instance that contains the Principals (identity) and Reduentials (credentials) of the end user;
2. The Subject instance delegates the application's SecurityManager to begin real validation by calling securityManager.login(token); Subject instance (usually DelegatingSubject or its subclasses)
3. SubjectManager receives token and calls the internal Authenticator instance to call authenticator.authenticate(token).Authenticator is usually a ModularRealmAuthenticator instance that supports reconciling one or more Realm instances in authentication;
4. If more than one Realm is configured in the application, the ModularRealmAuthenticator instance will use the configured AuthenticationStrategy to initiate the Multi-Realm authentication attempt. Before, during, and after Realms are invoked by authentication, AuthenticationStrategy is invoked to enable it to respond to the results of each Realm. (AuthenticationStrategy is called to react to the results of each Realm);
5. The Realm of each configuration is used to help see if it supports the submitted Authentication Token. If so, the getAuthentication Info method that supports Realm will be called with the submitted token. The getAuthentication Info method effectively represents a single authentication attempt for a specific Realm.
3. How to configure using Shiro in Spring
1, configure Shiro's Filter in web.xml;
2. Configure Shiro in Spring's configuration file;
3. Configure custom Realm: implement custom authentication and authorization;
4. Configure the caching strategy used by Shiro entity classes;
5. Configure SecurityManager;
6. Configure a Lifecycle Bean postprocessor that guarantees that the Shiro internal Bean declaration cycle is executed;
4. For fuzzy queries on search, paging, query lists are best written in a controller
4.1 Front End Writes Path
4.1.1 index.jsp front-end interface
<li> <a href="javascript:;"> <i class="iconfont"></i> <cite>Download Center</cite> <i class="iconfont nav_right"></i> </a> <ul class="sub-menu"> <li> <a _href="${pageContext.request.contextPath}/document/list"> <i class="iconfont"></i> <cite>Document Query</cite> </a> </li> <li id="document"> <a _href="${pageContext.request.contextPath}/document/toadd"> <i class="iconfont"></i> <cite>Upload Document</cite> </a> </li> </ul> </li>
4.1.2 list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib prefix="fkjava" uri="/pager-tags" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>document information</title> <meta name="renderer" content="webkit"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" /> <link rel="shortcut icon" href="${pageContext.request.contextPath}/public/logo.ico" type="image/x-icon" /> <link rel="stylesheet" href="${pageContext.request.contextPath}/public/css/font.css"> <link rel="stylesheet" href="${pageContext.request.contextPath}/public/css/xadmin.css"> <script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script> <script type="text/javascript" src="${pageContext.request.contextPath}/public/lib/layui/layui.js" charset="utf-8"></script> <script type="text/javascript" src="${pageContext.request.contextPath}/public/js/xadmin.js"></script> <script type="text/javascript"> $(function(){ /** Download Document Function */ $("a[id^='down_']").click(function(){ /** Get the id of the document you want to download */ var id = this.id.replace("down_",""); /** Download the document */ window.location = "${pageContext.request.contextPath}/document/downLoad?id="+id; }) }) </script> <script type="text/javascript"> $(function(){ if(${count}!=0){ $("#count1").hide(); $("#count2").show(); } var username = "${sessionScope.user_session.loginname}"; if(username=="admin"||username=="manager"){ $("#aaa").show(); $("#bbb").show(); $("#do").css("display", "block"); $("#ID").css("display", "block"); $('tr').find('td:eq(0)').show(); $('tr').find('td:eq(8)').show(); }else{ $("#aaa").hide(); $("#bbb").hide(); $("#do").css("display", "none"); $("#ID").css("display", "none"); $('tr').find('td:eq(8)').hide(); }; }) </script> </head> <body> <div class="x-nav"> <span class="layui-breadcrumb"> <a href="">home page</a> <a> <cite>document information</cite></a> </span> <button id="aaa" type="button" οnclick="location.href='${pageContext.request.contextPath}/document/toadd'" class="layui-btn layui-btn-small" style="line-height:1.6em;margin-top:3px;float:innert;margin-left:75%;;" lay-submit="" lay-filter="sreach"><i class="layui-icon"></i>increase</button> <a id="bbb" class="layui-btn layui-btn-small" style="line-height:1.6em;margin-top:3px;float:right" href="${pageContext.request.contextPath}/document/list" title="Refresh"> <i class="layui-icon" style="line-height:30px">ဂ</i></a> </div> <div class="x-body"> <div class="layui-row" style="" align="center"> <form class="layui-form layui-col-md12 x-so" method="get" action="${pageContext.request.contextPath}/document/list"> <input type="text" name="content" style="width:50%;" placeholder="Please enter your search" autocomplete="off" class="layui-input"> <button class="layui-btn" lay-submit="" lay-filter="sreach"><i class="layui-icon"></i></button> </form> </div> <table class="layui-table"> <thead> <tr> <th> <div class="layui-unselect header layui-form-checkbox" lay-skin="primary"><i class="layui-icon"></i></div> </th> <th>ID</th> <th>Title</th> <th>describe</th> <th>file name</th> <th>Release date</th> <th>Publishing Users</th> <th>download</th> <th id="do">operation</th> </thead> <tbody> <c:forEach items="${requestScope.list}" var="document" varStatus="stat"> <tr> <td> <div class="layui-unselect layui-form-checkbox" lay-skin="primary" data-id='2'><i class="layui-icon"></i></div> </td> <td>${document.id}</td> <td>${document.title }</td> <td>${document.remark }</td> <td>${document.filename }</td> <td>${document.createdate}</td> <td>${document.user.username }</td> <td align="center" width="40px;"><a href="#" id="down_${document.id }"> <img width="20" height="20" title="download" src="${pageContext.request.contextPath}/public/images/downLoad.png"/></a> </td> <td class="td-manage"> <a title="edit" href='${pageContext.request.contextPath}/document/toedit?id=${document.id}'> <i class="layui-icon"></i> </a> <a title="delete" οnclick="member_del(this,'${document.id }')" href="javascript:;"> <i class="layui-icon"></i> </a> </td> </tr> </c:forEach> </tbody> </table> <!-- Paging Label --> <div style="margin-left: 400px;" id="count1"> <fkjava:pager pageIndex="${requestScope.pageModel.pageIndex}" pageSize="${requestScope.pageModel.pageSize}" recordCount="${requestScope.pageModel.recordCount}" style="digg" submitUrl="${pageContext.request.contextPath}/document/list?pageIndex={0}"/> </div> <div style="margin-left: 500px; display: none;" id="count2"> <p style="color: rgb(0,97,222)">Total queries to<font color="red">${count}</font>Bar data</p> </div> </div> <script> /*User-Delete*/ function member_del(obj,id){ layer.confirm('Are you sure you want to delete it?',function(index){ //Send Asynchronous Delete Data //Wait until you use asynchronous, use it here first $.get("${pageContext.request.contextPath}/document/delete?id="+id); $(obj).parents("tr").remove(); layer.msg('Deleted!',{icon:1,time:1000}); location.reload(); }); } function delAll (argument) { var data = tableCheck.getData(); layer.confirm('Are you sure you want to delete it?'+data,function(index){ //Catch all selected and delete asynchronously layer.msg('Delete succeeded', {icon: 1}); $(".layui-form-checked").not('.header').parents('tr').remove(); }); } </script> </body> </html>
4.2 controller Layer Writing
package com.hrf.controller; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.hrf.bean.Document; import com.hrf.service.DocumentService; import com.hrf.util.PageModel; import com.hrf.util.UTF8String; import org.springframework.beans.factory.annotation.Autowired; 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.multipart.MultipartFile; import javax.jws.WebParam; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.*; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.UUID; @Controller @RequestMapping("/document") public class DocumentController { @Autowired private DocumentService documentService; @RequestMapping("/list") public String list(@RequestParam(name = "pageIndex",defaultValue = "1") Integer pageIndex, @RequestParam(name = "content",defaultValue = "") String content, PageModel pageModel, Model model){ PageHelper.startPage(pageIndex,5); List<Document> documentList = documentService.findDocumentList(content); // This is a paging class PageInfo pageInfo = new PageInfo(documentList); List list = pageInfo.getList(); pageModel.setPageIndex(pageIndex); pageModel.setRecordCount((int) pageInfo.getTotal()); model.addAttribute("list",list); model.addAttribute("pageModel",pageModel); return "/jsp/document/list.jsp"; } }
4.3 Service Layer Interfaces and Implementation Classes
4.3.1 Interface
package com.hrf.service; import com.hrf.bean.Document; import org.springframework.stereotype.Component; import java.util.List; @Component public interface DocumentService { List<Document> findDocumentList(String content); }
4.3.2 Implementation Class
package com.hrf.service; import com.hrf.bean.Document; import com.hrf.mapper.DocumentMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class DocumentServiceImpl implements DocumentService{ @Autowired private DocumentMapper documentMapper; @Override public List<Document> findDocumentList(String content) { return documentMapper.selectAll(content); } }
4.4 mapper interface and sql statement
4.4.1 mapper interface
package com.hrf.mapper; import com.hrf.bean.Document; import org.springframework.stereotype.Component; import java.util.List; @Component public interface DocumentMapper { int deleteByPrimaryKey(Integer id); }
Implementation of 4.4.2 SQL statement
<resultMap id="BaseResultMap" type="com.hrf.bean.Document"> <id column="id" jdbcType="INTEGER" property="id" /> <result column="title" jdbcType="VARCHAR" property="title" /> <result column="filename" jdbcType="VARCHAR" property="filename" /> <result column="remark" jdbcType="VARCHAR" property="remark" /> <result column="createdate" jdbcType="TIMESTAMP" property="createdate" /> <result column="user_id" jdbcType="INTEGER" property="userId" /> <association property="user" javaType="User" autoMapping="true"/> </resultMap> <select id="selectAll" resultMap="BaseResultMap"> select d.id, title, filename, remark, d.createdate, d.user_id,u.username from document_inf d left join user_inf u on d.user_id=u.id <where> <if test="content!=null"> title like '%' #{content} '%' </if> </where> </select>
4.5 Implementation Class
package com.hrf.bean; import java.util.Date; public class Document { private Integer id; private String title; private String filename; private String remark; private Date createdate; private Integer userId; //Relationships One-to-One private User user; //You can also pass in attributes, but it's best to pass in attributes //private String username; public User getUser() { return user; } public void setUser(User user) { this.user = user; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title == null ? null : title.trim(); } public String getFilename() { return filename; } public void setFilename(String filename) { this.filename = filename == null ? null : filename.trim(); } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark == null ? null : remark.trim(); } public Date getCreatedate() { return createdate; } public void setCreatedate(Date createdate) { this.createdate = createdate; } public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } }
5. Paging without custom tags
5.1 controller layer
@RequestMapping("/list") public String list(@RequestParam(name = "page",defaultValue = "1") Integer page, @RequestParam(name = "size",defaultValue = "5") Integer size, @RequestParam(name = "content",defaultValue = "") String content, HttpServletRequest request){ List<Employee> employeeList = employeeService.findEmployeeAll(page,size,content); PageInfo pageInfos = new PageInfo(employeeList); request.setAttribute("pageInfos",pageInfos); return "/jsp/employee/list.jsp"; }
5.2 service layer implementation class
@Override public List<Employee> findEmployeeAll(@Param("page") Integer page, @Param("size") Integer size, @Param("content") String content) { PageHelper.startPage(page,size); return employeeMapper.selectAll2(content); }
sql statement inside 5.3 mapper
<select id="selectAll2" resultMap="BaseResultMap"> select e.id, e.dept_id, e.job_id, e.name ename, e.card_id, e.address, e.phone, e.sex_id, e.education_id, e.createdate, e.user_id, u.id uid, u.username , u.email,j.name jname, d.name dname, ed.name edname ,s.name sexname from employee_inf e left join user_inf u on e.user_id=u.id left join job_inf j on e.job_id=j.id left join dept_inf d on e.dept_id=d.id left join education_inf ed on e.education_id=ed.id LEFT JOIN sex_inf s ON e.sex_id = s.id <where> <if test="content!=null"> or e.name like '%' #{content} '%' </if> <if test="content!=null"> or e.address like '%' #{content} '%' </if> <if test="content!=null"> or u.username like '%' #{content} '%' </if> <if test="content!=null"> or j.name like '%' #{content} '%' </if> <if test="content!=null"> or d.name like '%' #{content} '%' </if> <if test="content!=null"> or ed.name like '%' #{content} '%' </if> </where> </select> <resultMap id="BaseResultMap" type="com.hrf.bean.Employee"> <id column="id" jdbcType="INTEGER" property="id" /> <result column="dept_id" jdbcType="INTEGER" property="deptId" /> <result column="job_id" jdbcType="INTEGER" property="jobId" /> <result column="ename" jdbcType="VARCHAR" property="name" /> <result column="card_id" jdbcType="VARCHAR" property="cardId" /> <result column="address" jdbcType="VARCHAR" property="address" /> <result column="phone" jdbcType="VARCHAR" property="phone" /> <result column="sex_id" jdbcType="INTEGER" property="sexId" /> <result column="education_id" jdbcType="INTEGER" property="educationId" /> <result column="createdate" jdbcType="TIMESTAMP" property="createdate" /> <result column="user_id" jdbcType="INTEGER" property="userId" /> <association property="user" javaType="User" autoMapping="true"> </association> <association property="job" javaType="Job" autoMapping="true"> <result property="name" column="jname"/> </association> <association property="dept" javaType="Dept" autoMapping="true"> <result property="name" column="dname"/> </association> <association property="education" javaType="Education" autoMapping="true"> <result property="name" column="edname"/> </association> <association property="sex" javaType="Sex" autoMapping="true"> <result property="name" column="sname"/> </association> </resultMap>
5.4 Front End Implementation
5.4.1 JSP code
<link rel="stylesheet" href="${pageContext.request.contextPath}/public/css/myPage.css">
<c:forEach items="${requestScope.pageInfos.list}" var="employee" varStatus="stat"> <tr> <td> <div class="layui-unselect layui-form-checkbox" lay-skin="primary" data-id='2'><i class="layui-icon"></i></div> </td> <td>${employee.name }</td> <td>${employee.user.username}</td> <!--Easy to know who is associated with whom --> <td> <c:choose> <c:when test="${employee.sexId==1}">male</c:when> <c:otherwise><font>female</font></c:otherwise> </c:choose> </td> <td>${employee.phone }</td> <td>${employee.user.email }</td> <td>${employee.job.name }</td> <td>${employee.dept.name }</td> <td>${employee.education.name }</td> <td>${employee.cardId }</td> <td>${employee.address }</td> <td>${employee.createdate}</td> <td class="td-manage"> <a title="edit" href='${pageContext.request.contextPath}/employee/toedit?id=${employee.id}'> <i class="layui-icon"></i> </a> <a title="delete" οnclick="member_del(this,'${employee.id}')" href="javascript:;"> <i class="layui-icon"></i> </a> </td> </tr> </c:forEach> </tbody> </table> <!-- Paging Label --> <div style="margin-left: 400px;" id="count1"> <ul class="pagination modal-1"> <li><a href="${pageContext.request.contextPath}/employee/list?page=1&size=5" class="pre">home page</a></li> <c:if test="${pageInfos.pageNum==1}"> <li><a href="${pageContext.request.contextPath}/employee/list?page=1&size=5" class="prev">Previous page</a></li> </c:if> <c:if test="${pageInfos.pageNum!=1}"> <li><a href="${pageContext.request.contextPath}/employee/list?page=${pageInfos.pageNum-1}&size=5" class="prev">Previous page</a></li> </c:if> <c:forEach begin="1" end="${pageInfos.pages}" var="pageNumber"> <li><a href="${pageContext.request.contextPath}/employee/list?page=${pageNumber}&size=5" class="active">${pageNumber}</a></li> </c:forEach> <c:if test="${pageInfos.pageNum!=pageInfos.pages}"> <li><a href="${pageContext.request.contextPath}/employee/list?page=${pageInfos.pageNum+1}&size=5" class="next">next page</a></li> </c:if> <c:if test="${pageInfos.pageNum==pageInfos.pages}"> <li><a href="${pageContext.request.contextPath}/employee/list?page=${pageInfos.pages}&size=5" class="next">next page</a></li> </c:if> <li><a href="${pageContext.request.contextPath}/employee/list?page=${pageInfos.pages}&size=5" class="next">End Page</a></li> </ul> </div>
Style him with 5.4.2 css code
.pagination { list-style: none; display: inline-block; padding: 0; margin-top: 10px; } .pagination li { display: inline; text-align: center; } .pagination a { float: left; display: block; font-size: 14px; text-decoration: none; padding: 5px 12px; color: #fff; margin-left: -1px; border: 1px solid transparent; line-height: 1.5; } .pagination a.active { cursor: default; } .pagination a:active { outline: none; } .modal-1 li:first-child a { -moz-border-radius: 6px 0 0 6px; -webkit-border-radius: 6px; border-radius: 6px 0 0 6px; } .modal-1 li:last-child a { -moz-border-radius: 0 6px 6px 0; -webkit-border-radius: 0; border-radius: 0 6px 6px 0; } .modal-1 a { border-color: #ddd; color: #4285F4; background: #fff; } .modal-1 a:hover { background: #eee; } .modal-1 a.active, .modal-1 a:active { border-color: #4285F4; background: #4285F4; color: #fff; }
5.6 Result style for last page break
6. Uploading and downloading files
6.1 File Upload
The implementation of 6.1.1 front-end pages must have three points
(1): Uploaded files are uploaded to the server and saved to the database are file names
(2): The uploaded file is uploaded as a file converted to a binary stream
(3): enctype="multipart/form-data" needs to be set inside the form, otherwise the file cannot be submitted
</head> <body> <div class="x-body"> <form class="layui-form" method="POST" id="deptForm" enctype="multipart/form-data" action="${pageContext.request.contextPath}/document/add"> <input type="hidden" name="id" id="id" value="${document.id }" > <input type="hidden" name="userId" id="user_id" value="${sessionScope.user_session.id}" > <div class="layui-form-item"> <label for="username" class="layui-form-label"> <span class="x-red">*</span>Title </label> <div class="layui-input-inline"> <input type="text" id="title" name="title" required="" lay-verify="required" placeholder="No less than 3 Chinese characters" autocomplete="off" class="layui-input" value="${document.title }"> </div> </div> <div class="layui-form-item"> <label for="username" class="layui-form-label"> <span class="x-red">*</span>describe </label> <div class="layui-input-inline"> <input type="text" id="remark" name="remark" required="" lay-verify="required" placeholder="No less than 5 Chinese characters" autocomplete="off" class="layui-input" value="${document.remark }"> </div> </div> <div class="layui-form-item"> <label for="username" class="layui-form-label"> <span class="x-red">*</span>Upload Files </label> <div class="layui-input-inline"> <input type="file" id="file" name="file" > <p class="x-red">You must choose to upload a file</p> <p class="x-red">${param.message}</p> </div> </div> <div class="layui-form-item"> <label for="L_repass" class="layui-form-label"> </label> <input type="submit" value=" Submit" class="layui-btn" lay-filter="add" lay-submit=""/> </div> </form> </div> </body> </html>
6.1.2 controller Layer Method Implementation
Perform new operations,File Upload @RequestMapping("/add") public String add(Document document, @RequestParam("file") MultipartFile multipartFile, HttpServletRequest request) throws ParseException, IOException { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//Set date format document.setCreatedate(df.parse(df.format(new Date()))); // Upload Document // Get absolute path to file upload to specific folder String realpath = request.getSession().getServletContext().getRealPath("/upload/"); // Get the uploaded file name String fileName = multipartFile.getOriginalFilename(); //To ensure the rename of the uploaded file, process the file name fileName = UUID.randomUUID().toString() +"_"+ fileName; // Building file objects from paths // Attention must be paid to the path problem during the construction process File uploadFile = new File(realpath, fileName); // Determines whether the specified folder uploadfiles exist and creates them if they do not exist if (!uploadFile.exists()) { uploadFile.mkdirs(); } // Upload Files multipartFile.transferTo(uploadFile); document.setFilename(fileName); documentService.addDocument(document); return "redirect:/document/list"; }
6.2 File Download
// File Download @RequestMapping("/downLoad") public String downLoad(HttpServletRequest request, HttpServletResponse response, Integer id) throws IOException { // Get File Name Document document = documentService.findDocumentById(id); String filename = document.getFilename(); // Get the downloaded file path String realpath = request.getSession().getServletContext().getRealPath("/WEB-INF/files/"); // Set the response header when downloading files response.setHeader("Content-Type", "application/x-msdownload"); response.setHeader("Content-Disposition", "attachment;filename=" + UTF8String.toUTF8String(filename)); // Get File Input Stream FileInputStream in = new FileInputStream(new File(realpath, filename)); // Gets the output stream of the response object used to output binary data to the client ServletOutputStream out = response.getOutputStream(); out.flush(); int aRead = 0; byte[] b = new byte[1024]; // Write to Response Output Stream while ((aRead = in.read(b)) != -1 && in != null) { out.write(b, 0, aRead); } out.flush(); // Close IO Object in.close(); out.close(); return "redirect:/document/list"; } /** * Character encoding conversion method for saving Chinese file names when downloading */ public String toUTF8String(String str) { StringBuffer sb = new StringBuffer(); int len = str.length(); for (int i = 0; i < len; i++) { // Remove each character from the string char c = str.charAt(i); // Do not process when Unicode value is 0-255 if (c >= 0 && c <= 255) { sb.append(c); } else { // Convert to utf-8 encoding byte[] b; try { b = Character.toString(c).getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { // TODO: handle exception e.printStackTrace(); b = null; } // Convert to string form of%HH for (int j = 0; j < b.length; j++) { int k = b[j]; if (k < 0) { k &= 255; } sb.append("%" + Integer.toHexString(k).toUpperCase()); } } } return sb.toString(); }
7. Add people in bulk (take employees for example)
7.1 Batch Tool Class
package com.hrf.util; import com.hrf.bean.Employee; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.FileInputStream; import java.util.ArrayList; import java.util.List; public class ExcelData { private XSSFSheet sheet; /** * Constructor to initialize excel data * @param filePath excel Route * @param sheetName sheet Table Name */ public ExcelData(String filePath, String sheetName){ FileInputStream fileInputStream = null; try { fileInputStream = new FileInputStream(filePath); XSSFWorkbook sheets = new XSSFWorkbook(fileInputStream); //Get sheet sheet = sheets.getSheet(sheetName); } catch (Exception e) { e.printStackTrace(); } } /** * Getting cell data based on row and column indexes * @param row * @param column * @return */ public String getExcelDateByIndex(int row,int column){ XSSFRow row1 = sheet.getRow(row); String cell = row1.getCell(column).toString(); return cell; } /** * Gets the value of column x of a row based on the row whose column value is'****' * @param caseName * @param currentColumn Index of the current cell column * @param targetColumn Index of target cell column * @return */ public String getCellByCaseName(String caseName,int currentColumn,int targetColumn){ String operateSteps=""; //Get Number of Rows int rows = sheet.getPhysicalNumberOfRows(); for(int i=0;i<rows;i++){ XSSFRow row = sheet.getRow(i); String cell = row.getCell(currentColumn).toString(); if(cell.equals(caseName)){ operateSteps = row.getCell(targetColumn).toString(); break; } } return operateSteps; } //Print excel data public void readExcelData(){ //Get Number of Rows int rows = sheet.getPhysicalNumberOfRows(); for(int i=0;i<rows;i++){ //Get the number of columns XSSFRow row = sheet.getRow(i); int columns = row.getPhysicalNumberOfCells(); for(int j=0;j<columns;j++){ String cell = row.getCell(j).toString(); System.out.println(cell); } } } //Get Length public int len(String file){ ExcelData sheet1 = new ExcelData(file, "Sheet1"); int i=0; while (true){ try { String c=sheet1.getExcelDateByIndex(i,0); i++; }catch (NullPointerException e){ break; } } return i; } //test method public static void main(String[] args){ } //read object public List<Employee> employeeList(String file){ ExcelData excelData=new ExcelData(file,"Sheet1"); int i=excelData.len(file); //System.out.println(i); List<Employee> list=new ArrayList<>(); for(int j=1;j<i;j++){ String id=excelData.getExcelDateByIndex(j,0); String dept_id=excelData.getExcelDateByIndex(j,1); String job_id=excelData.getExcelDateByIndex(j,2); String name=excelData.getExcelDateByIndex(j,3); String card_id=excelData.getExcelDateByIndex(j,4); String address=excelData.getExcelDateByIndex(j,5); String phone=excelData.getExcelDateByIndex(j,6); String sex_id=excelData.getExcelDateByIndex(j,7); String education_id=excelData.getExcelDateByIndex(j,8); Employee employee=new Employee(); employee.setId(Integer.parseInt(id)); employee.setDeptId(Integer.parseInt(dept_id)); employee.setJobId(Integer.parseInt(job_id)); employee.setName(name); employee.setCardId(card_id); employee.setAddress(address); employee.setPhone(phone); employee.setSexId(Integer.parseInt(sex_id)); employee.setEducationId(Integer.parseInt(education_id)); list.add(employee); } return list; } }
7.2 controller Layer Method
// Join in in batch @RequestMapping("/piliang") public String piliang(@RequestParam("file") MultipartFile file, HttpServletRequest req, Model model) throws IOException { // Designed to upload and download files String fileName= file.getName(); String uploadPath= WebUtils.getRealPath(req.getSession().getServletContext(),"/upload/"); String path= uploadPath+ new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + fileName; file.transferTo(new File(path)); ExcelData excelData=new ExcelData(path,"sheet1"); List<Employee> list=excelData.employeeList(path); int i=employeeService.pladd(list); if (i!=0){ model.addAttribute("message","ok"); }else { model.addAttribute("message","error"); } return "redirect:/employee/list"; }
8 Data visualization
8.1 Data Visualization Tool Class
package com.hrf.util; public class ChartsVo { private String name; private Integer value; private Integer mailmarketing; private Integer allianceadvertising; private Integer videoadvertising; private Integer directaccess; private Integer searchengine; public Integer getMailmarketing() { return mailmarketing; } public void setMailmarketing(Integer mailmarketing) { this.mailmarketing = mailmarketing; } public Integer getAllianceadvertising() { return allianceadvertising; } public void setAllianceadvertising(Integer allianceadvertising) { this.allianceadvertising = allianceadvertising; } public Integer getVideoadvertising() { return videoadvertising; } public void setVideoadvertising(Integer videoadvertising) { this.videoadvertising = videoadvertising; } public Integer getDirectaccess() { return directaccess; } public void setDirectaccess(Integer directaccess) { this.directaccess = directaccess; } public Integer getSearchengine() { return searchengine; } public void setSearchengine(Integer searchengine) { this.searchengine = searchengine; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getValue() { return value; } public void setValue(Integer value) { this.value = value; } public ChartsVo() { } public ChartsVo(String name, Integer value) { this.name = name; this.value = value; } }
Methods in the 8.2 controller layer
package com.hrf.controller; import com.hrf.service.EmployeeService; import com.hrf.util.ChartsVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import java.util.List; @Controller public class StatisticsController { @Autowired private EmployeeService employeeService; // Visualize data @RequestMapping("/statistics") public String statistics(){ return "/jsp/statistics/statistics.jsp"; } //Get the percentage of men to women @RequestMapping("/echartsData") @ResponseBody public List<ChartsVo> echartsData() { List<ChartsVo> list= employeeService.getSexCount(); return list; } //Get the number of employees for each position @RequestMapping("/echartsData1") @ResponseBody public List<ChartsVo> echartsData1() { List<ChartsVo> list= employeeService.getJobCount(); return list; } //Get the number of business types processed in a week @RequestMapping("/echartsData2") @ResponseBody public List<ChartsVo> echartsData2() { List<ChartsVo> list= employeeService.getBusinessCount(); return list; } //Get the number of residence addresses for each employee @RequestMapping("/echartsData3") @ResponseBody public List<ChartsVo> echartsData3() { List<ChartsVo> list= employeeService.getAddressCount(); return list; } }
8.3 service layer implements methods in classes
//Get the percentage of men to women @Override public List<ChartsVo> getSexCount() { List<ChartsVo> list = new ArrayList<>(); int male = employeeMapper.selectByMale(); ChartsVo maleChartsVo = new ChartsVo("Male",male); list.add(maleChartsVo); int female = employeeMapper.selectByFemale(); ChartsVo femaleChartsVo = new ChartsVo("Female sex",female); list.add(femaleChartsVo); return list; } //Get the number of employees for each position @Override public List<ChartsVo> getJobCount() { return employeeMapper.getJobCount(); } //Get the number of business types processed in a week @Override public List<ChartsVo> getBusinessCount() { return employeeMapper.getBusinessCount(); } //Get the number of residence addresses for each employee @Override public List<ChartsVo> getAddressCount() { return employeeMapper.getAddressCount(); }
sql statement inside 8.4 mapper
<!-- Query the number of employees with male gender--> <select id="selectByMale" resultType="int"> select count(*) from employee_inf e ,sex_inf s where e.sex_id=s.id and s.name= 'male' </select> <!-- Query the number of employees whose gender is female--> <select id="selectByFemale" resultType="int"> select count(*) from employee_inf e ,sex_inf s where e.sex_id=s.id and s.name= 'female' </select> <!-- Query the number of employees in each position--> <select id="getJobCount" resultType="com.hrf.util.ChartsVo"> select count(e.job_id) value,j.name from employee_inf e join job_inf j on e.job_id=j.id group by e.job_id </select> <!-- Get the number of business types processed in a week--> <select id="getBusinessCount" resultType="com.hrf.util.ChartsVo"> select * from business_inf </select> <!-- Get the number of residence addresses for each employee--> <select id="getAddressCount" resultType="com.hrf.util.ChartsVo"> select count(*) value ,address name from employee_inf group by address </select>