Web笔记

Tomcat

JRE报错

一般教程会让我们配置JAVA_HOMEJRE_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>
// Post请求的表单数据
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); // 正常情况还是转发给默认的Servlet帮我们返回静态页面
}

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

<!-- 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);
}
}