springmvc的web工程通用配置

1.web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  	<context-param>
    	<param-name>contextConfigLocation</param-name>
    	<param-value>
             classpath:spring/applicationContext.xml
        </param-value>
  	</context-param>
    <context-param>
        <param-name>ssl</param-name>
        <param-value>8443</param-value>
    </context-param>
    <context-param>
        <param-name>http</param-name>
        <param-value>8080</param-value>
    </context-param>
    
	<listener>
	    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<listener>
	    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
	</listener>
	<listener>
		<listener-class>
			com.huawei.ecommerce.common.base.utils.SpringBeanGetter
		</listener-class>
	</listener>
	<filter>
		<filter-name>corsfilter</filter-name>
		<filter-class>com.huawei.ecsp.common.filter.CorsFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>corsfilter</filter-name>
		<url-pattern>/*</url-pattern>
		<dispatcher>REQUEST</dispatcher>
	</filter-mapping> 

     <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>
            com.huawei.ecommerce.common.base.web.filter.CharacterEncodingFilter
        </filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <context-param>
        <param-name>
             weblogic.httpd.inputCharset./*
         </param-name>
        <param-value>UTF-8</param-value>
    </context-param>
    
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!-- SQL、JS脚本 注入攻击过滤器 -->
    <filter>
	   <filter-name>xssFilter</filter-name>
	   <filter-class>com.huawei.esysadmin.common.filter.XssFilter</filter-class>
    </filter>
    <filter-mapping>
	   <filter-name>xssFilter</filter-name>
	   <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <!-- XSS 跨站请求攻击过滤器 -->
    <filter>
	    <filter-name>xssCsrfFilter</filter-name>
	    <filter-class>com.huawei.esysadmin.common.filter.XssCsrfFilter</filter-class>
    </filter>
    <filter-mapping>
	    <filter-name>xssCsrfFilter</filter-name>
	    <url-pattern>/*</url-pattern>
    </filter-mapping>
	
    <servlet>
		<servlet-name>springmvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springmvc-servlet.xml</param-value>
		</init-param>
  	</servlet>
  	<servlet-mapping>
  		<servlet-name>springmvc</servlet-name>
  		<url-pattern>/</url-pattern>
  	</servlet-mapping>

    <servlet>
        <servlet-name>freemarker</servlet-name>
        <servlet-class>
            freemarker.ext.servlet.FreemarkerServlet
        </servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>freemarker</servlet-name>
        <url-pattern>*.ftl</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
</web-app>

2.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" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
	
    <!--切面类配置-->
	<aop:aspectj-autoproxy>
		<aop:include name="xxxAspect" />
	</aop:aspectj-autoproxy>
	<!--切面类配置-->
	
    <!--数据源1各方面配置begin-->
	<!--数据源配置begin,拿到spring的SqlSessionTemplate对象,dao层调用其API-->
	<bean id="GlobalConfig"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
				<value>classpath:datasource.properties</value>
			</list>
		</property>
	</bean>
	<bean id="dataSource_config" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName" value="${xxx.jdbc.driverClassName}" />
		<property name="url" value="${xxx.jdbc.url}" />
		<property name="username" value="${xxx.jdbc.username}" />
		<property name="password" value="${xxx.jdbc.password}" />
	</bean> 
	<bean id="sqlSessionFactoryConfig" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="configLocation" value="classpath:mybatis/sqlmap-config-config.xml"></property>
		<property name="dataSource" ref="dataSource_config"></property>
	</bean>
	<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
		<constructor-arg index="0" ref="sqlSessionFactoryConfig"></constructor-arg>
	</bean>

	
	<!--配置事务管理器begin,-->
	<bean id="transactionManager_config"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource_config"></property>
	</bean>
	<tx:advice id="txAdvice_config" transaction-manager="transactionManager_config">
		<tx:attributes>
			<tx:method name="add*"   propagation="REQUIRED" rollback-for="Throwable" />
            <tx:method name="save*"  propagation="REQUIRED" rollback-for="Throwable" />                                 
            <tx:method name="insert*" propagation="REQUIRED" rollback-for="Throwable" />                                   
            <tx:method name="edit*"  propagation="REQUIRED" rollback-for="Throwable" />
            <tx:method name="modify*"  propagation="REQUIRED" rollback-for="Throwable" />                                 
            <tx:method name="update*" propagation="REQUIRED" rollback-for="Throwable" />
            <tx:method name="commit*" propagation="REQUIRED" rollback-for="Throwable" />  
            <tx:method name="*Commit*" propagation="REQUIRED" rollback-for="Throwable" />  
            <tx:method name="remove*" propagation="REQUIRED" rollback-for="Throwable" />                                 
            <tx:method name="del*"    propagation="REQUIRED"    rollback-for="Throwable" />                                 
            <tx:method name="cancle*" propagation="REQUIRED" rollback-for="Throwable" />   
            <tx:method name="resumeJob*" propagation="REQUIRED" rollback-for="Throwable" />
		</tx:attributes>
	</tx:advice>
    <aop:config>
		<aop:pointcut id="shoppingAllMethod_config"
			expression="execution(* *..service.impl.*.*(..))" />
		<aop:advisor advice-ref="txAdvice_config" pointcut-ref="shoppingAllMethod_config" />
	</aop:config>
	<!--配置事务管理器end-->
	<!--数据源1各方面配置end-->
	
	
	<!--配置调度器,容器初始化启动时执行线程-->
	<bean id="Manager" class="com.xxx.Manager" factory-method="getInstance" init-method="init"></bean>
	
	 <!加载本工程其他spring文件 -->
	<import resource="classpath:spring/applicationContext_*.xml" />

</beans>

创建调度器

/**调度器*/
public class Manager implements Runnable
{
    /** 日志记录 **/
    private static final Logger logger = Logger.getLogger(Manager.class);
    
    /** 调度任务 **/
    ScheduledExecutorService scheduleService = null;
    
    private final static Manager loader = new Manager();
    
    private Manager()
    {
    }
    
    public static Manager getInstance()
    {
        return loader;
    }
	
	 /**
     * 初始化方法,启用调度线程池,每180秒 do soemthing()
     */
    public void init()
    {
        scheduleService = Executors.newScheduledThreadPool(1);
        
        scheduleService.scheduleAtFixedRate(this, 30, 180, TimeUnit.SECONDS);
    }
   
    @Override
    public void run()
    {
        try
        {
           //do something();  
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }   
}

3.listener

SpringBeanGetter

/**
 此监听器用来监听容器初始化和销毁,完成一些操作
*/
public class SpringBeanGetter implements ServletContextListener {
	private static ServletContext context = null;
	private static final Logger logger = Logger.getLogger(SpringBeanGetter.class);
	private static int errorCount = 0;
    
	//容器销毁时执行
	public void contextDestroyed(ServletContextEvent arg0) {
	    setContext(null);
	}
	
	//容器初始化时执行
	public void contextInitialized(ServletContextEvent arg0) {
		setContext(arg0.getServletContext());
	}
	
	private static final void setContext(ServletContext context)
	{
	    SpringBeanGetter.context = context;
	}
    
	//获取bean实例
	public final static <T> T getBean(String beanId) {
		WebApplicationContext application = WebApplicationContextUtils
				.getWebApplicationContext(context);
		while (application == null && errorCount < 5) {
			try {
				Thread.currentThread().sleep(3000);
		        application = WebApplicationContextUtils
                .getWebApplicationContext(context);
				logger.error(" 未找到applicationContext 对象");
				errorCount++;
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		if(null != application)
		{
		    return (T) application.getBean(beanId);
		}
		
		return null;
	}

}

4.filter

SQL、JS脚本 注入攻击过滤器

/**
 * 防SQL、JS脚本、特殊字符 注入攻击过滤器
 */
public class XssFilter extends BaseFilter implements Filter
{
    private static final Log logger = LogFactory.getLog(XssFilter.class);
    
    /**
     * 必须要过滤的URL
     */
    private String[] mustFilterUrlList = null;
    
    /**
     * 不进行过滤的URL
     */
    private String[] notFilterUrlList = null;
    
    /**
     * 需要过滤的关键词
     */
    private String[] filterWordList = null;
    
    /**
     * 包含非法单词,但是整体合法的单词
     */
    private String[] ignorWordList = null;
    
    /**
     * 过滤器入口方法
     * 
     * @param arg0
     * @param arg1
     * @param arg2
     * @throws IOException
     * @throws ServletException
     */
    public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
            throws IOException, ServletException
    {
        HttpServletRequest request = (HttpServletRequest)arg0;
        HttpServletResponse response = (HttpServletResponse)arg1;
        String url = request.getRequestURI();
        
        if (this.ignoreUrlFromWeb(url.replaceAll(request.getContextPath(), "")))
        {
            arg2.doFilter(request, response);
            return;
        }
        url = request.getRequestURI()+"?"+request.getQueryString();
        // 检查url是否必须要过滤掉
        if (this.isUrlMustFilter(url))
        {
           response.setStatus(404);
            return;
        }
        
        // 检查url是否不需要过滤
        if (this.isUrlNotFilter(url))
        {
            // 如果不需要过滤,则执行下一个过滤器
            arg2.doFilter(arg0, arg1);
            return;
        }
        
        // 校验queryString
        String queryString = request.getQueryString();
        if (containsIllegalWord(queryString))
        {
           throw new Exception("invalid request");
        }
        
        // 解析请求参数,并进行参数过滤
        Enumeration<String> params = request.getParameterNames();
        if (null != params)
        {
            // 参数名称
            String paramName = null;
            // 参数值
            String[] paramValues = null;
            while (params.hasMoreElements())
            {
                paramName = params.nextElement();
                paramValues = request.getParameterValues(paramName);
                
                if (null == paramValues)
                {
                    continue;
                }
                
                for (String value : paramValues)
                {
                    if (this.containsIllegalWord(value))
                    {
                        throw new Exception("invalid request");
                    }
                }
            }
        }
        
        
        String type = request.getContentType();
        // 文件上传类型采用的contenttype为multipart/form-data;类型,上传的是文件流,无须校验
        // 如果是普通的form表单提交的,contenttype是非json模式的,不走json获取的参数校验
        if (StringUtils.isBlank(type) || !type.startsWith("application/json"))
        {
            arg2.doFilter(request, arg1);
            return;
        }
        
        ServletRequest requestWrapper = null;
        if (request instanceof HttpServletRequest)
        {
            requestWrapper = new ReaderReuseHttpServletRequestWrapper(request);
        }
        Reader reader = requestWrapper.getReader();
        
        // 读取Request Payload数据
        String payload = IOUtils.toString(reader);
        
        if (StringUtils.isNotBlank(type) && type.startsWith("application/json"))
        {
            parseJSONString(payload, request, response);
        }
        else
        {
            // 解析请求参数,并进行参数过滤
            Enumeration<String> params1 = request.getParameterNames();
            if (null != params1)
            {
                // 参数名称
                String paramName = null;
                // 参数值
                String[] paramValues = null;
                
                while (params1.hasMoreElements())
                {
                    paramName = params1.nextElement();
                    paramValues = request.getParameterValues(paramName);
                    
                    if (null == paramValues)
                    {
                        continue;
                    }
                    
                    for (String value : paramValues)
                    {
                        if (this.containsIllegalWord(value))
                        {
                            throw new Exception("invalid request");
                        }
                    }
                }
            }
        }
        arg2.doFilter(requestWrapper, arg1);
    }
    
    /**
     * 判断url是否必须过滤
     */
    private boolean isUrlMustFilter(String url)
    {
       //配置url白名单以及黑名单,判断是否要处理
    }
    
    /**
     * 判断url是否不需要过滤
     */
    private boolean isUrlNotFilter(String url)
    {
        // 转换为小写字符
        url = url.toLowerCase(Locale.US);
        //配置url白名单以及黑名单,判断是否要处理
        return false;
    }
    
    
    /**
     * 判断字符串是否包含非法关键字
     */
    private boolean containsIllegalWord(String s)
    {
        //判断字符串是否包含非法关键字,正则表达式
    }
    
   
    /**
     * 由于RequestBody是流的形式读取, 那么流读了一次就没有了,所以只能被调用一次。 既然是因为流只能读一次的原因,那么只要将流的内容保存下来,就可以实现反复读取了
     */
    public static class ReaderReuseHttpServletRequestWrapper extends HttpServletRequestWrapper
    {
        
        private final byte[] body;
        
        public ReaderReuseHttpServletRequestWrapper(HttpServletRequest request) throws IOException
        {
            super(request);
            body = IOUtils.toString(request.getReader()).getBytes(Charset.forName("UTF-8"));
        }
        
        @Override
        public BufferedReader getReader() throws IOException
        {
            return new BufferedReader(new InputStreamReader(getInputStream()));
        }
        
        @Override
        public ServletInputStream getInputStream() throws IOException
        {
            final ByteArrayInputStream bais = new ByteArrayInputStream(body);
            return new ServletInputStream()
            {
                
                @Override
                public int read() throws IOException
                {
                    return bais.read();
                }
                
            };
        }
    }
    
    public Object parseJSONString(String jsonString, HttpServletRequest request, HttpServletResponse response)
    {
        JSONArray jsonArray = null;
        JSONObject jsonObj = null;
        System.out.println("入参:"+jsonString);
        if (jsonString.startsWith("["))
        {
            jsonArray = JSONArray.parseArray(jsonString);
            return parseJSONArr(jsonArray, request, response);
        }
        else
        {
            jsonObj = JSONObject.parseObject(jsonString);
            return parseJSONObj(jsonObj, request, response);
        }
        
    }
    
    public Map<String, Object> parseJSONObj(JSONObject jsonObj, HttpServletRequest request,
            HttpServletResponse response)
    {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        if (null == jsonObj)
        {
            return paramMap;
        }
        String val = "";
        Object obj = null;
        for (Map.Entry<String, Object> entry : jsonObj.entrySet())
        {
            val = JSONObject.toJSONString(entry.getValue());
            if (val.startsWith("{") || val.startsWith("["))
            {
                obj = parseJSONString(val, request, response);
                paramMap.put(entry.getKey(), obj);
            }
            else
            {
                if (containsIllegalWord(String.valueOf(entry.getValue())))
                {
                    logger.info("XssFilter filtered invalid input param \"" + entry.getKey() + "\" with values \""
                            + entry.getValue() + "\", and will redirect to error page.");
                    
                    throw new ESysAdminException("invalid request");
                }
                paramMap.put(entry.getKey(), entry.getValue());
            }
        }
        return paramMap;
    }
    
    public List<Object> parseJSONArr(JSONArray jsonArray, HttpServletRequest request, HttpServletResponse response)
    {
        List<Object> paramList = new ArrayList<Object>();
        if (null == jsonArray)
        {
            return paramList;
        }
        
        String val = "";
        Object obj = null;
        Iterator<Object> iterator = jsonArray.iterator();
        while (iterator.hasNext())
        {
            obj = iterator.next();
            val = JSONObject.toJSONString(obj);
            if (val.startsWith("{") || val.startsWith("["))
            {
                paramList.add(parseJSONString(val, request, response));
            }
            else
            {
                if (containsIllegalWord(String.valueOf(obj)))
                {
                    logger.error("XssFilter filtered invalid input param with values \"" + obj
                            + "\", and will redirect to error page.");
                    throw new ESysAdminException("invalid request");
                }
                paramList.add(obj);
            }
        }
        
        return paramList;
    }
 
    /**
     * 初始化过滤器
     */
    public void init(FilterConfig arg0) throws ServletException
    {
        // 解析必须过滤的url
        String must = arg0.getInitParameter("mustFilterUrlList");
        if (StringUtils.isNotBlank(must))
        {
            // 转换中文逗号,并且统一转换为小写字符
            must = must.toLowerCase(Locale.US);
            mustFilterUrlList = must.split(",");
            
            logger.info("init XssFilter with must filter url:" + must);
        }
        
        // 解析不需要过滤的url
        String not = arg0.getInitParameter("notFilterUrlList");
        if (StringUtils.isNotBlank(not))
        {
            not = not.toLowerCase(Locale.US);
            notFilterUrlList = not.split(",");
            
            logger.info("init XssFilter with not filter url:" + not);
        }
        
        // 解析需要过滤关键词配置
        String filterWords = arg0.getInitParameter("filterWords");
        if (StringUtils.isNotBlank(filterWords))
        {
            filterWords = filterWords.trim().toLowerCase(Locale.US);
            filterWordList = filterWords.split(",");
            
            logger.info("init XssFilter with filter words:" + filterWords);
        }
        
        // 解析忽略过滤规则(安全的)关键词配置
        String ignorWords = arg0.getInitParameter("ignorWords");
        if (StringUtils.isNotBlank(ignorWords))
        {
            ignorWords = ignorWords.trim().toLowerCase(Locale.US);
            ignorWordList = ignorWords.split(",");
            
            logger.info("init XssFilter with ignor words:" + ignorWords);
        }
    }
    
    /**
     * 销毁过滤器
     */
    public void destroy()
    {
        this.mustFilterUrlList = null;
        this.notFilterUrlList = null;
        this.filterWordList = null;
        this.ignorWordList = null;
    }
}

XSS 跨站请求攻击过滤器

5.springmvc-servlet.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"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">
    
    <mvc:annotation-driven />
    
    <context:component-scan base-package="com.xxxx"/>
    
    <mvc:default-servlet-handler />
    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/" />
        <!-- 后缀 -->
        <property name="suffix" value=".jsp" />
    </bean>
    
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    	<property name="maxUploadSize" value="20971520"></property>
    </bean>
    
   <!-- <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/mvc/**"/>
            <bean class="com.huawei.springmvc.interceptor.MyInterceptor"></bean>
        </mvc:interceptor>        
    </mvc:interceptors> -->
    
</beans>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值