论坛首页 Java企业应用论坛

Spring 3.0 MVC 开发指南[强烈推荐1个小时掌握精华]

浏览 127154 次
该帖已经被评为精华帖
作者 正文
   发表时间:2012-02-16  
struts 2好像有个严重的安全问题,可以在struts 2控制器后面添加java动态脚本直接攻击应用服务器导致服务器被关闭,严重的情况下可以将服务器文件系统全部删除
不晓得有人碰到过没有。
0 请登录后投票
   发表时间:2012-02-16  
yin_bp 写道
struts 2好像有个严重的安全问题,可以在struts 2控制器后面添加java动态脚本直接攻击应用服务器导致服务器被关闭,严重的情况下可以将服务器文件系统全部删除
不晓得有人碰到过没有。


http://struts.apache.org/2.x/docs/version-notes-2312.html

引用
Default acceptedParamNames were updated to more restrictive values to solve security vulnerabilities in ParameterInterceptor - support for param names with withe spaces was dropped! Also a new configuration was added to CookieInterceptor call acceptCookieNames to prevent remote code execution with cookies. There is a security weaknesses in DebuggingInterceptor as a wanted feature in Development Mode, which anyway should not be used it in a production environment!


引用
Default acceptedParamNames were further updated to more restrictive values to solve security vulnerabilities in ParameterInterceptor.
Also a new method was added to ValueStack called setParameter to prevent remote code execution through the evaluation of parameter names.
0 请登录后投票
   发表时间:2012-02-16  
个人感觉这种问题是由struts 2本身的体系机制导致的,是一个先天性的缺陷,只要他还采用这种方式,那么类似的问题还会出现,而且他通过拦截器去扫描这些参数本身就有很大的性能开销。

0 请登录后投票
   发表时间:2012-02-16  
yin_bp 写道
个人感觉这种问题是由struts 2本身的体系机制导致的,是一个先天性的缺陷,只要他还采用这种方式,那么类似的问题还会出现,而且他通过拦截器去扫描这些参数本身就有很大的性能开销。



你这简直就是瞎扯淡。

这个漏洞是由OGNL带来的,和Struts2一点关系都没有。更何况,这个漏洞存在的依据在于注入的执行代码在操作系统级别有执行的权限,难道你的程序在服务器上连基本的运行权限都控制不好?这东西和先天性缺陷一毛钱关系都没有。

拦截器扫描参数有很大的性能开销?我真是无语了,要是连request.getParameterMap都有性能开销,我们还写什么J2EE程序?
0 请登录后投票
   发表时间:2012-02-16   最后修改:2012-02-16
risemanjavaeye 写道

...

更绝的是,对于List或者Map之类的容器映射,SpringMVC也无法处理。解决的方法,就是把List放到一个formbean里面去!

所以,那些说所谓SpringMVC在参数绑定上远超Struts2的人,我实在不明白他们的脑子在想什么!

不过SpringMVC3.1提供了针对参数的扩展机制,我们可以提供自己的扩展类来对上述问题进行处理。只是这个扩展类写起来有点麻烦,并且可能和传统的映射方式稍有冲突,有兴趣的可以自行实现。

1.上面downpour已经解释了,Spring MVC完全可以处理级联属性映射的问题,Spring一出生就支持了;
2.Spring MVC不是简单地直接支持List或Map的映射,Spring框架如果这么做,就不能显示Spring的高明了,Spring 3.0核心模块添加了很多东西,其中有两个最重要的,其一是:
org.springframework.core.convert 

其二是
org.springframework.format 

    也就是说Spring对类型转换和格式化都进行了高层的抽象,不再纠缠于实现一两个固有的功能,而是把类型转换和格式化抽象化、模块化、可扩展化。这也是我说Spring比其它框架在此处高明和有远见的地方。
    在Spring哲学看来format其实也是一种convert,因此,我们就只要简单地看看Spring在convert模块是如何抽象的就可以了。
   我们知道,早期很多框架的类型转换其实都是基于Java标准的PropertyEditor演化的,但是PropertyEditor拥有缺陷,或者说是限制吧:

        只能用于字符串和Java对象的转换,不适用于任意两个Java类型之间的转换;
        对源对象及目标对象所在的上下文信息(如注解、所在宿主类的结构等)不敏感,在类型转换时不能利用这些上下文信息实施高级转换逻辑。

  Spring的convert突破了这两点限制,所以可以让Spring的转换功能变得非常强大,拥有更多的可能。象Spring的Bean在绑定时支持JSR303校验体系(@NotNull @Pattern),支持格式化解(@DateFormat,@NumberFormat)等,溯其源就是因为Spring的convert模块在数据绑定时可以读取被绑定目标属性所在宿主类上下文信息(如属性上的注解,类型等等反射信息)的缘故。
  Spring允许无限扩展其类型转换的逻辑,通过
ConversionServiceFactoryBean
或者
FormattingConversionServiceFactoryBean
进行注册即可。
   下面是在Spring MVC在命令对象数据绑定时,支持Map的扩展实现(非常灵活和简单):
    <mvc:annotation-driven conversion-service="conversionService"/>
    <bean id="conversionService"
   		class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
   		<property name="converters">
   			<list>
   				<bean class="com.baobaotao.domain.StringToUserConverter" />
                <bean class="com.baobaotao.domain.StringToMapConverter" />
   			</list>
   		</property>
   	</bean>


   这里注册了2个自定义的类型转换器,其中StringToMapConverter可将key:value,key:value类型的参数变量绑定到Map中,而StringToUserConverter可以将userName:password:realName格式的参数变量绑定到User对象中。
   简单看一下这两个转换器的代码(StringToMapConverter):
public class StringToMapConverter implements Converter<String,Map> {
    
    //String->Map类型转换逻辑定义:假设是key:value,key:value的结构
    public Map convert(String source) {
       if(source != null){
           LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
           String[] items = source.split(",");
           for (String item : items) {
               String[] keyValue = item.split(":");
               map.put(keyValue[0],keyValue[1]);
           }
           return map;
       }else{
           return null;
       }
    }
}

  StringToUserConverter:
  public class StringToUserConverter implements Converter<String,User>{
        //String->User类型转换逻辑定义
	public User convert(String source) {
		User user = new User();
		if(source != null){
			String[] items = source.split(":");
			user.setUserName(items[0]);
			user.setPassword(items[1]);
			user.setRealName(items[2]);
		}
		return user;
	}
}
  

  看一下User这个命令对象:
public class User {   
	private String userId;	
	private String userName;	
	private String password;	
	private String realName;
        private Map<String,String> resumes;//key1:value1,key2:value2可绑定到这里
}

  以下是Controller的代码:
@Controller
@RequestMapping("/user")
public class UserController extends MyBase {
    @ResponseBody
    @RequestMapping(value = "/convertToListMap")
    public User convertToListMap(User user) {
        return user;
    }
}


  写一个测试类:
    @Test
	public void testConvertToListAndMap() {
        RestTemplate restTemplate = new RestTemplate();
        MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>();
        form.add("resumes", "key1:value1,key2:value2");
        String response = restTemplate.postForObject(
                "http://localhost:9080/user/convertToListMap", form, String.class);
        System.out.println("response:" + response);
	}

   将可以看到resumes参数会自动绑定到User的resumes中。
 
引用
也许评价一个框架的好坏有很多种标准,个人比较倾向于框架的扩展性和灵活性,而不是提供了什么内在的功能,毕竟永远不变的是变化。从这个这标准上来说,我觉得Spring MVC堪称典范。
0 请登录后投票
   发表时间:2012-02-16   最后修改:2012-02-16
   Spring MVC的扩展性真的很强,本人花了一周时间,使用Spring MVC框架实现了类似TOP(淘宝开放平台)http://api.taobao.com的REST框架,等整理后将在这儿公布出来,欢迎交流!
0 请登录后投票
   发表时间:2012-02-16   最后修改:2012-02-16
downpour 写道
yin_bp 写道
个人感觉这种问题是由struts 2本身的体系机制导致的,是一个先天性的缺陷,只要他还采用这种方式,那么类似的问题还会出现,而且他通过拦截器去扫描这些参数本身就有很大的性能开销。



你这简直就是瞎扯淡。

这个漏洞是由OGNL带来的,和Struts2一点关系都没有。更何况,这个漏洞存在的依据在于注入的执行代码在操作系统级别有执行的权限,难道你的程序在服务器上连基本的运行权限都控制不好?这东西和先天性缺陷一毛钱关系都没有。

拦截器扫描参数有很大的性能开销?我真是无语了,要是连request.getParameterMap都有性能开销,我们还写什么J2EE程序?



我不晓得这个问题和struts 2有没有关系,我只晓得很多人这么用了struts 2后就出现这种问题,很多应用都是外网系统。

拦截器扫描参数过滤特殊字符,应该是有性能开销的,和request.getParameterMap没关系。

明明是struts 2的问题还要赖到OGNL身上,其实有问题不可怕,可怕的是出了问题还这么瞎扯蛋,那就不对了。
0 请登录后投票
   发表时间:2012-02-16  
yin_bp 写道


我不晓得这个问题和struts 2有没有关系,我只晓得很多人这么用了struts 2后就出现这种问题,很多应用都是外网系统。

拦截器扫描参数过滤特殊字符,应该是有性能开销的,和request.getParameterMap没关系。

明明是struts 2的问题还要赖到OGNL身上,其实有问题不可怕,可怕的是出了问题还这么瞎扯蛋,那就不对了。


其实有问题不可怕,可怕的是像你如此无知的人还在那边大言不惭和混淆视听。求求你先看看ParametersInterceptor的源码再来讨论好不?

就你这样对待技术的态度简直让人脸红。
0 请登录后投票
   发表时间:2012-02-16  
你回复很不错,不过我还是要指出你概念上的一些错误。

stamen 写道

1.上面downpour已经解释了,Spring MVC完全可以处理级联属性映射的问题,Spring一出生就支持了;


SpringMVC能够处理级联属性映射的问题,但不是Spring一出生就支持的。我在回复中已经提到,Spring3.0中引入了SpringEL,而级联属性的映射内在机理是SpringEL,所以这一支持是从Spring3.0才开始的。Spring2.X的任何版本都无法支持这一特性。这也就是长期以来,SpringMVC在属性映射上无法战胜Struts2的一个很重要原因。

stamen 写道

2.Spring MVC不是简单地直接支持List或Map的映射,Spring框架如果这么做,就不能显示Spring的高明了


这句话的的逻辑明显有问题。不简单地直接支持一个特性,反而变成了它的高明之处,这逻辑到哪儿都是说不通的。

其实你后面举的那个converter包的例子,基本不能说明SpringMVC在参数映射上的优势。converter这东西在OGNL中就像玩一样简单。而Spring却是在3.0之后才提供的这一功能。

我个人对于这两个框架的使用时间都很长,所以基本上相对于其他一些盲目跟从者而言,还是有些发言权的。目前我的观点大概是这样:

1. Struts2在SpringMVC3.0版本之前可以说是一枝独秀的,这一点毋庸置疑。

2. SpringMVC在引入新的语法结构和对编程标准的支持上做的远比Struts2好,所以SpringMVC从架构本身的质量上来说已经超越Struts2。

3. 在局部功能点上,由于编程模型的限制,SpringMVC是不可能达到Struts2的程度的。比如参数绑定,只要同时用过2个框架的人,稍加比较就能一目了然。抬杠是没有意义的。

4. 不要鼓吹什么性能和扩展性。目前我看到的市面上所有对2个框架的性能测试比较都是错误的。有关扩展性,两者的思考角度是不同的。SpringMVC的扩展属于空间扩展,所以非常大气,给人的印象是扩展性非常好;而Struts2的扩展属于时间扩展,用robbin以前的说法:使用AOP来实现IoC。这也就是Struts2的拦截器能够给所有的人留下很深刻印象而SpringMVC的拦截器却碌碌无为的重要原因。

0 请登录后投票
   发表时间:2012-02-16  
downpour 写道
yin_bp 写道


我不晓得这个问题和struts 2有没有关系,我只晓得很多人这么用了struts 2后就出现这种问题,很多应用都是外网系统。

拦截器扫描参数过滤特殊字符,应该是有性能开销的,和request.getParameterMap没关系。

明明是struts 2的问题还要赖到OGNL身上,其实有问题不可怕,可怕的是出了问题还这么瞎扯蛋,那就不对了。


其实有问题不可怕,可怕的是像你如此无知的人还在那边大言不惭和混淆视听。求求你先看看ParametersInterceptor的源码再来讨论好不?

就你这样对待技术的态度简直让人脸红。


懒得和你这样的人磨嘴皮子,眼睛里面揉不得半点沙子,我对struts不感兴趣,也没有时间去看那个什么ParametersInterceptor的源码。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics