zoukankan      html  css  js  c++  java
  • Spring那些不得不知的细节

    1、SpringMVC拦截器的url-pattern和RequestMapping

    案例:

    1 url-pattern为/rest/*
    2 
    3 http请求为:/rest/query/id
    4 
    5 那么requestMapping为:/query/id

    2、post请求方式对MVC控制器的影响

    Post请求的四种ContentType:

    application/x-www-form-urlencoded   常规表单方式提交

    multipart/form-data            带文件上传的表单

    application/json              Json格式文本

    text/xml                  一般文本,例如webservice

    默认情况下大家接收参数用一个pojo,但是它只能接收get请求和post请求的application/x-www-form-urlencoded形式

    如果使用json请求,那么请在参数前面加上@RequestBody

    如果文件上传,请加上@MultiparyFile

    附:json解析配置(jakson2.x)<mvc:annotation-driven>自动注入jakson的bean,转换器是为了保证编码问题

     1 <!-- 处理请求返回json字符串的中文乱码问题 以及映射器、适配器和试图解析器的自动配置-->
     2     <mvc:annotation-driven>
     3         <mvc:message-converters>
     4             <bean class="org.springframework.http.converter.StringHttpMessageConverter">
     5                 <property name="supportedMediaTypes">
     6                     <list>
     7                         <value>application/json;charset=UTF-8</value>
     8                         <value>text/html;charset=UTF-8</value>
     9                     </list>
    10                 </property>
    11             </bean>
    12         </mvc:message-converters>
    13     </mvc:annotation-driven>

     3、web中url-pattern中的 / 与 /* 的问题

    解:首先大家都知道"/*"可以匹配所有url,包括带扩展名的,一般只用在过滤器上。

    而"/"很多人理解成不能拦截带扩展名的,这种理解是错误的!它其实也能拦截“.js”,“.css”,".png"等静态资源的访问。

    看官方文档可知,它是tomcat的默认servlet,当其他的url-pattern匹配不上时都会走这个servlet。它除了能够处理静态资源还能够处理HTTP缓存请求,媒体(音频/视频)数据流和文件下载简历。所以如果我们的项目中配置了"/",会覆盖掉tomcat中的default servlet。


    tomcat服务器的web.xml配置:

    所以当springMVC的前端控制器配置为“/”时,需要在主配置文件中配置放行静态资源。

    4、Spring提供了对properties文件读取的支持

    配置文件加载属性文件:

    <!-- 加载配置文件 -->
        <context:property-placeholder location="classpath:resource/*.properties" />

    配置文件中使用:${propertyName}

     1 <!-- 数据库连接池 -->
     2     <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
     3         destroy-method="close">
     4         <property name="url" value="${jdbc.url}" />
     5         <property name="username" value="${jdbc.username}" />
     6         <property name="password" value="${jdbc.password}" />
     7         <property name="driverClassName" value="${jdbc.driver}" />
     8         <property name="maxActive" value="10" />
     9         <property name="minIdle" value="5" />
    10     </bean>

    Java程序中使用:Spring注解自动注入

    1     @Value("${REDIS_KEY_CONTENT}")
    2     private String REDIS_KEY_CONTENT;

     5、Spring提供的md5加密,以后再也不用手写了

     6、Spring的IOC容器

      1)如果用了SpringMVC,并且容器分别由spring和springMVC管理,那么存在两个容器,MVC容器可以访问spring的,反之不可以。

      2)MVC容器只能访问父容器的bean,不能访问properties属性。如图

    7、SpringMVC中@ResponseBody返回中文乱码问题

    默认处理:不经过视图解析器,而是经过转换器转换后直接输出(加<mvc:annotation-driven />)

    如果遇到Object对象,默认会采用MappingJackson2HttpMessageConverter(这是jakson2.x的),而且编码自动是UTF-8,所以一般不用配置

    如果遇到String对象,默认会采用StringHttpMessageConverter进行解析,但是默认编码是ISO8859-1

    配置如下即可解决

    <!-- 处理请求返回json字符串的中文乱码问题 以及映射器、适配器和试图解析器的自动配置 -->
        <mvc:annotation-driven>
            <mvc:message-converters>
                <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                    <property name="supportedMediaTypes">
                        <list>
                            <<value>text/html;charset=UTF-8</value>
                        </list>
                    </property>
                </bean>
            </mvc:message-converters>
        </mvc:annotation-driven>

    也可以这样,估计是内部自动转换的吧

    <!-- 处理请求返回json字符串的中文乱码问题 以及映射器、适配器和试图解析器的自动配置 -->
        <mvc:annotation-driven>
            <mvc:message-converters>
                <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                    <property name="supportedMediaTypes" value="text/html;charset=UTF-8"/>
                </bean>
            </mvc:message-converters>
        </mvc:annotation-driven>

     8、在Spring启动后执行立马执行某项任务,比如定时任务。

    类似于在系统启动时做操作一样,只不过一个是ServletContextListener,而监听Spring的是InitializingBean

     1 /**
     2  * @Describtion: (执行任务调度). <br/> 
     3  * @date: 2018年6月9日 下午12:46:45 <br/> 
     4  * @author Beats <br/> 
     5  * @version v1.0 <br/>
     6  * @since JDK 1.8
     7  */
     8 @Component
     9 public class SpringContextLisener implements InitializingBean {
    10 
    11     @Autowired ExamStatusScanner examStatusScanner;
    12     
    13     @Override
    14     public void afterPropertiesSet() throws Exception {
    15         //启动
    16         examStatusScanner.run();
    17     }
    18 }

    9、配置在spring项目中随时随地获取已经注册好的Bean。

    某些情况下,一个类内部需要的对象无法通过正常方式注入进去,比如Quartz通过反射加载job,此时job内就无法使用注解注入。

    例外情况代码:

    此时就无法通过xml或者注解来注入了

    解决方案,手动注入,自定义SpringUtil

    1、创建SpringUtil,该类继承ApplicationContextAware

     1 public class SpringUtil implements ApplicationContextAware {
     2 
     3     private static ApplicationContext ac;
     4 
     5     @Override
     6     public void setApplicationContext(ApplicationContext arg0) throws BeansException {
     7         ac = arg0;
     8     }
     9     
    10     public static ApplicationContext getApplicationContext() {
    11         return ac;
    12     }
    13     
    14     /**
    15      * 获取对象
    16      * @param name
    17      * @return Object 一个以所给名字注册的bean的实例
    18      * @throws BeansException
    19      */
    20     public static Object getBean(String beanName) {
    21         Object obj = null;
    22         obj = ac.getBean(beanName);
    23         return obj;
    24     }
    25     
    26     /**
    27      * 如果bean不能被类型转换,相应的异常将会被抛出(BeanNotOfRequiredTypeException)
    28      * @param name       bean注册名
    29      * @param requiredType 返回对象类型
    30      * @return Object 返回requiredType类型对象
    31      * @throws BeansException
    32      */
    33     public static <T> T getBean(String beanName, Class<T> type) {
    34         T obj = null;
    35         obj = ac.getBean(beanName, type);
    36         return obj;
    37     }
    38     
    39     /**
    40      * 如果BeanFactory包含所给名称匹配的bean返回true
    41      * @param name
    42      * @return boolean
    43      */
    44     public static boolean containsBean(String name) {
    45         return ac.containsBean(name);
    46     }
    47     
    48     /**
    49      * 判断注册的bean是singleton还是prototype。
    50      * 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
    51      * @param name
    52      * @return boolean
    53      * @throws NoSuchBeanDefinitionException
    54      */
    55     public static boolean isSingleton(String name) {
    56         return ac.isSingleton(name);
    57     }
    58     
    59     /**
    60      * @param name
    61      * @return Class 注册对象的类型
    62      * @throws NoSuchBeanDefinitionException
    63      */
    64     public static Class<?> getType(String name) {
    65         return ac.getType(name);
    66     }
    67 }

    2、在Spring中注册他,单例模式

    1     <!-- springUtil的创建 ,实现ApplicationContextAware接口 -->
    2     <bean id="springUtil" class="henu.util.SpringUtil" scope="singleton" />

    之后就可以随时调用。

    10、随时随地获取Spring的配置文件键值对

    都知道在spring中可以通过@Value来自动注入资源文件中的键值对信息,但是SpringMVC是无法读取到Spring的资源文件的。

    所以,可以自定义一个工具类,随时随地获取资源文件信息,并且不用写注解。

    1、创建工具类,继承PropertyPlaceholderConfigurer

     1 public class PropertyUtil extends PropertyPlaceholderConfigurer {
     2     private static Map<String,String> propertyMap;
     3 
     4     @Override
     5     protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props) throws BeansException {
     6         super.processProperties(beanFactoryToProcess, props);
     7         propertyMap = new HashMap<String, String>();
     8         for (Object key : props.keySet()) {
     9             String keyStr = key.toString();
    10             String value = props.getProperty(keyStr);
    11             propertyMap.put(keyStr, value);
    12         }
    13     }
    14 
    15     //static method for accessing context properties
    16     public static String getProperty(String name) {
    17         return propertyMap.get(name);
    18     }
    19 }

    2、在配置文件中注册

    是不是很熟悉,跟context:property-placeholder 加载配置文件一样吧

    1     <!-- 自定义配置文件获取 -->
    2     <bean id="propertyConfigurer" class="henu.util.PropertyUtil" scope="singleton">
    3         <property name="location" value="classpath:res.properties"/>
    4         <property name="fileEncoding" value="UTF-8"/>
    5     </bean>

    3、使用:PropertyUtil.getProperty(propName)即可

    11、AOP拦截控制器

    将AOP配置在SpringMVC中即可,因为父子容器关系。

    12、AOP中获取request和response

    1、自动注入

    1     @Autowired
    2     private HttpServletRequest request;
    3 
    4     @Autowired
    5     private HttpServletResponse response;

    2、配置监听器

    1     <listener>
    2         <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    3     </listener>
  • 相关阅读:
    PHP学习笔记之继承(面向对象三大特性之一)
    php学习笔记之封装练习题
    PHP学习笔记---封装(面向对象三大特性之一)
    PHP学习笔记之面向对象(上)
    php学习笔记之数组遍历练习题1
    php学习笔记数组与数据结构1(数组)
    php学习笔记数组与数据结构1(日期时间函数及遇到的问题解决)
    顺序查找和二分法查找
    冒泡排序
    字符串类型的一些操作处理
  • 原文地址:https://www.cnblogs.com/webyyq/p/8886033.html
Copyright © 2011-2022 走看看