iyihua

  • 首页

  • 标签

  • 分类

  • 归档

[spring-boot]springboot实践之在项目中使用spring-cache和redis实现缓存

发表于 2016-04-09 | 更新于 2019-05-22 | 分类于 java-spring

1.首先需要准备一个redis服务端作为缓存

redis下载安装启动,比较简单,请google之。

2.项目依赖

使用spring boot和spring cache,需要springboot依赖

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

连接redis,需要spring data redis和jedis包

1
2
3
4
5
6
7
8
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>

3.程序配置实现与使用

不同于spring使用xml配置文件来配置bean,spring boot使用java bean直接在java类中配置需要用到的Bean。

添加redis cache相关的config类,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;

@Configuration
@EnableCaching
public class RedisCacheConfig extends CachingConfigurerSupport {
@Bean
public JedisConnectionFactory redisConnectionFactory() {
JedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory();
redisConnectionFactory.setHostName("127.0.0.1");
redisConnectionFactory.setPort(6379);
return redisConnectionFactory;
}
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf) {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();
redisTemplate.setConnectionFactory(cf);
return redisTemplate;
}
@Bean(name = "redisCacheManager")
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
cacheManager.setDefaultExpiration(300);
return cacheManager;
}
}

@Configuration标记此java类为spring boot的配置类
@EnableCaching标记为项目启用缓存
@Bean,每个被此注解标记的方法都会配置一个bean,等同于xml配置中的
从以上代码可以看到,使用spring cache和redis缓存,我们需要一个JedisConnectionFactory,一个RedisTemplate和一个CacheManager。
其中JedisConnectionFactory配置了redis服务的ip和端口,为了方便这里直接写在了程序里,可以移出去放到配置文件中读取。

如何使用?

使用非常简单,只需要在我们想要缓存的方法前加一个@Cacheable注解即可
下面是一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
@Cacheable(value = "find")
public List<Object> find(Long id) {
...
}
@CacheEvict(value = "find", allEntries = true)
public Object saveProject(Object object) {
...
}
@CacheEvict(value = "find" , allEntries = true)
public void deleteProject(Long id) {
...
}

这里@Cacheable标记的方法在首次调用后,将会将读取到的内容缓存到redis中,以后每次只要缓存中存在该缓存,读取都会从缓存中读取。
但如果实际数据改变了怎么办?
我查看spring cache的api后,没有适用的动态更新缓存的方法,所以这里适用了一种不怎么优雅的解决方案:
每次会对模型数据改变的方法,都清除一次缓存。清除后的第一次,查询会读取数据库,之后再缓存。
@CacheEvict标记的方法,表示将会清除缓存,value属性中配置了“find”,表示清除key为“find”的缓存数据。

这个方案不是很优雅,就是用起来简单,如果想更优雅的方案,应该要自己再实现一套自己可控的缓存程序。

为你的项目做合理的版本控制管理

发表于 2016-04-07 | 更新于 2019-05-22 | 分类于 version

一款经典的分支管理规范

###
我们需要善用代码版本控制系统。上图就是一款经典的分支管理规范,实践如下。

1.
最稳定的代码放在 master 分支上(相当于 SVN 的 trunk 分支),我们不要直接在 master 分支上提交代码,只能在该分支上进行代码合并操作,例如将其它分支的代码合并到 master 分支上。

2.
我们日常开发中的代码需要从 master 分支拉一条 develop 分支出来,该分支所有人都能访问,但一般情况下,我们也不会直接在该分支上提交代码,代码同样是从其它分支合并到 develop 分支上去。

3.
当我们需要开发某个特性时,需要从 develop 分支拉出一条 feature 分支,例如 feature-1 与 feature-2,在这些分支上并行地开发具体特性。

4.
当特性开发完毕后,我们决定需要发布某个版本了,此时需要从 develop 分支上拉出一条 release 分支,例如 release-1.0.0,并将需要发布的特性从相关 feature 分支一同合并到 release 分支上,随后将针对 release 分支部署测试环境,测试工程师在该分支上做功能测试,开发工程师在该分支上修改 bug。待测试工程师无法找到任何 bug 时,我们可将该 release 分支部署到预发环境,再次验证以后,均无任何 bug,此时可将 release 分支部署到生产环境。待上线完成后,将 release 分支上的代码同时合并到 develop 分支与 master 分支,并在 master 分支上打一个 tag,例如 v1.0.0。

5.
当生产环境发现 bug 时,我们需要从对应的 tag 上(例如 v1.0.0)拉出一条 hotfix 分支(例如 hotfix-1.0.1),并在该分支上做 bug 修复。待 bug 完全修复后,需将 hotfix 分支上的代码同时合并到 develop 分支与 master 分支。

6.
对于版本号我们也有要求,格式为:x.y.z,其中,x 用于有重大重构时才会升级,y 用于有新的特性发布时才会升级,z 用于修改了某个 bug 后才会升级。针对每个微服务,我们都需要严格按照以上开发模式来执行。

在linux下部署spring boot项目过程记录

发表于 2016-03-21 | 更新于 2019-05-22 | 分类于 deploy

在linux下部署spring boot项目过程记录

说明

本文章是在centos7下部署spring boot架构的java web项目的过程中的一些记录,记录了linux服务器中需要用到的软件服务的安装和使用

环境说明

linux版本:CentOs7
配备的开发环境软件服务:

- mysql(centos下默认使用mariadb,也可以,两者兼容)
- jdk
- ftp
- redis

1. linux下开放端口

先把一些已知要用到的端口放开了,省的后面要用到的时候连不上
由于centos7默认没有iptables服务,所以需要先安装
首先暂停防火墙

1
2
systemctl stop firewalld
systemctl mask firewalld

Then, install the iptables-services package:

1
yum install iptables-services

Enable the service at boot-time:

1
systemctl enable iptables

配置要放开的端口

1
2
3
4
5
6
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
iptables -I INPUT -p tcp --dport 22 -j ACCEPT
iptables -I INPUT -p tcp --dport 3306 -j ACCEPT
iptables -I INPUT -p tcp --dport 8080 -j ACCEPT
iptables -I INPUT -p tcp --dport 21 -j ACCEPT
iptables -I INPUT -p tcp --dport 8081 -j ACCEPT

保存配置

1
2
3
service iptables save
or
/usr/libexec/iptables/iptables.init save

Managing the service开启停止防火墙服务

1
systemctl [stop|start|restart] iptables

2. linux下安装使用mysql

一般的linux安装mysql,会使用yum install mysql mysql-server mysql-devel
然而,在centos7下这样安装的时候,却发现mysql-server安装不上。
原来,由于Oracle收购mysql后,开源社区担心mysql有闭源的风险,于是使用mysql的一个分支mariadb替代mysql。mariadb完全兼容mysql。 而centos7就是默认推荐使用mariadb代替mysql。
那么,centos7下安装mysql就有两种方式
1)使用mariadb;
2)卸载mariadb,安装mysql

方法1:使用mariadb

1
2
3
yum install mariadb-server mariadb
systemctl start mariadb
mysql -u root -p

方法2:安装mysql:

1
2
3
# wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm
# rpm -ivh mysql-community-release-el7-5.noarch.rpm
# yum install mysql-community-server

安装成功后重启mysql服务。

1
# service mysqld restart

初次安装mysql,root账户没有密码。

1
[root@yl-web yl]# mysql -u root

设置密码

1
mysql> set password for 'root'@'localhost' =password('password');

实践结论:如果不介意使用mariadb的话,就不用折腾安装mysql了,因为我在实际使用方法2安装MySQL的过程中,遇到不少需要折腾的问题。

记录如下:
1)在进入mysql工具时,总是有错误提示:

1
2
3
# mysql -u root -p
Enter password:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

解决:方法操作很简单,如下:

1
2
3
4
5
6
7
8
9
# /etc/init.d/mysql stop
# mysqld_safe --user=mysql --skip-grant-tables --skip-networking &
# mysql -u root mysql
mysql> UPDATE user SET Password=PASSWORD('newpassword') where USER='root' and host='root' or host='localhost';//把空的用户密码都修改成非空的密码就行了。
mysql> FLUSH PRIVILEGES;
mysql> quit
# /etc/init.d/mysqld restart
# mysql -uroot -p
Enter password: <输入新设的密码newpassword>

2)MySQL服务在启动的时候,不能创建pid文件。

在终端看一下该目录是否存在,果然,不存在。
于是,创建了/var/run/mysqld/目录,重启MySQL服务

1
2
[root@spark01 ~]# mkdir -p /var/run/mysqld/
[root@spark01 ~]# /etc/init.d/mysqld start

如果依旧不能成功启动,那有可能是/var/run/mysqld/的属主和属组还是root,mysql并不能在其中创建文件,那么修改该目录的属主和属组,应该就行了。

1
2
3
4
[root@spark01 ~]# ls -ld /var/run/mysqld/
drwxr-xr-x 2 root root 40 Jan 20 18:28 /var/run/mysqld/
[root@spark01 ~]# chown mysql.mysql /var/run/mysqld/
[root@spark01 ~]# /etc/init.d/mysqld start

3. linux下安装jdk

一、卸载系统自带的openjdk
1、查询系统内置的jdk,使用命令如下:

1
rpm -qa | grep java

此时会列出系统中存在的jdk,如果存在就进行卸载,不存在就直接进行安装。
如下:
python-javapackages-3.4.1-11.el7.noarch
java-1.8.0-openjdk-1.8.0.65-3.b17.el7.x86_64
java-1.7.0-openjdk-headless-1.7.0.91-2.6.2.3.el7.x86_64
java-1.8.0-openjdk-headless-1.8.0.65-3.b17.el7.x86_64
tzdata-java-2015g-1.el7.noarch
javapackages-tools-3.4.1-11.el7.noarch
java-1.7.0-openjdk-1.7.0.91-2.6.2.3.el7.x86_64

2、进行卸载,使用命令如下:

1
rpm -e --nodeps jdk相关名称

依次卸载如下:

1
2
3
4
5
6
7
rpm -e --nodeps python-javapackages-3.4.1-11.el7.noarch
rpm -e --nodeps java-1.8.0-openjdk-1.8.0.65-3.b17.el7.x86_64
rpm -e --nodeps java-1.7.0-openjdk-headless-1.7.0.91-2.6.2.3.el7.x86_64
rpm -e --nodeps java-1.8.0-openjdk-headless-1.8.0.65-3.b17.el7.x86_64
rpm -e --nodeps tzdata-java-2015g-1.el7.noarch
rpm -e --nodeps javapackages-tools-3.4.1-11.el7.noarch
rpm -e --nodeps java-1.7.0-openjdk-1.7.0.91-2.6.2.3.el7.x86_64

二、jdk安装
1、下载jdk并上传到/usr/java目录
jdk7下载地址为:http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html 选择对应的linux版本,下载rpm文件。这里选择的是jdk-7u79-linux-x64.rpm。并上传到Linux的/urs/java目录下(java目录不存在则进行创建)。

2、解压安装
进入/usr/java目录,运行如下命令进行解压(rpm -ivh rpm文件名称)

1
rpm -ivh jdk-7u79-linux-x64.rpm

3、配置profile文件
运行如下命令

1
vi /etc/profile

将如下内容添加到profile文件末尾并保持

1
2
export JAVA_HOME=/usr/java/jdk1.7.0_79
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar export PATH=$PATH:$JAVA_HOME/bin

/usr/java/jdk1.7.0_79 指的是jdk的路径

保存之后,运行如下命令使配置生效

1
source /etc/profile

检查jdk是否安装成功,运行如下命令

1
java -version

4. linux下安装redis

1)方法1:使用命令安装
安装redis:

1
yum -y install redis

启动/停止/重启 Redis
启动服务:

1
systemctl start redis.service

停止服务:

1
systemctl stop redis.service

重启服务:

1
systemctl restart redis.service

检查状态:

1
systemctl status redis.service

随系统启动服务:

1
systemctl enable redis.service

2)方法二:编译安装
下载安装编译:

1
2
3
4
5
wget http://download.redis.io/releases/redis-2.8.17.tar.gz
tar xzf redis-2.8.17.tar.gz
cd redis-2.8.17
make
make install

设置配置文件路径:

1
mkdir -p /etc/redis && cp redis.conf /etc/redis

修改配置文件:

1
vim /etc/redis/redis.conf

修改为: daemonize yes
启动Redis:

1
/usr/local/bin/redis-server /etc/redis/redis.conf

5. linux配置ftp服务

在安装前查看是否已安装vsftpd

1
2
[root@localhost ~]# rpm -q vsftpd
vsftpd-3.0.2-9.el7.x86_64

如果有显示类似以上的信息,说明已经安装vsftpd,如果没有,用yum安装:

1
[root@localhost ~]# yum -y install vsftpd

查看一下vsftpd安装在哪:

1
2
[root@localhost ~]# whereis vsftpd
vsftpd: /usr/sbin/vsftpd /etc/vsftpd /usr/share/man/man8/vsftpd.8.gz

启动vsftpd服务:

1
[root@localhost ~]# systemctl start vsftpd.service

修改配置

1
vi /etc/vsftpd/vsftpd.conf

修改如下配置:
anonymous_enable=NO
chroot_local_user=YES
allow_writeable_chroot=YES #加上这行解决了无法登陆的问题

启动/重新启动ftp

1
2
service vsftpd start
service vsftpd restart

设置开机启动ftp

1
chkconfig vsftpd on

配置用户

1
2
3
[root@localhost ~]# useradd -g root -M -d /var/www/html -s /sbin/nologin ftpuser
[root@localhost ~]# passwd ftpuser
[root@localhost ~]# 输入密码

把 /var/www/html 的所有权给ftpuser.root

1
[root@localhost ~]# chown -R ftpuser.root /var/www/html

6. 附:使用maven把java project打成包含依赖包的jar包,上传到服务器,并启动

编译打包:

方法1:使用maven-assembly-plugin插件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.iyihua.itimes.App</mainClass></manifest>
</archive>
<descriptorRefs>
<descriptorRef> jar-with-dependencies </descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>

运行命令:mvn assembly:assembly
或者命令:mvn package

由于我使用这个方式,打出来的jar包里,依赖的jar和模块的class都正常,但是自己项目内的所有class都是空的class,用反编译看class文件,发现都是

1
class {}

解压出来取单个class查看又是正常的,这个问题一直百撕不得骑姐,所以我最后使用了方法2的方式解决了问题。

方法2:使用spring-boot-maven-plugin插件
由于我的project是spring boot项目,所以可以使用此方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.iyihua.itimes.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>

运行mvn package打jar包,done!

上传并启动

连接sftp
lcd 打开本地路径
cd 进入服务器目标路径
put xxx.jar 把目标jar包上传到服务器对应路径
java -jar xxx.jar 启动java程序

集群监控初步整理

发表于 2016-03-11 | 更新于 2019-05-22 | 分类于 architecture

集群监控初步整理

spring aop 知识体系整理

发表于 2016-02-20 | 更新于 2019-05-22 | 分类于 java-spring

spring aop 整理
参考:
1.https://www.ibm.com/developerworks/cn/java/j-lo-springaopcglib/
2.http://blog.csdn.net/dreamrealised/article/details/12885739
思维导图:
http://naotu.baidu.com/file/b3c0f4b10b0af258be629adb3b3259a2

java-io体系整理

发表于 2016-02-20 | 更新于 2019-05-22 | 分类于 java

java io体系使用整理

  • 来源:http://www.importnew.com/17714.html
  • 思维导图:http://naotu.baidu.com/file/ef892698672800bd4e2a8306f946f91f

[java]从代码中去除if-else

发表于 2016-02-02 | 更新于 2019-05-22 | 分类于 java

有时候代码中会遇到大段的if else语句,灰常的不优雅,就算没有强迫症的人,也必定除之而后快。在java中,都有哪些方式能去除那些if else呢?

首先要明确的是,实践而言,并不是只要有大段的if else语句就一定需要优化,在开始的时候,如果这里的逻辑比较清楚简单,而且也没有预期到一些业务逻辑会产生变动,那么其实就并不需要,起码是并不急着需要去优化这个if else语句。

当判断到确实需要优化if else,方法有很多,总结如下。

  1. 使用map.
  2. 使用枚举.
  3. 多态. 当然,设计模式实际上就是多态,而且理论上,大部分的设计模式都能用于优化if else,可以根据具体情况处理。
    当if else代码段中的逻辑比较多和复杂的时候,可以适当的使用方法或者类封装好处理逻辑,然后使用反射来根据不同条件匹配对应处理方法或处理类。

下面举例。
要优化的原if else语句:

1
2
3
4
5
6
7
int code;
if("Name".equals(str))
code = 0;
else if("Age".equals(str))
code = 1;
else if("Address".equals(str))
code = 2;

使用map优化

1
2
3
4
5
6
7
8
public final static Map map = new HashMap();  
static {
map.put("Name", 0);
map.put("Age", 1);
map.put("Address", 2);
}

int code = map.get(type);

使用枚举优化

1
2
3
4
5
6
7
8
9
public enum Codes {
Name(0), Age(1), Address(2);
public int code;
Codes(int code){
this.code = code;
}
}

int code = Codes.valueOf(str).code;

使用多态优化

1
2
3
ICode iCode = (ICode)Class.forName("com.xxx." + str).newInstance();

int code = iCode.getCode();

“责任链”如何优化if else?

首先,既然每个if分支后面跟着一堆复杂的逻辑,每个分支里做的事情肯定不同,把它们堆在一个方法中并不妥当(如果楼主想讨论为什么不妥当,可以另外讨论,最常见的不妥当是因为各个分支的抽象层次不同导致阅读者思路混乱)。因此最好把各个分支的处理代码分别抽出来,分别形成独立的方法。这样每个分支处理都有明确的边界,而且我们可以在方法上写javadoc,形成良好的文档。

好,现在你有了一个单纯含有if分支的主控方法和一堆执行处理的方法,你面临的第二个问题是每个方法上都要传入一大串参数,因为原来的复杂处理往往依赖大量的上下文状态。解决这个问题的最正统有效(未必优雅)的方法是创建一个上下文(Context)类,或者也可以叫请求(Request)类来携带传入参数。这样可以解决参数文档问题,默认值问题和参数顺序问题。但你有许多个执行方法,显然你不会傻到为每个方法都创建一个上下文,而会只创建一个上下文类,每个方法都接收这个上下文实例,只取自己真正关注的属性。毕竟既然这些执行方法都从一个if结构中抽取处理,这些属性之间逻辑上总有些关联,放在一起也不会有很大问题。

现在你有了一堆参数一致,但名称不同的方法。如果你的需求变动不大,就这样就可以了。但如果你觉得需求可能会有变化,未来可能需要覆盖其中一些方法。你会发现,如果需求1需要你覆盖A,你需要创建一个子类。需求2需要你覆盖B,又要创建一个子类。需求3需要你同时具有需求A,需求B的特性,你又要创建一个子类。既然这样,何不把它们抽到独立的类中,可以分别扩展? 抽取过程中,你发现现在每个处理类都只有一个方法,方法名和类名是重复的。而且本质上它们都是某种处理器(Handler),何不让它们实现统一的接口,方法名统一改为handle。强调一下,这一步是预期需求会有变化的情况才做,如果认为需求不太可能会变化,或者预计变化有足够时间重构,完全可以在前一步就停止。

好,现在你有一个主控方法,这个方法创建一个上下文对象,再根据分支条件分别调用不同Handler子类上的handle方法,传入这个上下文。你注意到一个问题,分支条件本身和对应的处理逻辑是内聚的。如果条件发生变化,处理往往也要发生变化。反之依然。而且你读代码时,读到一个复杂的条件,往往不能轻易看出它要判断什么,这时最好的方法就是直接看看对应Handler的命名和文档,从处理方式反推这个条件对应的业务需求。既然这样,何不干脆把条件都搬到Handler里去,让每个Handler根据传入的上下文,看看在当前状态下自己是否应该执行处理。

现在你得到了一个主控类,这个类持有一堆Handler实例,主控类创建一个上下文,然后把上下文依次传给各个Handler,Handler自行判断是否应该执行自己的处理。

到了这一步,其实已经差不多了。不过对于某些人,他在进行前一步的重构时,就会醒悟:主控类现在已经变成了一个单纯的任务转发人(分配者)。它根本没有必要持有一个Handler的列表再分别逐个调用,还要管理该继续还是该中断等等逻辑(这些逻辑是依赖每个Handler返回的标志来决定的)。何不让Handler自己负责把控制向后分发,主控类只需要知道领头的那个Handler最终会把事情处理好就行了。这种结构还有一个好处,就是每个Handler可以自行决定是否该往下传递控制,还可以根据需要替换上下文实例的实现来影响后续的处理。(这一步与上一步是二选一,有些人喜欢在主控类中持有Handler队列,有些人喜欢链式Handler。我个人认为问题不大,两者的实现难度也没有差别,实现需求就行)

最后,我们为了交流方便,把这种组合方式称为“责任链”。

使用状态模式优化if else

参考:http://www.blogjava.net/xzclog/archive/2006/10/16/75399.html

[springboot][items][项目使用实践]springboot get started

发表于 2016-02-01 | 更新于 2019-05-22 | 分类于 java-spring

往后将通过一个时间记录web app项目,实践并记录spring boot的使用
为了快速实现,以及以后能更灵活的扩展,后台选用spring boot微服务框架。

1.pom.xml中添加maven依赖

1
2
3
4
5
6
7
8
9
10
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

2.编写项目启动入口App.java

1
2
3
4
5
6
7
@SpringBootApplication
public class App
{
public static void main(String[] args) throws Exception {
SpringApplication.run(App.class, args);
}
}

ok! done!
这样就已经能直接使用spring boot了.
启动App.java,spring boot就会使用内置的tomcat直接在本机的8080端口开启一个服务。

再进一步,为应用引入spring mvc

1
2
3
4
5
6
7
8
9
10
11
@Controller
public class SampleController {


@RequestMapping("/")
@ResponseBody
String home() {
String data = "";
return "Hello World!";
}
}

启动App.java,访问localhost:8080, 即可遇见“Hello World!”

jquery-validate常用用法总结

发表于 2016-01-04 | 更新于 2019-05-22 | 分类于 javascript
  1. juqry validate中,如何对使用ajax提交的方式进行校验?
    有两种方式
    1)使用submitHandler属性配置ajax提交,submithandler:当表单全部校验通过之后会回调配置的代码,此处也就是当校验通过之后调用ajax提交。
    2)使用valid方法,监听form的submit事件,当$(‘#form’).valid()返回true的时候再提交。

    1
    2
    3
    4
    5
    6
    7
    //通过监听form的submit事件,对form进行ajax提交。
    $('#formId').submit(function() {
    if (!$("#formId").valid())
    return false;
    $(this).omAjaxSubmit({});
    return false; //此处必须返回false,阻止常规的form提交
    });
  2. juqry validate中,如何对校验错误的提示信息位置和样式进行更改?
    1)js代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $(function(){  
    $("#form1").validate({
    errorPlacement: function (error, element) {
    error.appendTo(element.parent("td"));
    },
    rules:{
    }
    });
    $("[name$='.sign']").each(function(){
    $(this).rules("add",{required:true,messages:{required:"至少选择一个选项"}});
    });
    });

    2)validate会默认追加一个label,样式默认是error,所以我们做的就是写一个class为error的css就可以了

    1
    2
    3
    4
    5
    6
    7
    8
    <style>  
    label.error {
    color:Red;
    font-size:13px;
    margin-left:5px;
    padding-left:16px;
    }
    </style>

    3) 校验时机,可以自定义在js中想要的时候去校验

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $('.selector').click(function() {
    if ($("selector of you form").valid()) {
    alert('in');
    } else {
    alert('out');
    }
    });
    $("selector of you form").validate({
    rules: {
    receiveDayFrom: {
    required: true
    }
    }
    });

    4) 例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    $("#form").validate({
    rules: {
    name: {
    required: true
    },
    firstname: {
    required: true
    }
    },
    messages: {
    name: {
    required: "Enter name"
    },
    firstname: {
    required: "Enter firstname"
    }
    },
    errorPlacement: function ($error, $element) {
    var name = $element.attr("name");
    $("#error" + name).append($error);
    }
    });
    or:
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    $("#form").validate({
    errorLabelContainer: "#errors",
    rules: {
    name: {
    required: true
    },
    firstname: {
    required: true
    }
    },
    messages: {
    name: {
    required: "Enter name"
    },
    firstname: {
    required: "Enter firstname"
    }
    }
    });
  3. 如何添加自定义的校验?

  • 添加一个方法

    1
    2
    3
    4
    // 字符验证,只能包含英文、数字、下划线等字符。    
    jQuery.validator.addMethod("nameStringCheck", function(value, element) {
    return this.optional(element) || /^[a-zA-Z0-9-_]+$/.test(value);
    }, "只能包含英文、数字、下划线等字符");
  • 在validate配置中使用新加的方法

    1
    2
    3
    4
    5
    6
    7
    8
    $('#form selector').validate({
    rules: {
    username: {
    required: true,
    nameStringCheck: true
    }
    }
    });
  1. 如何使用ajax请求进行远程校验

    1
    2
    3
    jQuery.validator.addMethod("checkUnique", function(value, element) {
    return validateUsernameByAjax(value, element.name, 'ajax请求地址');
    }, "此输入的值不可用");
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    /**
    * 同步做用户名或邮箱的请求,检查到不可用,则返回false,否则返回true
    */
    function validateUsernameByAjax(value, fieldname, url) {
    var _request = url + "?"+fieldname+"="+value;
    var deferred = $.Deferred();//创建一个延迟对象
    $.ajax({
    url:_request,
    async:false,//要指定不能异步,必须等待后台服务校验完成再执行后续代码
    dataType:"json",
    success:function(data) {
    if (data.status === "error" || data.status === "fail") {
    deferred.reject();
    } else{
    deferred.resolve();
    }
    }
    });
    //deferred.state()有3个状态:pending:还未结束,rejected:失败,resolved:成功
    return deferred.state() == "resolved" ? true : false;
    }
    1
    2
    3
    4
    5
    6
    7
    $('#form selector').validate({
    rules: {
    username: {
    checkUnique: true
    }
    }
    });

[git]git常用-把本地项目提交到github

发表于 2015-12-31 | 更新于 2019-05-22 | 分类于 git

1.把本地项目提交到github

touch README.md //新建说明文件
git init //在当前项目目录中生成本地git管理,并建立一个隐藏.git目录
git add . //添加当前目录中的所有文件到索引
git commit -m “first commit” //提交到本地源码库,并附加提交注释
git remote add origin https://github.com/chape/test.git //添加到远程项目,别名为origin
git push -u origin master //把本地源码库push到github 别名为origin的远程项目中,确认提交

2.如果有error: failed to push some refs to ‘https://github.com/YihuaWanglv/myhexo.git'

有如下几种解决方法:

1.使用强制push的方法:
$ git push -u origin master -f
这样会使远程修改丢失,一般是不可取的,尤其是多人协作开发的时候。
2.push前先将远程repository修改pull下来
$ git pull origin master
$ git push -u origin master
3.若不想merge远程和本地修改,可以先创建新的分支:
$ git branch [name]
然后push
$ git push -u origin [name]

1…789
Wanglv Yihua

Wanglv Yihua

82 日志
20 分类
206 标签
RSS
© 2019 Wanglv Yihua
由 Hexo 强力驱动 v3.9.0
|
主题 – NexT.Muse v6.4.1