Day66 Spring IOC(控制/反轉)

神一樣的我發表於2018-05-10

Spring學習內容

Spring IOC
Spring AOP
Spring TX

Spring框架介紹

Spring 簡介:
Spring可以稱為是框架的框架。
發明者:Rod Johnson
理論:不要重複的發明輪子。
Spring框架介紹:
jar包介紹:
這裡寫圖片描述

Spring IOC學習:

問題:
            處理一個使用者的請求程式碼,是基於責任鏈的機制進行編寫的。
            這樣造成物件與物件之間的耦合性過高,不易於程式碼的升級迭代。
        解決:
            使用Spring IOC
        概念:
            作用:統一對物件的建立進行管理
            特點:將物件與物件之間的依賴關係進行了解耦
            IOC:控制/反轉
            控制:
                由Spring容器物件建立物件的過程
            反轉:
                Spring容器物件將建立的物件返回給呼叫物件的過程
        DI:
            依賴注入
    學習:
        構造器方式
        工廠方式
        屬性注入方式
        Spring整合Mybatis
    使用:
        匯入jar包:
                 commons-logging-1.1.3.jar
spring-beans-4.1.6.RELEASE.jar
spring-context-4.1.6.RELEASE.jar
spring-core-4.1.6.RELEASE.jar
spring-expression-4.1.6.RELEASE.jar
        配置xml檔案
            在src下建立applicationcontext.xml檔案並配置
                載入Schema:
                    <beans xmlns="http://www.springframework.org/schema/beans"
    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.xsd">
                配置bean標籤:
                     <bean id="唯一標識" class="類的全限定路徑"></bean>
                    示例:
                     <bean id="stu" class="com.bjsxt.pojo.Student2"></bean>
            使用Spring容器物件獲取要使用的物件
                    建立Spring容器物件
                        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationcontext.xml");
                    獲取物件:
                        ac.getBean(String id)。id為要獲取的物件在配置檔案中的標籤ID值。
                    使用物件完成操作

springIOC建立物件的三種方式

SpringIOC建立物件的三種方式:
        第一種方式:構造器方式
            無參構造器:預設使用,建立一個空物件並返回。
            有參構造器:
                    宣告呼叫的有參構造器的引數的個數:
                        <constructor-arg type="int" value="6"></constructor-arg>
                        一個constructor-arg標籤,代表一個引數個數
                    使用屬性表明引數型別:
                        每一個引數宣告,必須要寫屬性表名引數的型別,角標,屬性名,實參值。示例:
                        <constructor-arg type="int" index="0" name="sid" value="6"></constructor-arg>
            注意:Spring預設使用無參構造器建立物件.
        第二種方式:工廠方式(工廠設計模式):
            作用:簡化物件的建立流程。
            靜態工廠:
                生產物件的方式是靜態方法,直接類名.方法名完成物件的生產。
            動態工廠:
                生產物件的方式是非靜態方法,工廠類例項化物件.方法完成物件的生產。
            Spring管理方式:
                靜態管理:
                    先有靜態工廠類
                    在applicationcontext.xml檔案中配置bean,使用靜態工廠物件。
                    <bean id="user2" class="靜態工廠類的全限定路徑" factory-method="生產物件的方法名"></bean>
                動態管理:
                    先有動態工廠類
                    在applicationcontext.xml檔案中配置bean,使用動態工廠物件。
                    <bean id="factory" class="動態工廠的全限定路徑"></bean>
                    <bean id="user" factory-bean="factory" factory-method="生產物件的方法名"></bean>
        第三種方式:屬性注入方式(DI)
            建立bean標籤,使用子標籤property配置類的屬性即可。
            示例:
            <bean id="s" class="com.bjsxt.pojo.Student">
                <!--基本型別屬性注入  -->
                    <property name="sid" value="9"></property>
                    <property name="sname" value="柳巖"></property>
                <!--引入資料型別  -->
                    <!-- 普通物件型別 -->
                    <property name="teacher" ref="tea"></property>
                    <!-- 陣列型別  -->
                    <property name="str">
                        <array>
                            <value>1</value>
                            <value>2</value>
                            <value>3</value>
                        </array>
                    </property>
                    <!--集合型別  -->
                        <property name="ls">
                            <list>
                                <value>a</value>
                                <value>b</value>
                            </list>
                        </property>
                        <property name="map">
                            <map>
                                <entry key="a" value="哈哈" ></entry>
                                <entry key="b" value="嘿嘿"></entry>
                            </map>
                        </property>
            </bean>
            <!--建立Teacher bean  -->
            <bean id="tea" class="com.bjsxt.pojo.Teacher">
                <property name="tid" value="3"></property>
                <property name="tname" value="大鵬"></property>
            </bean>

            原理:
                先建立一個空的例項化物件,然後反射呼叫set方法將屬性進行賦值。
            依賴注入(DI):
                將一個物件作為另外一個物件的屬性注入的過程稱為依賴注入。




spring整合Mybatis

Spring整合Mybatis:
    第一步:搭建框架環境
        匯入jar包:
            Spring核心包
                   commons-logging-1.1.3.jar
spring-beans-4.1.6.RELEASE.jar
spring-context-4.1.6.RELEASE.jar
spring-core-4.1.6.RELEASE.jar
spring-expression-4.1.6.RELEASE.jar
spring-tx-4.1.6.RELEASE.jar
spring-aop-4.1.6.RELEASE.jar
            Mybatis的所有jar包  --
            Spring+Mybatis的整合包        mybatis-spring-1.2.3
            Spring資料庫操作相關包  spring-jdbc-4.1.6.RELEASE
                       Mysql的驅動包

        建立並配置applicationcontext.xml:
            <!--Spring Mybatis的整合  -->
            <!--配置資料來源  -->
                <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                    <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
                    <property name="url" value="jdbc:mysql://localhost:3306/mybatis"></property>
                    <property name="username" value="root"></property>
                    <property name="password" value="1234"></property>
                </bean>
            <!--配置工廠物件  -->
                <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
                    <property name="dataSource" ref="dataSource"></property>
                </bean>
            <!--配置mapper掃描  -->
                <bean id="mapper" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
                    <property name="basePackage" value="com.bjsxt.mapper"></property>
                    <property name="sqlSessionFactory" ref="factory"></property>
                </bean>
            <!--相關bean  -->
                <!--配置業務層bean  -->
                <bean id="ss" class="com.bjsxt.serviceImpl.StudentServiceImpl">
                    <property name="sm" ref="studentMapper"></property>
                </bean>
    第二步:
        建立包
        com.bjsxt.mapper
        com.bjsxt.service
        com.bjsxt.serviceImpl:
            public class StudentServiceImpl implements StudentService{
    //宣告mapper介面物件
    private StudentMapper sm;

    public StudentMapper getSm() {
        return sm;
    }

    public void setSm(StudentMapper sm) {
        this.sm = sm;
    }

    @Override
    public List<Student> selStuService() {
        return sm.selStu();
    }

}
        com.bjsxt.servlet
            //獲取業務層物件
                    //獲取Spring容器物件
                    ApplicationContext ac=new ClassPathXmlApplicationContext("applicationcontext.xml");
                    //獲取業務層物件
                    StudentService ss=(StudentService) ac.getBean("ss");
        com.bjsxt.pojo
    第三步:
        在mapper包中建立mapper.xml並建立對應的介面
        完成程式碼編寫

DTD &Schema

mybatis:
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">

mapper:
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">


spring  :<beans xmlns="http://www.springframework.org/schema/beans"
    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.xsd">
           </beans>

其他知識點

容器:ApplicationContext
SpringIOC的作用:解耦
Spring IOC的應用:
    Spring整合Mybatis注意:
     1、mybatis.xml的東西被applicationContext.xml代替
     2、原來mybatis.xml 有用的jdbc和掃描包由 applicationContext.xml配置
     3、SqlSession物件的建立由applicationContext.xml配置工廠物件並建立
     4、所有在責任鏈上的物件的建立由applicationContext建立
     5、為了減少applicationContext物件的建立,和serviceImpl裡必須得到studentMapper,所以在建立serviceImpl的時候,在serviceImpl的屬性依賴注入studentMapper物件的建立,
                <!--配置業務層bean  -->
                <bean id="ss" class="com.bjsxt.serviceImpl.StudentServiceImpl">
                    <property name="sm" ref="studentMapper"></property>
                </bean>
          然後在serviceImpl裡建立,因為依賴注入必須得由get,set方法。
                            //宣告mapper介面層物件  
       private StudentMapper sm;
       public StudentMapper getSm() {
        return sm;
    }
    public void setSm(StudentMapper sm) {
        this.sm = sm;
    }
    //查詢所有學生的的資訊
    @Override
    public List<Student> getStuInfo() {
        return sm.sel();
    }

    配置資料來源
    配置工廠物件
    mapper包掃描  :掃描過後   介面的別名為原名,首字母小寫 比如 StudentMapper->studentMapper
    配置業務層bean
            <!--Spring Mybatis的整合  -->
            <!--配置資料來源  -->
                <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
                    <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
                    <property name="url" value="jdbc:mysql://localhost:3306/mybatis"></property>
                    <property name="username" value="root"></property>
                    <property name="password" value="1234"></property>
                </bean>
            <!--配置工廠物件  -->
                <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
                    <property name="dataSource" ref="dataSource"></property>
                </bean>
            <!--配置mapper掃描  -->
                <bean id="mapper" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
                    <property name="basePackage" value="com.bjsxt.mapper"></property>
                    <property name="sqlSessionFactory" ref="factory"></property>
                </bean>
            <!--相關bean  -->
                <!--配置業務層bean  -->
                <bean id="ss" class="com.bjsxt.serviceImpl.StudentServiceImpl">
                    <property name="sm" ref="studentMapper"></property>
                </bean>
資料來源配置引數所在包:spring-jdbc-4.1.6.RELEASE.jar->org.springframework.jdbc.datasource
引數:driverClassName  url   username  password
工廠物件所在包:mybatis-spring-1.2.3.jar->org.mybatis.spring->SqlSessionFactoryBean.class
引數: dataSource    ref="dataSource"
mapper包掃描:mybatis-spring-1.2.3.jar->org.mybatis.spring.mapper->MapperScannerConfigurer.class
引數:basePackage  : com.bjsxt.mapper  sqlSessionFactory        ref:factory
DTD和Schema的區別:
spring配置檔案是基於schema
2.3.1 schema副檔名.xsd
2.3.2 把schema理解成DTD的升級版.
2.3.2.1 比DTD具備更好的擴充套件性.
2.3.3 每次引入一個xsd檔案是一個namespace(xmlns)



Ioc—Inversion of Control,即“控制反轉”,不是什麼技術,而是一種設計思想。
:由Spring容器物件統一建立物件的過程稱為控制,將建立的物件返回給呼叫物件的過程稱為反轉,最大特點是解耦
依賴注入:是通過spring ICO 的屬性注入方式來建立物件,在建立物件的時候將另外一個物件使用ref注入進去的方式,  將一個物件注入另一個物件的屬性的方式。

使用Spring IOC 的情況:任務鏈上的物件建立,耦合性較高的。

不解耦:自己用Java程式碼new出來的。
解耦一部分:如果一個物件的建立依賴於其他物件的建立,用工廠模式建立,然後用spring Ioc 管理工廠
完全解耦:使用  Spring容器的 DI  依賴注入方式建立物件


Bean標籤:Spring裡面的bean就類似是定義的一個元件,而這個元件的作用就是實現某個功能的,
作用域:
解耦:借用第三方

ApplicationContext物件的建立問題


問題1:ApplicationContext物件建立次數問題
ApplicationContext物件在Servlet中如果這樣建立:
  //獲取spring容器物件
           ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
            //獲取業務層物件
           UserService us=(UserService) ac.getBean("ss");

那麼一個請求就會建立一次,造成了資源浪費,所以,我們利用servlet的init方法建立它,這樣不管多少請求來,就只建立一個。
       private UserService us;
  public void init() throws ServletException {
          //獲取spring容器物件
           ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
            //獲取業務層物件
           us=(UserService) ac.getBean("ss");

    }


問題2:把applicationContext路徑與java程式碼解耦:
需要的包:spring-web-4.1.6.RELEASE.jar
WEB-INF下建立並配置web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
 <!--配置Spring 配置檔案路徑  -->
     <!--配置引數  -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
<!--配置監聽器  -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
</web-app>

更新servlet中 載入applicationContext.xml檔案的方式,變更為
由於ServletContext可以獲取在web.xml配置的全域性屬性。
由webApplicationContextUtils的方法獲得一個ServletContext(Application)物件,作用域為一個專案之內。
getServletContext()是spring對外提供的封裝好的獲取全域性配置檔案的物件。

       private UserService us;
  public void init() throws ServletException {
          //獲取spring容器物件
            ApplicationContext ac=WebApplicationContextUtils.getWebApplicationContext(getServletContext());
            //獲取業務層物件
                us=(UserService) ac.getBean("ss");
           }


伺服器端驗證碼

伺服器端驗證碼:
方式一:自己寫生成程式碼:
生成驗證碼並放入session物件中:
//生成驗證碼
   public static void CreatVerifyCode(HttpServletRequest req,HttpServletResponse resp) throws IOException{
        //建立圖片
        BufferedImage image=new BufferedImage(200,100, BufferedImage.TYPE_INT_RGB);
    //設定圖片
        //獲取畫筆
        Graphics2D gh=(Graphics2D) image.getGraphics();
        //設定畫筆顏色
        gh.setColor(Color.ORANGE);
        //填充畫板
        gh.fillRect(0, 0, 200, 100);
        //作畫

            //設定字型
            gh.setFont(new Font("宋體",Font.ITALIC|Font.BOLD, 40));
            //建立隨機驗證碼
            ArrayList<Integer> list=new ArrayList<>();
            for(int i=0;i<4;i++){
                int num=(int) (Math.random()*10);
                list.add(num);                  
            }
            //設定顏色陣列
            Color[] crs=new Color[]{Color.black,Color.cyan,Color.blue,Color.GREEN,Color.red,Color.yellow};
            //遍歷驗證碼
            for(int i=0;i<list.size();i++){
                //重新設定畫筆顏色
                gh.setColor(crs[(int) (Math.random()*crs.length)]);
                //畫驗證碼
                gh.drawString(list.get(i)+"",i*40,(int)(70+(Math.random()*21-10)));
            }

            //畫線
            gh.drawLine(0, (int)(Math.random()*100), 200, (int)(Math.random()*100));
            gh.drawLine(0, (int)(Math.random()*100), 200, (int)(Math.random()*100));
            //將驗證碼資訊儲存到session中
            req.getSession().setAttribute("codeSystem", ""+list.get(0)+list.get(1)+list.get(2)+list.get(3));
    //響應圖片
        //獲取響應流物件
        OutputStream os=resp.getOutputStream();
        //輸出圖片
        ImageIO.write(image, "jpg", os);
   }


Servlet 獲取前臺資料並且校驗驗證碼:
                        String code=req.getParameter("code");
                        //校驗驗證碼
                        String codeSystem=(String) req.getSession().getAttribute("codeSystem");
                        if(!code.equals(codeSystem)){
                            req.setAttribute("str", "驗證碼不正確");
                            //請求轉發
                            req.getRequestDispatcher("login.jsp").forward(req, resp);
                            return;
                        }

方式二:使用外掛:
https://www.cnblogs.com/xdp-gacl/p/4221848.html

小案例

使用spring 整合mybatis實現登入
資料庫設計 t_usr : uid uname upwd

src:
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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
     <!--配置資料來源  -->
     <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
     <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
     <property name="url" value="jdbc:mysql://localhost:3306/mybatis"></property>
     <property name="username" value="root"></property>
     <property name="password" value="root"></property>
     </bean>
     <!--配置工廠類物件  -->
     <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean" >
     <property name="dataSource" ref="dataSource"></property>
     </bean>
     <!--配置mapper包掃描  -->
     <bean id="mapper" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.bjsxt.mapper"></property>
        <property name="sqlSessionFactory" ref="factory"></property>
     </bean>
     <!--相關bean  --> 
        <!--業務層bean  -->
     <bean id="ss" class="com.bjsxt.serviceImpl.UserServiceImpl">
     <property name="um" ref="userMapper"></property>
     </bean>
</beans>

com.bjsxt.mapper:
UserMapper.java:

package com.bjsxt.mapper;

import com.bjsxt.pojo.User;

public interface UserMapper {
    //根據賬號密碼查詢使用者資料
   User selUser(String uname,String upwd);
}

UserMapper.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.bjsxt.mapper.UserMapper">
  <select id="selUser" resultType="com.bjsxt.pojo.User" >
   select * from t_user where uname=#{0} and upwd=#{1}
  </select>

 </mapper>

com.bjsxt.pojo:
User.java:

package com.bjsxt.pojo;

public class User {
  private int uid;
  private String uname;
  private String upwd;
public User() {
    super();
    // TODO Auto-generated constructor stub
}
public User(int uid, String uname, String upwd) {
    super();
    this.uid = uid;
    this.uname = uname;
    this.upwd = upwd;
}
public int getUid() {
    return uid;
}
public void setUid(int uid) {
    this.uid = uid;
}
public String getUname() {
    return uname;
}
public void setUname(String uname) {
    this.uname = uname;
}
public String getUpwd() {
    return upwd;
}
public void setUpwd(String upwd) {
    this.upwd = upwd;
}
@Override
public String toString() {
    return "User [uid=" + uid + ", uname=" + uname + ", upwd=" + upwd + "]";
}
@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + uid;
    result = prime * result + ((uname == null) ? 0 : uname.hashCode());
    result = prime * result + ((upwd == null) ? 0 : upwd.hashCode());
    return result;
}
@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    User other = (User) obj;
    if (uid != other.uid)
        return false;
    if (uname == null) {
        if (other.uname != null)
            return false;
    } else if (!uname.equals(other.uname))
        return false;
    if (upwd == null) {
        if (other.upwd != null)
            return false;
    } else if (!upwd.equals(other.upwd))
        return false;
    return true;
}

}

com.bjsxt.service:
UserService.java:

package com.bjsxt.service;

import com.bjsxt.pojo.User;

public interface UserService {
   User getUserInfo(String uname,String upwd);
}

com.bjsxt.serviceImpl:
UserServiceImpl.java:

package com.bjsxt.serviceImpl;

import com.bjsxt.mapper.UserMapper;
import com.bjsxt.pojo.User;
import com.bjsxt.service.UserService;

public class UserServiceImpl implements  UserService{
    private UserMapper um;


    public UserMapper getUm() {
        return um;
    }


    public void setUm(UserMapper um) {
        this.um = um;
    }


    //根據賬號密碼查詢使用者資訊
    @Override
    public User getUserInfo(String uname, String upwd) {
        return um.selUser(uname, upwd);
    }

}

com.bjsxt.servlet:
UserServlet.java:

package com.bjsxt.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.bjsxt.pojo.User;
import com.bjsxt.service.UserService;

/**
 * Servlet implementation class UserServlet
 */
@WebServlet("/user")
public class UserServlet extends HttpServlet {
    //宣告業務層物件
        private UserService us;
    @Override
    public void init() throws ServletException {
          //獲取spring容器物件
           //ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
         ApplicationContext ac=WebApplicationContextUtils.getWebApplicationContext(getServletContext());
            //獲取業務層物件
            us=(UserService) ac.getBean("ss");
           //獲取結果
    }
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //設定請求編碼格式
        req.setCharacterEncoding("utf-8");
        //設定響應編碼格式
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        //獲取請求資訊
        String uname=req.getParameter("uname");
        String upwd=req.getParameter("upwd");
        String code=req.getParameter("code");
        //處理請求資訊
             User user=us.getUserInfo(uname, upwd);
            //校驗驗證碼
                String codeSystem=(String) req.getSession().getAttribute("codeSystem");
                if(!code.equals(codeSystem)){
                    req.setAttribute("str", "驗證碼不正確");
                    //請求轉發
                    req.getRequestDispatcher("login.jsp").forward(req, resp);
                    return;
                }
        //響應處理結果
           if(user!=null){
               //獲取session物件
              HttpSession  hs=req.getSession();
              hs.setAttribute("user", user);
              resp.sendRedirect("main.jsp");
           }else{
               req.setAttribute("str", "賬號或者密碼錯誤,請重新輸入");
               req.getRequestDispatcher("login.jsp").forward(req, resp);
           }
    }
}

CodeServlet.java:

package com.bjsxt.servlet;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.bjsxt.util.VerifyCodeUtil;

/**
 * Servlet implementation class CodeServlet
 */
@WebServlet("/cs")
public class CodeServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //建立驗證碼
        VerifyCodeUtil.CreatVerifyCode(req, resp);
    }
}

com.bjsxt.util:
VerifyCodeUtil.java:

package com.bjsxt.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class VerifyCodeUtil {

    //生成驗證碼
   public static void CreatVerifyCode(HttpServletRequest req,HttpServletResponse resp) throws IOException{
        //建立圖片
        BufferedImage image=new BufferedImage(200,100, BufferedImage.TYPE_INT_RGB);
    //設定圖片
        //獲取畫筆
        Graphics2D gh=(Graphics2D) image.getGraphics();
        //設定畫筆顏色
        gh.setColor(Color.ORANGE);
        //填充畫板
        gh.fillRect(0, 0, 200, 100);
        //作畫

            //設定字型
            gh.setFont(new Font("宋體",Font.ITALIC|Font.BOLD, 40));
            //建立隨機驗證碼
            ArrayList<Integer> list=new ArrayList<>();
            for(int i=0;i<4;i++){
                int num=(int) (Math.random()*10);
                list.add(num);                  
            }
            //設定顏色陣列
            Color[] crs=new Color[]{Color.black,Color.cyan,Color.blue,Color.GREEN,Color.red,Color.yellow};
            //遍歷驗證碼
            for(int i=0;i<list.size();i++){
                //重新設定畫筆顏色
                gh.setColor(crs[(int) (Math.random()*crs.length)]);
                //畫驗證碼
                gh.drawString(list.get(i)+"",i*40,(int)(70+(Math.random()*21-10)));
            }

            //畫線
            gh.drawLine(0, (int)(Math.random()*100), 200, (int)(Math.random()*100));
            gh.drawLine(0, (int)(Math.random()*100), 200, (int)(Math.random()*100));
            //將驗證碼資訊儲存到session中
            req.getSession().setAttribute("codeSystem", ""+list.get(0)+list.get(1)+list.get(2)+list.get(3));
    //響應圖片
        //獲取響應流物件
        OutputStream os=resp.getOutputStream();
        //輸出圖片
        ImageIO.write(image, "jpg", os);
   }
}

WebContext:
js:
jquery-1.9.1.js
login.jsp:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>登入介面</title>
<script type="text/javascript" src="j/jquery-1.9.1.js"></script>
<script type="text/javascript">
 $(function(){
     $("#a2").click(function(){
         $("#a1").attr("src","cs?"+new Date());
         return false;
     })
 })
</script>
</head>
<body>
${str } ${code}
  <form action="user" method="get">
    賬號: <input type="text"  name="uname" value=""/><br />
   密碼:<input type="password" name="upwd" value="" /><br />
   驗證碼: <input type="text" name="code" value="" /><img  src="cs" id="a1"/>
   <a href=""  id="a2">看不清點我</a><br />
  <input type="submit" value="登入" />
  </form>
</body>
</html>

main.jsp:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>主頁面</title>
</head>
<body>
  歡迎${user.uname} 登入
</body>
</html>

WEB-INF:
web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
 <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>
</web-app>

原始碼地址:
連結:https://pan.baidu.com/s/1rjWTJ9nl2UeBECt9JY0t2A 密碼:svai

小結

Spring 框架介紹以及知識點
spring IOC學習
springIOC建立物件的三種方式
spring整合Mybatis
DTD &Schema
其他知識點
ApplicationContext物件的建立問題
伺服器端驗證碼
小案例

相關文章