In the process of system development, in order to increase the security of the system and prevent malicious attacks from some bad users, many systems will use the way to generate and verify the authentication code, and the way to unlock the user to allow users to log in, this article we will simply talk about how to generate a picture verification code, how to verify the picture verification code.
the generation of picture verification code
1, first of all, our husband into a verification code, verification code generation rules are diverse, we do not repeat here, you can refer to the article http://blog.csdn.net/zyhlwzy/article/details/77850395 (Verification code generation and send).
2, provide picture width, height, imagetype parameters to build BufferedImage objects, BufferedImage class is a buffer with the image class, image class is used to describe the information of the class.
3. Obtain the Graphics object through the constructed BufferedImage object, which can perform various drawing operations on the image.
4. Draw the jamming line and draw the string through the Graphics object
5, constructs the Bytearrayoutputstream object, will draw the good image information writes Bytearrayoutputstream.
6, the Bytearrayoutputstream into a byte array to write to the HttpServletResponse, through the flow of output to the client.
The detailed code is as follows:
public class Imageverifycodeutils {private static Random Random = new Random (); private static int width = 80;//picture wide private static int height = 38;//picture high private static int linesize = 40;//interference Line Quantity * * Get font/private static font GetFont () {return new font ("Fixedsys", Font.center_baselin
E, 18);
* * * Get color/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-16);
int g = FC + Random.nextint (BC-FC-14);
int B = FC + Random.nextint (bc-fc-18);
return new Color (R, G, b); /** * @Comment Draw Interference Line * @Author Ron * @Date September 15, 2017 pm 4:31:04 * @return/private S
tatic void Drowline (Graphics g) {int x = random.nextint (width);
int y = random.nextint (height);
int xl = Random.nextint (13); InT yl = random.nextint (15);
G.drawline (x, y, X + xl, y + yl); /** * @Comment Draw String * @Author Ron * @Date September 15, 2017 pm 6:06:25 * @return/private S
tatic void drowstring (Graphics g,string vchar,int i) {G.setfont (GetFont ());
G.setcolor (New Color (Random.nextint (), Random.nextint (), Random. Nextint (121)));
G.translate (Random.nextint (3), Random.nextint (3));
g.DrawString (Vchar, * I, 25); /** * @Comment get random CAPTCHA * @Author Ron * @Date September 15, 2017 pm 4:24:02 * @return * * Public static void Getrandcode (HttpServletRequest request,httpservletresponse response,string verifycode) {//BufferedIm The age class is an image class that has buffers, and the image class is the class BufferedImage image that describes the image information = new BufferedImage (width, height,bufferedimage.type_int_b
GR);
A Graphics object that produces an image object that can perform various drawing operations on the images Graphics g = image.getgraphics ();
G.fillrect (0, 0, width, height); G.setfont (New Font ("Times New Roman", Font.roman_baseline, 18));
G.setcolor (Getrandcolor (110, 133));
Draw the jamming line for (int i = 0; I <= linesize; i++) {drowline (g); //Draw string for (int i = 0; i < verifycode.length (); i++) {drowstring (g,string.valueof verif
Ycode.charat (i)), i);
} g.dispose ();
try {bytearrayoutputstream tmp = new Bytearrayoutputstream ();
Imageio.write (Image, "PNG", TMP);
Tmp.close ();
Integer contentlength = Tmp.size ();
Response.setheader ("Content-length", ContentLength + ""); Response.getoutputstream (). Write (Tmp.tobytearray ());//Output The in-memory picture to the client in the form of a stream (Exception e) {E.P
Rintstacktrace ();
}finally{try {response.getoutputstream (). Flush ();
Response.getoutputstream (). Close ();
catch (Exception E2) { E2.printstacktrace (); }
}
}
}
Second, Spring session storage verification Code
For some smaller systems, temporary data such as CAPTCHA is typically chosen to be stored in the session.
In many application servers, HTTP session state is saved in the JVM, which is the same as the JVM running the application code because it is easy to implement and fast. When a new application server instance joins or leaves the cluster, the HTTP session is rebalanced based on an existing application server instance. In a resilient cloud environment, we have hundreds of application server instances, and the number of instances can increase or decrease at any time, so we have some problems: rebalancing the HTTP session can be a performance bottleneck. In order to store a large number of sessions, a lot of heap space is required, which can result in garbage collection, which adversely affects performance. The cloud infrastructure typically prohibits TCP multicasting (multicast), but the session manager often uses this mechanism to discover which application server instance has joined or left the cluster.
Therefore, a more efficient approach is to save the HTTP session state in a separate data store, which is located outside the JVM where the application code is running. For example, we can configure 100 Tomcat instances to use Redis to store session state, and the session stored in Redis will not be affected when the Tomcat instance is incremented or decreased. Also, because Redis is written in C, it can use hundreds of gigabytes or even terabytes of RAM, and it does not involve garbage collection issues.
For open source servers like Tomcat, it is easy to find alternatives to the session manager, which can use external data storage, such as Redis or memcached. However, these configuration processes can be complex and differ for each application server. For closed-source products such as WebSphere and WebLogic, it is not only difficult, but sometimes impossible, to find their session manager alternatives.
The Spring session provides an application-independent solution that configures pluggable session data stores within the servlet specification, and does not rely on specific APIs for any application server. This means that the spring session can be used in all application servers that implement the servlet specification (Tomcat, Jetty, WebSphere, WebLogic, JBoss, etc.) It is very convenient to configure in all application servers in exactly the same way. We can also choose any external session data store that best fits the needs. This makes the spring session an ideal migration tool, helping us to move traditional Java EE applications into the cloud to make them meet 12-factor (https://12factor.net/) applications.
How to integrate the spring session (where we use Redis to store data) is divided into the following steps:
2.1. Installation and Deployment Redis
Specific Reference Redis official website (https://redis.io/)
2.2. Configure Spring session Dependencies
Configuring spring session dependencies is simple, adding spring session dependencies directly to Pom.xml, because we're using Redis to store data, so we just rely on Spring-session-data-redis.
<!--Spring-session-data-redis dependent-->
<dependency>
<groupid>org.springframework.session </groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>${ Spring_session_data_redis_version}</version>
</dependency>
2.3, the integration of Redis client, configuration Redis parameters
Adding Redis client dependencies in Pom.xml
<!--redis Client configuration-->
<dependency>
<groupId>redis.clients</groupId>
< artifactid>jedis</artifactid>
<version>${redis_clients_version}</version>
</ Dependency>
Write Redis information (host address, port, etc.) in the Config.properties file in the resources directory
#Redis信息配置
#绑定的主机地址
redis.host=127.0.0.1
#指定Redis监听端口, the default port is 6379
redis.port=6379
# Authorization password (not used in this example)
redis.password=123456
#最大空闲数: When the number of free links is greater than Maxidle, the recycle
redis.maxidle=100
# Maximum number of connections: can be established at the same time "maximum number of links"
redis.maxtotal=300
#最大等待时间: Unit ms
redis.maxwait=1000
#使用连接时, detect the success of the connection
redis.testonborrow=true
#当客户端闲置多长时间后关闭连接, if specified as 0, to turn off the feature
redis.timeout=10000
Create a new Spring-context-redis.xml file in the resources directory and start configuring Redis.
<?xml version= "1.0" encoding= "UTF-8"?> <beans "xmlns=" xmlns: Xsi= "Http://www.w3.org/2001/XMLSchema-instance" xmlns:p= "http://www.springframework.org/schema/p" xmlns:context= "Http://www.springframework.org/schema/context" xmlns:mvc= "Http://www.springframework.org/schema/mvc" xsi: schemalocation= "Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/ Spring-beans-4.0.xsd Http://www.springframework.org/schema/context Http://www.springframework.org/schem A/context/spring-context-4.0.xsd Http://www.springframework.org/schema/mvc http://www.springframework.or G/schema/mvc/spring-mvc-4.0.xsd "> <context:annotation-config/> <!--Introducing Properties configuration file--> &l T;context:property-placeholder ignore-unresolvable= "true" location= "Classpath:config.properties"/> <bean id= "Redishttpsessionconfiguration" class= "Org.sPringframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration "> <property Name= "Maxinactiveintervalinseconds" value= "/> </bean> <!--jedis configuration--> <bean id=" PO Olconfig "class=" Redis.clients.jedis.JedisPoolConfig "> <property name=" maxtotal "value=" ${redis.maxtota L} "/> <property name=" Maxidle "value=" ${redis.maxidle} "/> <property name=" Maxwaitmilli S "value=" ${redis.maxwait} "/> <property name=" Testonborrow "value=" ${redis.testonborrow} "/> & lt;/bean> <!--redis Server center--> <bean id= "ConnectionFactory" class=
. connection.jedis.JedisConnectionFactory "> <property name=" poolconfig "ref=" Poolconfig "/>" <property name= "Port" value= "${redis.port}"/> <property name= "hostName" value= "${redis.host}"/&G
T <property NamE= "Timeout" value= "${redis.timeout}" ></property> </bean> </beans>
Because we are already configured in Web.xml, all XML files that begin with Spring-context are loaded when the context is initialized, so the relevant content of Redis is loaded and initialized when the context is initialized.
2.4. Configure Spring Session filter
In Web.xml, add the following configuration:
<!--Spring Session filter Start-->
<filter>
<filter-name>springSessionRepositoryFilter< /filter-name>
<filter-class>org.springframework.web.filter.delegatingfilterproxy</filter-class >
</filter>
<filter-mapping>
<filter-name>springsessionrepositoryfilter</ filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--Spring Session Filter End-->
After the configuration of all the information is complete, we use the spring session in the same way as the traditional use method, for example, we need to store the verification code in this example, we just have to follow the following lines:
Request.getsession (). setattribute ("Loginverifycode", verification Code);
To obtain the authentication code:
Request.getsession (). getattribute ("Loginverifycode");
Project Source: Https://github.com/Ron-Zheng/blog-system
References: https://www.infoq.com/articles/Next-Generation-Session-Management-with-Spring-Session