J2EE


log4j

普通输出

public class TestLog4j {
    public static void main(String[] args) {
        System.out.println("跟踪信息");
        System.out.println("调试信息");
        System.out.println("输出信息");
        System.out.println("警告信息");
        System.out.println("错误信息");
        System.out.println("致命信息");
    }
}

log4j日志输出

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;

public class TestLog4j {
    // 基于类的名称获取日志对象
    static Logger logger = Logger.getLogger(TestLog4j.class);
    public static void main(String[] args){
        //进行默认配置
        BasicConfigurator.configure();
        //设置日志输出级别
        logger.setLevel(Level.DEBUG);
        logger.trace("跟踪信息");
        logger.debug("调试信息");
        logger.info("输出信息");
        logger.warn("警告信息");
        logger.error("错误信息");
        logger.fatal("致命信息");
    }
}

输出:

0 [main] DEBUG log4j.TestLog4j  - 调试信息
1 [main] INFO log4j.TestLog4j  - 输出信息
1011 [main] WARN log4j.TestLog4j  - 警告信息
1011 [main] ERROR log4j.TestLog4j  - 错误信息
1011 [main] FATAL log4j.TestLog4j  - 致命信息

配置文件

# log4j.properties
# 设置日志输出的等级为debug,低于debug就不会输出了
# 设置日志输出到两种地方,分别叫做 stdout和 R
log4j.rootLogger=debug, stdout, R

# stdout到控制台
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

# 第二个地方R, 以滚动的方式输出到文件,文件名是example.log,
# 文件最大100k, 最多滚动5个文件
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=example.log

log4j.appender.R.MaxFileSize=100KB
# Keep one backup file
log4j.appender.R.MaxBackupIndex=5

log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n

java

public class TestLog4j {
    static Logger logger = Logger.getLogger(TestLog4j.class);
    public static void main(String[] args) {
        // 采用指定配置文件
        PropertyConfigurator.configure(ClassLoader.getSystemResource("log4j.properties"));
        logger.trace("跟踪信息");
        logger.debug("调试信息");
        logger.info("输出信息");
        logger.warn("警告信息");
        logger.error("错误信息");
        logger.fatal("致命信息");
    }
}

日志

DEBUG [main] (TestLog4j.java:12) - 调试信息
 INFO [main] (TestLog4j.java:13) - 输出信息
 WARN [main] (TestLog4j.java:14) - 警告信息
ERROR [main] (TestLog4j.java:15) - 错误信息
FATAL [main] (TestLog4j.java:16) - 致命信息

文件

image-20210924132012405

也可用xml文件配置。

junit

待测试的函数

public class TestJunit {
    public static int sum(int i,int j) {
        return i+j;
    }
}

测试:

public class TestSum {
    @Before
    public void before() {
        System.out.println("测试前的准备工作,比如链接数据库等等");
    }
    @After
    public void after() {
        System.out.println("测试结束后的工作,比如关闭链接等等");
    }

    @Test
    public void testSum1() {
        int result = TestJunit.sum(2,3);
        Assert.assertEquals(result,5);

        result = TestJunit.sum(2,6);
        Assert.assertEquals(result,8);
    }

    @Test
    public void testSum2() {
        int result = TestJunit.sum(2,6);
        Assert.assertEquals(result,5);
    }
}

image-20210924134221855

Filter

@WebFilter(urlPatterns = "/*")
public class DemoFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
        //Filter一定会随着tomcat的启动自启动。
        System.out.println("DemoFilter init()");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        String ip = req.getRemoteAddr();
        String url = req.getRequestURI().toString();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d = new Date();
        String date = sdf.format(d);
        System.out.printf("%s %s访问了 %s\n",date,ip,url);
        chain.doFilter(req,resp);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}

输出测试:

2021-09-24 16:08:30 0:0:0:0:0:0:0:1访问了 /
2021-09-24 16:08:44 0:0:0:0:0:0:0:1访问了 /listHero
2021-09-24 16:09:21 0:0:0:0:0:0:0:1访问了 /addHero.html

0:0:0:0:0:0:0:1是 ipv6 的表现形式,对应 ipv4 来说相当于127.0.0.1,也就是本机如果项目部署在本机win7系统,访问时是通过 localhost 来访问,用 Java 获取 ip 地址可能会出现该问题,这时获取的 ip 将是 0:0:0:0:0:0:0:1

可以通过request.setCharacterEncoding("UTF-8");正确获取UTF-8编码的中文,但是如果有很多servlet都需要获取中文,那么就必须在每个Servlet中增加这段代码。

有一个简便的办法,那就是通过Filter过滤器进行中文处理 ,那么所有的Servlet都不需要单独处理了。

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        request.setCharacterEncoding("UTF-8");
        chain.doFilter(request, response);
    }

Listener

ServletContextListener

该接口用于监听Web应用的启动与关闭

@WebListener
public class demo implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext application = sce.getServletContext();
        System.out.println("开启web应用用户名字:"+application.getInitParameter("userName"));
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        ServletContext application = sce.getServletContext();
        System.out.println("关闭web应用用户名字:"+application.getInitParameter("userName"));
    }
}

配置xml

<!--    web.xml-->
    <context-param>
        <param-name>userName</param-name>
        <param-value>web项目的初始化参数</param-value>
    </context-param>

output:
开启web应用用户名字:web项目的初始化参数
...

ServletContextAttributeListener

该接口 用于监听ServletContext范围(application)内属性的改变。

ServletRequestListener与ServletRequestAttributeListener

ServletRequestListener用于监听用户请求,而ServletRequestAttributeListener用于监听request范围内属性的变化。

HttpSessionListener与HttpSessionAttributeListener

HttpSessionListener监听用户session的开始与结束,而HttpSessionAttributeListener监听HttpSession范围(session)内的属性的改变。

服务器端为了保存用户的状态而创建的一个特殊的对象(即session对象)。

当浏览器第一次访问服务器时,服务器会创建session对象(该对象有一个唯一的id,一般称之为sessionId),接下来服务器会将sessionId以cookie的方式发送给浏览器。当浏览器再次访问服务器时,会将sessionId发送过来,服务器就可以依据sessionId找到对应的sessinon对象。

参考

log4j

J2EE

配置拦截器(Filter)时把js、css等静态资源拦截解决方案

Java如何使用Listener