关于SpringMVC中model的attribute无法指定别名的解决方案

最近由于项目需要,发现spring mvc在绑定参数时有这么一个缺陷。

Url: http://localhost:8080/api/test?user_name=testUser

Controller:

@Controller
@RequestMapping("/api")
public class ApiController extends BaseController {

    @RequestMapping(value = "/test", headers = "Accept=application/json")
    public void authUser(ModelMap modelMap, Account acc) {
        ResultPack.packOk(modelMap);
    }
}

public class Account{
    private static final long serialVersionUID = 750752375611621980L;

    private long id;
    private String userName;
    private String password;
    private AccountType type = AccountType.ADMIN;
    private long timeTag;
    private int status = 1;
    ...
    ...
}

user_name无法映射到acc的userName上。如果使用json的方式,可以使用JsonProperty注解来解决。否则,spring貌似没提供解决方案。

于是追踪了一下spring mvc的源代码,发现可以通过重写ServletModelAttributeMethodProcessor来支持这个功能。

Github: https://github.com/superhj1987/spring-mvc-model-attribute-alias

工作总结@2014

突然发觉已经是2015年的1月15号了,即兴补上一篇2014年的总结吧。

对自己来说,今年最大的事情莫过于离开一座城市,到达另一座城市,开始了新的职业生涯。

进入新的公司,一个创业公司,截然不同的运作方式让我一开始有点措手不及。相比之前在大公司,小公司更需要一个人的快速成长以及自我约束,以及那种随叫随到、不怕脏累的奋斗精神。而技术层面,要尽最大化压榨硬件资源,用有限的硬件资源达到最大的性能。这些都让自己的架构方式和代码编写不得不去改变、去适应,这也算是一种成长吧。公司的基础架构、公共组件、项目管理、技术体系、项目架构都是一个初级的水平,改变这些是一个很难很长的路,但又不得不做。到现在,在做这些改变的过程中,自己的基础知识得到了巩固、架构能力也有了一定的提升,技术视野也开阔了一些。熟悉了公司的流程和整体的氛围,也算融入了这个团队,要做的还有很多,阻力也有很多。一切都在逼迫自己去学习、去思考、去提高。这也是与以前相比,给自己最大动力的事情。

2015年,工作上希望自己能做到这些

  • 合理设计并实现整个公司的基础架构
  • 构建合理的项目管理流程、监督机制
  • 提升团队的整体水平
  • 保证产品的研发进度以及线上稳定性
  • 招一些优秀的人加入

自身方面,希望能做到这些:

  • 提升自身的技术水平和视野
  • 深入学习一门技术:docker netty kafka rabbitmq elasticsearch solr
  • 阅读至少五本非技术书籍

Stay hungry,stay foolish!

SpringMVC的controller传递HttpServletResponse参数的那点事

    @RequestMapping(value = "cardDown", method = RequestMethod.GET, headers = "Accept=text/html")
    public void cardDown(ModelMap modelMap, HttpServletRequest request, HttpServletResponse response, String id, int status){
    ......
    }

之前在使用Spring mvc的时候发现这么一回事:在spring mvc的controller的参数里如果有HttpServletResponse(类似上面的代码),那么必须有返回值框架才会去在执行完handler后去搜索相应的viewResolver和view从而展现数据。如果没有返回值,那么默认就是返回null的。我初步推测框架的处理过程大致如此:如果controller参数里传递HttpServletResposne的话,框架就认为视图由handler自己生成可以不参于这个过程,但是如果handler有返回值的话,那么仍然认为还需要参与到视图生成的过程中。

ShellShock这点事

前言

在微博上看到最近安全界爆出了一个危害比之前的“心脏流血”(Heartbleed Bug)还要大很多的Bash代码注入漏洞:CVE-2014-6271 “shellshock”漏洞,然后随之而来一系列相关漏洞。详情可以看这些链接:CVE-2014-6271CVE-2014-7169CVE-2014-7186CVE-2014-7187CVE-2014-6277。世界上Linux服务器的占有份额是很大的,而bash又是Linux不可或缺的一个部分。可想而知,这个漏洞的破坏力有多大。这个从名字上就可以看出来,ShellShock是医学上的一种严重的疾病,中文叫做“弹震症”,指的是受到爆炸冲击后导致浑身颤抖、思维混乱等症状。这个命名很形象地反映了问题的严重性。

Nginx源码分析之启动过程

nginx的启动过程代码主要分布在src/core以及src/os/unix目录下。启动流程的函数调用序列:main(src/core/nginx.c)→ngx_init_cycle(src/core/ngx_cycle.c)→ngx_master_process_cycle(src/os/)。nginx的启动过程就是围绕着这三个函数进行的。

main函数的处理过程总体上可以概括如下:

Nginx负载均衡

目录

本文最新更新于2016.11.01

一 特点

1.1 应用情况

Nginx做为一个强大的Web服务器软件,具有高性能、高并发性和低内存占用的特点。此外,其也能够提供强大的反向代理功能。俄罗斯大约有超过20%的虚拟主机采用Nginx作为反向代理服务器,在国内也有腾讯、新浪、网易等多家网站在使用Nginx作为反向代理服务器。据Netcraft统计,世界上最繁忙的网站中有11.48%使用Nginx作为其服务器或者代理服务器。基于反向代理的功能,Nginx作为负载均衡主要有以下几点理由:

  1. 高并发连接
  2. 内存消耗少
  3. 配置文件非常简单
  4. 成本低廉
  5. 支持Rewrite重写规则
  6. 内置的健康检查功能
  7. 节省带宽
  8. 稳定性高

Async源码分析

最近在使用到node js的async库的时候,对其waterfall的实现感觉很奇妙,于是看了一下源码:

    async.waterfall = function (tasks, callback) {
        callback = callback || function () {};
        if (!_isArray(tasks)) {
          var err = new Error('First argument to waterfall must be an array of functions');
          return callback(err);
        }
        if (!tasks.length) {
            return callback();
        }
        var wrapIterator = function (iterator) {
            return function (err) {
                if (err) {
                    callback.apply(null, arguments);
                    callback = function () {};
                }
                else {
                    var args = Array.prototype.slice.call(arguments, 1);
                    var next = iterator.next();
                    if (next) {
                        args.push(wrapIterator(next));
                    }
                    else {
                        args.push(callback);
                    }
                    async.setImmediate(function () {
                        iterator.apply(null, args);
                    });
                }
            };
        };
        wrapIterator(async.iterator(tasks))();
    };
 

技术的成长

最近因为一件事情,让自己突然对自己产生了巨大的怀疑。工作一年多,仔细想想貌似真的只是在积累项目经验,而在技术深度上却一直停滞不前。这其中确也有因为之前做产品没有太多空闲时间的缘故,但更多的还是自己一直不得章法。对nginx源码的学习,一拖再拖,想成为这方面的专家却也不知道努力挤出时间或者说没有好的方法让自己合理安排出时间。

毕业的时候自己选择这里,就是想安心的做技术,以求在技术上得到长足的进步。现在却发现在做着一些没那么有技术含量的东西,像某人所说:上学的时候给我一定的时间也能够做出来。虽然我觉得上学的时候,大部分进公司做的东西也能做出来(除非是那种需要基于一定的环境像大数据、高并发才能做的)。但其实我明白,那句话的意思主要强调的是应该潜心去研究一门技术,比如hadoop、storm等,成为一个领域的专家。这也的确是自己的软肋,也的确该好好加强。

Nginx源码分析之基本数据结构

引言

nginx实现中有很多结构体,一般命名为ngx_xxx_t。这些结构体分散在许多头文件中。src/core/ngx_core.h中把几乎所有的头文件都集合起来。也因此造成了nginx各部分源代码的耦合。但实际上nginx各个部分逻辑划分还是很明确的,整体上是一种松散的结构。

作者之所以重复造了这些轮子,无非是为了追求高效。查看这些数据结构的源码,的确是设计的比较精巧,也保证了对内存足够小的占用以及各种操作的高效。

谈谈系统架构这个东西

架构这个词在很多人看来都是很高大上的一个东西。事实上,搞架构的这些人却也都是些大神,至少都是在这个领域浸淫N久的专家级人物。现在很火的全栈工程师这个概念,就是架构师的另一种表现形式。

之于架构,其含义无非是从技术细节跳出来自上而下宏观地看待系统的一个思维,就好比建筑设计一样。架构师的角色和建筑设计师在某种意义上是相同的。在微博上看到蔡学镛分享过这么一个架构设计流程的图,从中或多或少能看出架构设计一个大概的流程。

arch-1

首当其冲的,肯定是需要对整个系统的业务进行拆分,进行业务设计,目的就是要捋清楚系统是干什么的,能提供什么功能,对系统的需求要做到详尽的分析和考虑。不过这部分,在我参与过的一些项目看来,尤其是对现在普遍使用的敏捷开发流程来说,无需考虑的太面面俱到,但至少不能太窄或者偏离正轨,后续的开发过程会不断的反馈回来进行调整。

接下来,系统的业务明确之后,交互设计和领域建模便可以同时执行。当然,这里我是觉得交互设计和架构师是没啥关系的,顶多就是两者要相辅相成。而领域建模这个就显得很重要了。领域建模是业务设计的主要逻辑,把现实中的业务转化成抽象的对象,这个确实是能力的体现了。我觉得这一部分很多出色的架构师相比其他人突出的一个很关键的地方。

技术模块设计则是在理解了系统的业务需求之后,对整体的一个技术框架上的设计。这里对于技术架构,我一直有一个分不太清楚的东西,就是软件架构和系统架构。说到底,这两者都是软件层面的含义,所不同的是前者到了代码层面,而系统架构则是到了软件层面。软件架构是位于系统架构之上的。一个系统,使用了Spring、Hibernater然后用了MVC设计模式,这就是软件架构;一个系统分成负载均衡模块、Link模块、队列模块、数据模块、推送模块等等则就是系统架构。再往下就应该是部署架构了,比如系统部署了几个结点、结点之间的关系、网络的规划结构、系统的高可用、可扩展等等。当然对于一个系统来说,数据的设计是可以拿出来重点进行的,毕竟对于互联网应用来说,数据 is all,系统的很多性能、效率问题是和数据的存储设计有密切关系的。

到最后,业务之上的这些设计会反作用于业务,将系统的关键点反馈回来,从而对业务进行调整,进而再推进整个架构的流程。现在很火的敏捷开发,某种角度看来就是一个不断迭代、反馈的过程,是传统架构设计的一种演化形式。

谈到架构,那么如何才能具有架构能力呢?借鉴在知乎上看到一个回答:

  • 视野开阔,知道可以直接用哪个开源项目来满足这样那样的需求。多数时候其实我们并不需要重复造轮子。视野窄的架构师会放着捷径不走,不断让团队重复造轮子,直至把项目拖死。
  • 精通设计模式,但又不泛用。不设计过度,不在各种细节问题上需求蔓延。所有架构设计都是为了满足产品需求的,不满足需求或者过度设计都是菜鸟行为。
  • 把系统拆分成多个子系统或模块,模块之间尽量松耦合,使得原先只能串行的开发任务,可以并行开展,也就是说良好的设计可以通过投入更多人力来缩短工期。反之拙劣的设计需要一个人维护一大坨代码,无法通过加人并行开发来缩短工期。
  • 能清楚地知道系统的瓶颈在什么地方,不断地定位技术难度、研发进度、性能、内存等各方面的瓶颈,不断调整骨干力量解决瓶颈,在风险爆发之前就消除隐患。
  • 行业经验带来的直觉和预见性,可以预先需求可能产生怎样的变化,提前把可扩展性、后向兼容性设计好。但仍然不要过度设计

以上对架构的一些理解,很多地方自认还是有点迷糊。在进行系统设计的时候,也经常摸不着头脑,把不同层次的东西混为一谈。记得蔡学镛大神之前还分享过一张图片,对架构讲的挺透彻的。不明白的时候看看这个,会有种茅塞顿开的感觉。

arch-2