有2天没有写diary report了,由于这几天都在火车上颠簸。上个星期五晚上9点的火车从广州到武汉,星期日在学校考试,而后晚上9点的火车又匆忙的赶回广州。今天是8点30赶到的广州,很累。今天老大给我布置了一个新的Task,实现FastDFS的集群和负载均衡。看来今天是要加班的,FastDFS对我来讲是一个未知的领域,Spring Security 和 Filter、Interceptor的demo尚未写出来。(目测又要delay)个人时间计划表是天天6点30起床,晚上加班到10点(正常是6点),笨鸟先飞。html
###What did you do todayjava
可插拔性,在软件系统的设计中,可插拔是一个重要特性。它意味着给系统添加新功能的时候(或者将原来功能的实现替换成新的实现而保持接口不变),不改变系统已有的功能。web
CMD (Common Module Definition):公共模块定义,对于模块的依赖,CMD是延迟执行,推崇依赖就近。spring
今天安装VMware Workstation,这个玩意大学上嵌入式的时候用过(设置ip和掩码:ifconfig eth0 192.168.1.2 netmask 255.255.255.0就是这样用,设置的ip是一次性,重启虚拟机后就失效, 设置网关:route add default gw 192.168.1.1),但是在我本身的笔记本我一直用Virtural Box。用起来Vmware还真不习惯,首先遇到一个问题就是虚拟机ping不一样主机(真尼玛蛋疼),因此记录一下。vim
进入虚拟机设置,把网络链接设置为桥接模式。 tomcat
点“高级”按钮,记录咱们的MAC地址00:0C:29:67:76:2F bash
若是/etc/sysconfig/network-scripts目录没有ifcfg-eth0文件,那么咱们就建立ifcfg-eth0文件,cd /etc/sysconfig/network-scripts, touch ifcfg-eth0网络
vi ifcfg-eth0 ,对这个文件进行编辑。具体的编辑内容能够参考图片。 session
vi /etc/resolv.conf 进入resolv.conf文件设置dns。 mvc
vim /etc/rc.d/rc.local,配置ifup eth0,让开始时重启eth0。
重启网络服务,service network restart
咱们满怀期待的输入ping 192.168.12.61(这个是主机地址),而后结果啪啪啪打脸,根本就ping不通嘛。
左思右想一下,发现是本地防火墙开启的问题,那么咱们关掉防火墙再试一试。果真是防火墙的问题,草他妈。
咱们本地的防火墙确定不能关闭,那么有没有一种策略,能实现虚拟机ping通主机同时又保证本地防火墙保持开启状态呢?确定是有的,打开Windows防火墙,找到高级设置。
咱们在入站规则中找到“文件和打印机共享(回显请求 - ICMPv4-In)”,而后启动该规则便可解决问题。
可是咱们又发现一个问题,咱们ping不通www.baidu.com,这个问题就很操蛋了。
咱们只须要把nameserver 设置为 114.114.114.114就能解决虚拟机ping不通外网的问题。
关于<mvc:annotation-driven />这个问题,咱们接着上一篇博客讲,我上一篇博客的观点出自于使用@Controller注解为何要配置<mvc:annotation-driven />,这篇博客做者的观点是"要使用spring mvc中的@Controller注解,就必需要配置<mvc:annotation-driven />,不然org.springframework.web.servlet.DispatcherServlet没法找到控制器并把请求分发到控制器。" 当我刚开始学习SpringMVC的时候,就看过这篇文章,这篇文章某些观点的确解决了个人一些开发问题,可是我上面列举的做者观点就错的有点离谱。 下面我就用代码去证实这个观点是错的!
@RequestMapping("/mvc")
@Controller
public class MvcAnnotationDrivenTestController {
@RequestMapping(value = "/testMvcAnnotationDriven", method = RequestMethod.GET)
public ModelAndView testMvcAnnotationDriven() {
return new ModelAndView("mvc_annotation_driven_test");
}
}
复制代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>mvc_annotation_driven_test</title>
</head>
<body>
hello, this is mvc_annotation_driven_test
</body>
</html>
复制代码
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping("/interceptor1")
public String testInterceptor1(HttpSession session) {
session.setAttribute("test1", "interceptor1");
session.invalidate();
return "testInterceptor1";
}
@GetMapping("/interceptor2")
public String testInterceptor2(HttpSession session) {
session.setAttribute("test2", "interceptor2");
session.invalidate();
return "testInterceptor2";
}
}
复制代码
* 会抛出"[20:02:37:859] [WARN] - org.springframework.web.servlet.DispatcherServlet.noHandlerFound(DispatcherServlet.java:1176) - No mapping found for HTTP request with URI [/test/interceptor1] in DispatcherServlet with name 'filter_interceptor_mvc'"这个错误,形成404。
复制代码
<mvc:annotation-driven /> is actually rather pointless. It declares explicit support for annotation-driven MVC controllers (i.e.@RequestMapping, @Controller, etc), even though support for those is the default behaviour.
复制代码
My advice is to always declare <context:annotation-config>, but don't bother with <mvc:annotation-driven /> unless you want JSON support via Jackson. 复制代码
我想上面的解释能解开大家心中的疑惑。美滋滋!
接下来的篇幅会讲Listener、Filter、Interceptor的demo(终于能够还债了)。
@Slf4j
public class TestInterceptor1 extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("TestInteceptor1 preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("TestInterceptor1 postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info("TestInterceptor1 afterCompletion");
}
}
复制代码
@Slf4j
public class TestInterceptor2 extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("TestInterceptor2 preHandle");
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("TestInterceptor2 postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info("TestInterceptor2 afterCompletion");
}
}
复制代码
@Slf4j
public class TestFilter1 extends OncePerRequestFilter {
private String username;
private String password;
public TestFilter1() {}
public TestFilter1(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
log.info("TestFilter1 doFilterInternal started, username = {} , password = {} ", username, password);
filterChain.doFilter(httpServletRequest, httpServletResponse);
log.info("TestFilter1 doFilterInternal end, username = {} , password = {}", username, password);
}
}
复制代码
@Slf4j
public class TestFilter2 extends OncePerRequestFilter {
private String username;
private String password;
public TestFilter2() {}
public TestFilter2(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
log.info("TestFilter2 doFilterInternal started");
filterChain.doFilter(httpServletRequest, httpServletResponse);
log.info("TestFilter2 doFilterInternal end");
}
}
复制代码
@Slf4j
public class ContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
log.info("context initialized");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
log.info("context destroyed");
}
}
复制代码
@Slf4j
public class RequesListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
log.info("request destroyed");
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
log.info("request initialized");
}
}
复制代码
@Slf4j
public class RequestAttributeListener implements ServletRequestAttributeListener {
@Override
public void attributeAdded(ServletRequestAttributeEvent servletRequestAttributeEvent) {
log.info("attribute added");
}
@Override
public void attributeRemoved(ServletRequestAttributeEvent servletRequestAttributeEvent) {
log.info("attribute removed");
}
@Override
public void attributeReplaced(ServletRequestAttributeEvent servletRequestAttributeEvent) {
log.info("attribute replaced");
}
}
复制代码
@Slf4j
public class SessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
log.info("session created");
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
log.info("session destroyed");
}
}
复制代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>filter_interceptor</display-name>
<welcome-file-list>
<welcome-file>cmazxiaoma.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:spring-config.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextCleanupListener</listener-class>
</listener>
<listener>
<listener-class>com.cmazxiaoma.demo.listener.ContextListener</listener-class>
</listener>
<listener>
<listener-class>com.cmazxiaoma.demo.listener.RequesListener</listener-class>
</listener>
<listener>
<listener-class>com.cmazxiaoma.demo.listener.RequestAttributeListener</listener-class>
</listener>
<listener>
<listener-class>com.cmazxiaoma.demo.listener.SessionListener</listener-class>
</listener>
<servlet>
<servlet-name>filter_interceptor_mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-servlet.xml</param-value>
</init-param>
<init-param>
<param-name>detectAllHandlerExceptionResolvers</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>filter_interceptor_mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>testFilter1</filter-name>
<filter-class>com.cmazxiaoma.demo.filter.TestFilter1</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>username</param-name>
<param-value>testFilter1</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>123</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>testFilter1</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>testFilter2</filter-name>
<filter-class>com.cmazxiaoma.demo.filter.TestFilter2</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>username</param-name>
<param-value>testFilter2</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>456</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>testFilter2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
复制代码
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/test/interceptor1"/>
<bean class="com.cmazxiaoma.demo.interceptor.TestInterceptor1" />
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/test/interceptor2"/>
<bean class="com.cmazxiaoma.demo.interceptor.TestInterceptor2" />
</mvc:interceptor>
</mvc:interceptors>
复制代码
[21:19:03:666] [INFO] - com.cmazxiaoma.demo.listener.RequesListener.requestInitialized(RequesListener.java:18) - request initialized
[21:19:03:666] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:03:666] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:03:667] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:03:667] [INFO] - com.cmazxiaoma.demo.filter.TestFilter1.doFilterInternal(TestFilter1.java:44) - TestFilter1 doFilterInternal started, username = testFilter1 , password = 123
[21:19:03:667] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:03:667] [INFO] - com.cmazxiaoma.demo.filter.TestFilter2.doFilterInternal(TestFilter2.java:42) - TestFilter2 doFilterInternal started
[21:19:03:680] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:03:680] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:03:680] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:03:681] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:03:681] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:03:681] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:03:685] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:03:686] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:03:686] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:03:691] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:03:691] [INFO] - com.cmazxiaoma.demo.interceptor.TestInterceptor1.preHandle(TestInterceptor1.java:15) - TestInteceptor1 preHandle
[21:19:03:705] [INFO] - com.cmazxiaoma.demo.listener.SessionListener.sessionDestroyed(SessionListener.java:18) - session destroyed
[21:19:03:718] [INFO] - com.cmazxiaoma.demo.interceptor.TestInterceptor1.postHandle(TestInterceptor1.java:22) - TestInterceptor1 postHandle
[21:19:03:718] [INFO] - com.cmazxiaoma.demo.interceptor.TestInterceptor1.afterCompletion(TestInterceptor1.java:27) - TestInterceptor1 afterCompletion
[21:19:03:719] [INFO] - com.cmazxiaoma.demo.filter.TestFilter2.doFilterInternal(TestFilter2.java:44) - TestFilter2 doFilterInternal end
[21:19:03:719] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeRemoved(RequestAttributeListener.java:18) - attribute removed
[21:19:03:719] [INFO] - com.cmazxiaoma.demo.filter.TestFilter1.doFilterInternal(TestFilter1.java:46) - TestFilter1 doFilterInternal end, username = testFilter1 , password = 123
[21:19:03:719] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeRemoved(RequestAttributeListener.java:18) - attribute removed
[21:19:03:719] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeRemoved(RequestAttributeListener.java:18) - attribute removed
[21:19:03:719] [INFO] - com.cmazxiaoma.demo.listener.RequesListener.requestDestroyed(RequesListener.java:13) - request destroyed
复制代码
[21:19:46:054] [INFO] - com.cmazxiaoma.demo.listener.RequesListener.requestInitialized(RequesListener.java:18) - request initialized
[21:19:46:055] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:46:056] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:46:056] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:46:056] [INFO] - com.cmazxiaoma.demo.filter.TestFilter1.doFilterInternal(TestFilter1.java:44) - TestFilter1 doFilterInternal started, username = testFilter1 , password = 123
[21:19:46:056] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:46:057] [INFO] - com.cmazxiaoma.demo.filter.TestFilter2.doFilterInternal(TestFilter2.java:42) - TestFilter2 doFilterInternal started
[21:19:46:057] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:46:057] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:46:058] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:46:058] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:46:059] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:46:059] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:46:059] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:46:060] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:46:060] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:46:061] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeAdded(RequestAttributeListener.java:13) - attribute added
[21:19:46:061] [INFO] - com.cmazxiaoma.demo.interceptor.TestInterceptor2.preHandle(TestInterceptor2.java:15) - TestInterceptor2 preHandle
[21:19:46:061] [INFO] - com.cmazxiaoma.demo.filter.TestFilter2.doFilterInternal(TestFilter2.java:44) - TestFilter2 doFilterInternal end
[21:19:46:062] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeRemoved(RequestAttributeListener.java:18) - attribute removed
[21:19:46:062] [INFO] - com.cmazxiaoma.demo.filter.TestFilter1.doFilterInternal(TestFilter1.java:46) - TestFilter1 doFilterInternal end, username = testFilter1 , password = 123
[21:19:46:062] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeRemoved(RequestAttributeListener.java:18) - attribute removed
[21:19:46:062] [INFO] - com.cmazxiaoma.demo.listener.RequestAttributeListener.attributeRemoved(RequestAttributeListener.java:18) - attribute removed
[21:19:46:063] [INFO] - com.cmazxiaoma.demo.listener.RequesListener.requestDestroyed(RequesListener.java:13) - request destroyed
复制代码
经过对比log和返回的视图,咱们发现了Interceptor1执行了preHandler()、postHandler()、afterCompletion()这三个方法,而Interceptor2只执行了preHandler()这个方法。经过比较它们的源码,咱们发现了Interceptor1的preHandler()返回的是true,而Interceptor2的preHandler()返回的是false。而第一个url咱们拦截了请求,返回了视图,第二个url咱们拦截了请求,返回没有视图。
preHandle方法是进行处理拦截用的,该方法将在Controller处理以前调用,Interceptor拦截器是链式的,而且能够中断,当返回false的时候整个请求结束。
当preHandle返回true时,postHandle()才会执行,在Controller的方法调用以后执行,可是它会在DispatcherServlet进行视图的渲染以前执行。
当preHandle返回ture才会执行,该方法将在整个请求完成以后,也就是DispatcherServlet渲染视完毕才执行,主要做用是情理资源。
从启动日志来看,Listener > Filter > Interceptor > Servlet,自定义Listener和Filter很简单,也不须要讲。
###What to do tomorrow
###Summary
笨鸟先飞