การเรียนรู้ฤดูใบไม้ผลิในทางปฏิบัติเป้าหมายสูงสุดของซีรี่ส์นี้คือการทำโครงการที่ใช้การลงทะเบียนผู้ใช้และฟังก์ชั่นการเข้าสู่ระบบ
กระบวนการพื้นฐานที่คาดหวังมีดังนี้:
1. ลงทะเบียนเว็บไซต์ผู้ใช้กรอกข้อมูลชื่อผู้ใช้รหัสผ่านอีเมลและหมายเลขโทรศัพท์มือถือและส่งคืนตกลงหลังจากฝากไว้ในฐานข้อมูลในพื้นหลัง (เรียนรู้ความรู้พื้นฐานของ IOC, MyBatis, SpringMVC, การตรวจสอบข้อมูลแบบฟอร์ม, การอัปโหลดไฟล์ ฯลฯ )
2. เซิร์ฟเวอร์ส่งอีเมลแบบอะซิงโครนัสไปยังผู้ใช้ที่ลงทะเบียน (เรียนรู้คิวข้อความ)
3. เข้าสู่ระบบผู้ใช้ (การเรียนรู้แคชความปลอดภัยของฤดูใบไม้ผลิ)
4. อื่น ๆ
ศึกษาและสรุปและอัปเดตเป็นครั้งคราว สภาพแวดล้อมของโครงการคือ Intellij + Spring4
1. การเตรียมงาน
1. สร้างฐานข้อมูลและตารางใน MySQL
2. สร้างโครงการ Maven Webapp ใน Intellij
(1) นำเข้าแพ็คเกจการพึ่งพาที่ต้องการใน pom.xml
<? xml version = "1.0" encoding = "utf-8"?> <project xmlns = "http://maven.apache.org/pom/4.0.0" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" http://maven.apache.org/xsd/maven-4.0.0.xsd "> <moderVervesion> 4.0.0 </modelversion> <roupId> com.everseeker < /groupid><Artifactid> register</artifactid><packaging> war</packaging><version>1.0</version> <name> register Maven Webapp </name> <url> http://maven.apache.org </url> <properties> <pring.version> 4.3.1.release </spring.version> </premerties> บริบท-> <cendency> <roupId> org.springframework </GroupId> <ratifactId> Spring-Contex CTID> Spring-Context-Support </artifactid> <sersion> $ {spring.version} </เวอร์ชัน> </การพึ่งพา> <การพึ่งพาอาศัย> <roupid> org.springframework </groupid> rsion> </derctency> <การพึ่งพา> <roupId> org.springframework </groupId> <ratifactid> Spring-Beans </artifactid> <version> $ {Spring.version} </เวอร์ชัน> </การพึ่งพา> <! tifactid> junit </artifactid> <cersion> 4.12 </version> <!-<Pope> ทดสอบ </pope>-> </การพึ่งพา> <การพึ่งพาอาศัย> <roupId> org.springframework </groupid> rsion> </derctency> <!-SpringMvc-> <การพึ่งพา> <roupId> org.springframework </groupId> <ArtIfactId> Spring-Webmvc </artifactid> <SPRONTION> $ {Spring.Version} </เวอร์ชัน> Amework </groupId> <ratifactId> Spring-Web </ArtifactId> <sersion> $ {Spring.Version} </Service> </การพึ่งพา> <การพึ่งพา> <roupId> Javax.validation </roupId> Al </เวอร์ชัน> </การพึ่งพา> <การพึ่งพา> <roupId> org.hibernate </groupId> <ratifactId> hibernate-validator </artifactid> <erson> 5.2.4.final </เวอร์ชัน> </การพึ่งพา> <! /groupid> <Artifactid> Javax.servlet-api</artifactid><version>3.1.0</version></dependency> <dependency><groupid> javax.servlet</groupid> MyBatis-> <การพึ่งพา> <roupId> org.springframework </groupId> <ratifactId> Spring-Jdbc </artifactid> <spring.version} </SidefACTIC/ARTIFACTICTIC <ARTIFACTIC ID> <persion> 6.0.3 </Serve> </การพึ่งพา> <การพึ่งพา> <roupId> org.mybatis </groupId> <ratifactid> mybatis </artifactid> <version> 3.4.1 </Side IFACTID> <Sersion> 1.3.0 </เวอร์ชัน> </การพึ่งพา> <การพึ่งพา> <roupId> C3P0 </groupID> <ArtIfactId> C3P0 </artifactId> <Sersion> 0.9.1.2 </Side> </การพึ่งพา> <การพึ่งพา n> <roupId> org.apache.maven.plugins </groupId> <ratifactid> maven-war-plugin </artifactid> <sersion> 2.2 </version> <การกำหนดค่า> <FailOnMissingWebxMl> FALSE </failonMissingWebxml> (2) โครงสร้างไดเรกทอรีโครงการมีดังนี้:
2. mybatis
1. กำหนดค่าข้อมูลพื้นฐานของฐานข้อมูล MySQL
# databasedb.mysql.driverclass = com.mysql.jdbc.driverdb.mysql.jdbcurl = jdbc: mysql: // localhost: 3306/register_notice? 333DB.MinPoolSize = 10dB.MaxPoolsize = 100dB.initialPoolSize = 20dB.MaxidLetime = 60dB.AcquireIncrement = 5dB.MaxStatements = 100dB.IDLECONNECTIONTESTESTES truedb.testConnectionOnCheckout = falsedB.properties
2. กำหนดค่า mybatis.xml และ Spring-mybatis.xml
<? XML เวอร์ชัน = "1.0" การเข้ารหัส = "UTF-8"?> <! doctype configurationPublic "-// mybatis.org//dtd config 3.0 // en" "http://mybatis.org/dtd/mybatis-3-config.dtdig.dtdiG นามแฝง-> <typealiases> <!-เลือกหนึ่งในสองวิธีต่อไปนี้ วิธีที่ 1: ใช้ typealias เพื่อตั้งค่านามแฝงสำหรับคลาสเดียว -> <!-<typealias type = "com.everseeker.entity.user" alias = "ผู้ใช้" /> --- วิธีที่ 2: ใช้แพ็คเกจเพื่อตั้งค่านามแฝงสำหรับคลาสทั้งหมดด้านล่างแพ็คเกจ กฎเริ่มต้นคือ com.everseeker.entity.user ถูกตั้งค่าเป็นผู้ใช้และลบชื่อแพ็คเกจก่อนหน้า -> <package name = "com.everseeker.entity" /></typealiases></configuration>mybatis.xml<?xml เวอร์ชัน = "1.0" การเข้ารหัส = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" /schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:p="http://www.springframework.org/schema/p"งอม ringframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.spring framework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/tx/spring-tx.xsd"><! การแนะนำไฟล์ db.properties ลงในไฟล์นี้สามารถตรวจสอบได้ว่าค่าที่สอดคล้องกันสามารถพบได้ในการกำหนดค่าที่ตามมาเช่น $ {db.mysql.driverclass}-มิฉะนั้นถ้าเพื่อนร่วมงานโหลด db.properties และ sproperties ข้อผิดพลาด-> <บริบท: สถานที่ตั้งสถานที่ตั้งตำแหน่ง = "classpath: db.properties"/> <!-การกำหนดค่าแหล่งข้อมูล C3P0 มีแพ็คเกจการใช้งานแหล่งข้อมูลทั่วไป 2 แพคเกจหนึ่งคือ Apache DBCP (org.apache.Commons.dbcp.basicDataSource) และอื่น ๆ คือ C3P0 -> <bean id = "dataSource" destroy-method = "close"> <property name = "driverclass" value = "$ {db.mysql.driverclass}" /> <property name = "jdbcurl" value = "$ {db.mysql.jdbcurl}" /> <property name = "รหัสผ่าน" value = "$ {db.mysql.password}" /> <!-จำนวนการเชื่อมต่อขั้นต่ำที่เก็บไว้ในพูลการเชื่อมต่อ -> <property name = "minpoolsize" value = "$ {db.minpoolsize}" /> <!-จำนวนการเชื่อมต่อสูงสุดที่เก็บไว้ในพูลเชื่อมต่อ ค่าเริ่มต้น: 15-> <property name = "maxPoolSize" value = "$ {db.MaxPoolSize}" /> <!-จำนวนการเชื่อมต่อที่ได้รับระหว่างการเริ่มต้นควรอยู่ระหว่าง minpoolsize และ maxpoolsize ค่าเริ่มต้น: 3-> <property name = "InitialPoolSize" value = "$ {db.initialPoolSize}" /> <!-เวลาว่างสูงสุดหากไม่ได้ใช้ภายใน 60 วินาทีการเชื่อมต่อจะถูกยกเลิก ถ้าเป็น 0 มันจะไม่ถูกทิ้ง ค่าเริ่มต้น: 0-> <property name = "maxidLetime" value = "$ {db.maxidletime}" /> <!-จำนวนการเชื่อมต่อที่ได้รับจาก C3P0 ในเวลาเดียวกันเมื่อการเชื่อมต่อในพูลเชื่อมต่อหมดลง ค่าเริ่มต้น: 3-> <property name = "AcquireIncrement" value = "$ {db.acquireincrement}" /> <!-พารามิเตอร์มาตรฐานของ JDBC ใช้เพื่อควบคุมจำนวนของ preparedStatements ที่โหลดในแหล่งข้อมูล แต่เนื่องจากคำสั่ง Precache เป็นของการเชื่อมต่อเดียวมากกว่าพูลการเชื่อมต่อทั้งหมด ดังนั้นการตั้งค่าพารามิเตอร์นี้ต้องพิจารณาปัจจัยหลายอย่าง หากทั้ง maxstatements และ maxstatementsperconnection คือ 0 แคชจะถูกปิด ค่าเริ่มต้น: 0-> <property name = "MaxStatements" value = "$ {db.maxStatements}" /> <!-ตรวจสอบการเชื่อมต่อทั้งหมดในพูลการเชื่อมต่อทุก ๆ 60 วินาที ค่าเริ่มต้น: 0-> <property name = "IdleConnectionTestPeriod" value = "$ {db.idleConnectionTestPeriod}" /> <!-กำหนดจำนวนความพยายามซ้ำ ๆ หลังจากการเชื่อมต่อใหม่ล้มเหลวในการดึงข้อมูลจากฐานข้อมูล ค่าเริ่มต้น: 30-> <property name = "acquireretryAttempts" value = "$ {db.acquireretryAttempts}" /> <!-การรับการเชื่อมต่อจะทำให้เธรดทั้งหมดรอการเชื่อมต่อเพื่อรับการเชื่อมต่อเพื่อโยนข้อยกเว้น อย่างไรก็ตามแหล่งข้อมูลยังคงใช้ได้และพยายามเชื่อมต่อในครั้งต่อไปที่คุณเรียก getConnection () หากตั้งค่าเป็นจริงแหล่งข้อมูลจะประกาศว่ามันถูกตัดการเชื่อมต่อและปิดอย่างถาวรหลังจากความพยายามที่ล้มเหลวในการรับการเชื่อมต่อ ค่าเริ่มต้น: false-> <property name = "breakafteracquirefailure" value = "$ {db.breakafteracquirefailure}" /> <!-สำหรับการบริโภคประสิทธิภาพสูงโปรดใช้เมื่อจำเป็นเท่านั้น หากตั้งค่าเป็นจริงความถูกต้องของมันจะได้รับการตรวจสอบในการส่งการเชื่อมต่อแต่ละครั้ง ขอแนะนำให้ใช้ IdleConnectionTestPeriod หรือ AutomatictestTable เพื่อปรับปรุงประสิทธิภาพของการทดสอบการเชื่อมต่อ ค่าเริ่มต้น: false-> <property name = "TestConnectionOnCheckout" value = "$ {db.testConnectionOnCheckout}"/> </ebean> <!-ความแตกต่างระหว่างการกำหนดค่า mybatis.classpath และ classpath*, อ้างถึงเอกสาร: http://blog.csdn.net/zl34503450345034503450345034503450345034 ส่งคืนทรัพยากรการจับคู่แรกเท่านั้น ขอแนะนำให้ใช้ ClassPath สำหรับเอกสารเดียวที่กำหนดเส้นทาง ใช้ classpath*เมื่อจับคู่เอกสารหลายฉบับ-> <bean id = "sqlsessionfactory" p: dataSource-ref = "dataSource" p: configlocation = "classpath: mybatis.xml" p: mapperlocations = "classpath*: mapper /* จะถูกค้นหา สามารถระบุแพ็คเกจหลายแพ็คเกจ MappersCannerConfigurer จะสแกนคลาสอินเตอร์เฟสทั้งหมด (รวมถึงแพ็คเกจย่อย) ภายใต้แพ็คเกจที่ระบุโดย BasePackage หากพวกเขาได้รับการกำหนดในไฟล์การแมป SQL พวกเขาจะถูกกำหนดแบบไดนามิกเป็นถั่วสปริง -> <property name = "basepackage" value = "com.everseeker.dao" /> <property name = "SQLSessionFactoryBeanName" value = "SQLSessionFactory" /> </ebean> <! id = "transactionManager" class = "org.springframework.jdbc.datasource.datasourceTransactionManager"> <property name = "DataSource" ref = "DataSource" /> </ebean> <! โดยค่าเริ่มต้นตัวจัดการธุรกรรมชื่อ TransactionManager จะถูกใช้โดยอัตโนมัติ Proxy-target-class เป็นจริงแสดงให้เห็นว่าฤดูใบไม้ผลิจะเป็นคลาสธุรกิจพร็อกซีโดยการสร้างคลาสย่อยและจำเป็นต้องเพิ่ม CGLIB.JAR Class Library ให้กับ ClassPath -> <tx: transaction-driven transaction-manager = "TransactionManager" proxy-target-class = "true" /></beans>spring-mybatis.xml3. สร้างคลาสผู้ใช้และอินเทอร์เฟซ UserDao
ผู้ใช้ระดับสาธารณะ {@Size (min = 32, max = 32, message = "uuid ควรเป็นสตริง 32 บิต") id สตริงส่วนตัว; @size (min = 1, max = 32, message = "ความยาวบัญชีควรอยู่ระหว่าง 1-32-bit")@ementyment joverexty ไม่ถูกต้อง ") อีเมลสตริงส่วนตัว; @Size (min = 11, max = 11, message =" ความยาวของหมายเลขโทรศัพท์มือถือคือ 11 ตัวเลข ") โทรศัพท์มือถือส่วนตัว; โทรศัพท์มือถือ) {ชื่อนี้ (ชื่อผู้ใช้รหัสผ่านอีเมลโทรศัพท์มือถือวันที่ใหม่ (). getTime ());} ผู้ใช้สาธารณะ (ชื่อผู้ใช้สตริงรหัสผ่านสตริงอีเมลสตริงโทรศัพท์มือถือสตริง regdate ยาว) อีเมล; this.cellphone = โทรศัพท์มือถือ; this.regdate = regdate;} สตริงสาธารณะ getId () {return id;} โมฆะสาธารณะ setId (string id) {this.id = id;} สตริงสาธารณะ getUserName () {return username; SetPassword (รหัสผ่านสตริง) {this.password = รหัสผ่าน;} สตริงสาธารณะ getEmail () {return email;} โมฆะสาธารณะ setemail (อีเมลสตริง) {this.email = อีเมล;} สตริงสาธารณะ getCellphone () {คืนโทรศัพท์มือถือ setregDate (regdate ยาว) {this.regDate = regDate;}@verridepublic สตริง toString () {return "[user: id =" + id + ", ชื่อผู้ใช้ =" + ชื่อผู้ใช้ + ", รหัสผ่าน =" + รหัสผ่าน ", อีเมล =" + อีเมลความคิดเห็นเช่น @NotNull, @NotEmpty, @Size และ @Email ใน user.java ถูกละเว้นชั่วคราวและอธิบายในภายหลัง
@RepositoryPublic Interface UserDao {Void Adduser (ผู้ใช้ผู้ใช้); ผู้ใช้ getUserByUserName (ชื่อผู้ใช้สตริง);}4. สร้างไฟล์การแมป usermapper.xml ในไดเรกทอรี SRC/Main/Resources/Mapper เพื่อใช้วิธีการในอินเทอร์เฟซ UserDAO หมายเหตุ: *ไฟล์ mapper.xml จะต้องอยู่ในไดเรกทอรี SRC/Main/Resources และก่อนหน้านี้ถูกวางไว้ในไดเรกทอรี SRC/Main/Java/COM/EVERSEEKER/DAO ทำให้เกิดข้อผิดพลาดที่อธิบายไม่ได้
<? xml version = "1.0" การเข้ารหัส = "utf-8"?> <! doctype mapper สาธารณะ "-// mybatis.org//dtd mapper 3.0 // en" "http://mybatis.org/dtd/mybatis-3-mapper.dtd namespace = "com.everseeker.dao.userdao"> <resultmap id = "resultmapuser" type = "com.everseeker.entity.user"> </resultmap> <insert id = "adduser" ค่า regdate (adduser) #{username}, #{รหัสผ่าน}, #{email}, #{cellphone}, #{regdate}) </insert> <select id = "getUserByUserName" parameterType = "String" resultMap = "resultMapUser"> select * iii. IOC
1. สร้างคอนเทนเนอร์ IOC และใช้วิธีการอธิบายประกอบเพื่อ RootConfig.java
@configuration@componentscan (basepackages = {"com.everseeker"}, excludeFilters = {@componentscan.filter (type = filterType.custom, value = rootConfig.webpackage.class)})@importresource WebPackage ขยาย regexpatterntypefilter {public webpackage () {super (pattern.compile ("com //. everseeker //. web"));}}}} @Configuration: ระบุว่านี่เป็นคลาสการกำหนดค่า
@componentscan: เปิดใช้งานการสแกนส่วนประกอบ, basepackages: แพ็คเกจพื้นฐานที่ต้องสแกน ExcludeFilters: อย่าสแกนว่าตัวกรองตรงกับเงื่อนไขตัวกรองหรือไม่
@Importresource: แนะนำไฟล์ XML
@PropertySource: แนะนำไฟล์คุณสมบัติ
2. เนื่องจากโครงการ WebApp ถูกสร้างขึ้นและใช้ SpringMVC แล้ว DispatchERServlet จึงเป็นหลัก ในเวอร์ชันสปริงก่อนหน้านี้โดยทั่วไปจะถูกกำหนดค่าใน web.xml ในฤดูใบไม้ผลิ 4 สามารถนำไปใช้ในรหัส Java webappinitializer.java
Public Class WebAppinitializer ขยาย AbstractannotationConfigDispatcherservleTinitializer {// คลาสที่สืบทอด AbstractannotationConfigDispatcherservletInitializer จะกำหนดค่า dispatcherservlet และสปริงแอปพลิเคชัน @OverrideProtected };}/*** คลาส rootconfig ใช้เพื่อกำหนดค่าถั่วในบริบทแอปพลิเคชันที่สร้างขึ้นโดย contextloaderListener,*ตัวอย่างเช่น @repository, @Service และส่วนประกอบอื่น ๆ*/ @class overrideProtected <?> [] getRootConfigClasses () บริบทแอปพลิเคชันใช้ถั่วที่กำหนดไว้ในคลาสการกำหนดค่า WebConfig * ใช้ในการโหลดถั่วที่มีส่วนประกอบของเว็บเช่นคอนโทรลเลอร์ดูตัวแยกวิเคราะห์และการแมปโปรเซสเซอร์ @Controller @requestmapping ฯลฯ };}@overrideProtected void conticalegistration (servletregistration.dynamic registration) {// จำกัด ขนาดไฟล์ที่อัปโหลดไม่เกิน 2MB คำขอทั้งหมดไม่เกิน 4M และไฟล์ที่อัปโหลดทั้งหมด 4194304, 0));}}3. สร้าง webconfig.java
@configuration@enablewebmvc@componentscan ("com.everseeker.web") คลาสสาธารณะ WebConfig ขยาย WebMVCCONFigurerAdapter {// กำหนดค่า JSP View Parser @BeanPublic ViewResolver ViewResolver () InternalResourceViewResolver (); ResourceViewResolver.setPrefix ("/web-inf/views/"); ResourceViewResolver.setSuffix (". jsp"); ResourceViewResolver.setexposecontextBeanSattributes (จริง) @BeanPublic MultipartResolver MultipartResolver () พ่น IOException {ส่งคืนมาตรฐานใหม่ MultipArtresolver ();} // กำหนดค่าทรัพยากรแบบคงที่การประมวลผล @OverridePublic Void (defaultServlethandlerConfigure@Bean: การประกาศวิธีนี้สร้างอินสแตนซ์ของประเภทที่ต้องการและการลงทะเบียนเป็นถั่วในบริบทแอปพลิเคชันฤดูใบไม้ผลิ
ข้างต้นเป็นคำอธิบายโดยละเอียดของการเรียนรู้ฤดูใบไม้ผลิหมายเหตุ 1, IOC, แนะนำโดยบรรณาธิการคุณพยายามใช้คำอธิบายประกอบและรหัส Java ให้มากที่สุด ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉันและบรรณาธิการจะตอบกลับทุกคนในเวลา ขอบคุณมากสำหรับการสนับสนุนเว็บไซต์ Wulin.com!