Tomcat
JRE报错
一般教程会让我们配置JAVA_HOME
和JRE_HOME
,然后启动Tomcat;
然而,在JDK9以后,就不默认包含JRE了。
此时,我们使用命令
jlink --module-path jmods --add-modules java.desktop --output jre
生成一个JRE后,启动Tomcat,就会报错:
WARNING: Unknown module: java.rmi specified to --add-opens Exception in thread "main" java.lang.NoClassDefFoundError: java/util/logging/Logger at org.apache.juli.logging.DirectJDKLog.<init>(DirectJDKLog.java:61) at org.apache.juli.logging.DirectJDKLog.getInstance(DirectJDKLog.java:181) at org.apache.juli.logging.LogFactory.getInstance(LogFactory.java:133) at org.apache.juli.logging.LogFactory.getInstance(LogFactory.java:156) at org.apache.juli.logging.LogFactory.getLog(LogFactory.java:211) at org.apache.catalina.startup.Bootstrap.<clinit>(Bootstrap.java:49) Caused by: java.lang.ClassNotFoundException: java.util.logging.Logger at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525) ... 6 more
这时候,只需要把jre文件和JRE_HOME
环境变量删除,Tomcat就能正常启动
Cookies
Remember-me
<div > <label > <input type ="checkbox" placeholder ="记住密码" name ="remember-me" > 记住密码 </label > </div >
Map<String, String[]> reqMap = req.getParameterMap(); if (map.containsKey("remember-me" )){ Cookie cookie_username = new Cookie ("username" , username); cookie_username.setMaxAge(30 ); Cookie cookie_password = new Cookie ("password" , password); cookie_password.setMaxAge(30 ); resp.addCookie(cookie_username); resp.addCookie(cookie_password); }
@Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Cookie[] cookies = req.getCookies(); if (cookies != null ){ String username = null ; String password = null ; for (Cookie cookie : cookies) { if (cookie.getName().equals("username" )) username = cookie.getValue(); if (cookie.getName().equals("password" )) password = cookie.getValue(); } if (username != null && password != null ){ try (SqlSession sqlSession = factory.openSession(true )){ UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = mapper.getUser(username, password); if (user != null ){ resp.sendRedirect("index" ); return ; } } } } req.getRequestDispatcher("/" ).forward(req, resp); }
Session
Session基于Cookies实现。Session使我们能够辨别不同用户的会话。
HttpSession session = req.getSession();session.setAttribute("user" , user); User user = (User) session.getAttribute("user" );
Servlet
一个Servlet的生命周期为:
首先执行构造方法完成 Servlet 初始化
Servlet 初始化后调用 init ()
方法。
Servlet 调用 service()
方法来处理客户端的请求。
Servlet 销毁前调用 destroy()
方法。
最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。
Servlet 用于动态网页响应,使后端数据能够与前端通信。
@WebServlet("/page") public class PageServlet implements Servlet { @Override doGet(req, resp) { ... } }
上传文件
使用commons.io
<dependency > <groupId > commons-io</groupId > <artifactId > commons-io</artifactId > <version > 2.6</version > </dependency >
前端表单设置multipart
<form method ="post" action ="file" enctype ="multipart/form-data" > <div > <input type ="file" name ="test-file" > </div > <div > <button > 上传文件</button > </div > </form >
后端定义Post方法
@MultipartConfig @WebServlet("/file") public class FileServlet extends HttpServlet { @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try (FileOutputStream stream = new FileOutputStream ("/Users/nagocoler/Documents/IdeaProjects/WebTest/test.png" )){ Part part = req.getPart("test-file" ); IOUtils.copy(part.getInputStream(), stream); resp.setContentType("text/html;charset=UTF-8" ); resp.getWriter().write("文件上传成功!" ); } } }
Context
ServeletContext属于整个Web应用程序,全局唯一
ServeltContext context = getServletContext();context.setAttribute("key" , "value" );
Filter
Filter相当于在所有访问前加了一堵墙,来自浏览器的所有访问请求都会首先经过Filter。
只有Filter允许通过的请求,才可以顺利到达Servlet。
@WebFileter("/*") public class MyFilter implements Filter { @Override public void doFilter (req, resp, chain) { ... chain.doFilter(req, res); } }