本周进行了web组件中的filter的学习;
package crud.web; import javax.servlet.*; import javax.servlet.annotation.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import java.io.IOException; @WebFilter("/*") public class LoginFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { HttpServletRequest req = (HttpServletRequest) request; // 判断网页url是否和登陆有关进行放行 String[] urls = {"/login.jsp","/imgs/","/css/","/login","/register.jsp","/res"}; String url = req.getRequestURL().toString(); // 循环判断请求的URL是否需要放行 for (String u : urls) { if (url.contains(u)) { chain.doFilter(request, response); return; } } HttpSession session = req.getSession(); Object user = session.getAttribute("user"); if (user != null) { // 登陆了,继续执行下一个过滤器或Servlet chain.doFilter(request, response); } else { // 未登录,重定向到登录页面,并传递提示信息 req.setAttribute("login_msg","你尚未登录"); req.getRequestDispatcher("/login.jsp").forward(req,response); } } public void init(FilterConfig config) throws ServletException { // 初始化方法,可以在此处进行一些初始化操作 } public void destroy() { // 销毁方法,可以在此处进行一些资源清理操作 } }
@WebFilter("/*"): 通过@WebFilter注解,将该过滤器应用于所有URL。
doFilter方法:在该方法中进行实际的过滤逻辑处理。
首先,将ServletRequest对象强制转换为HttpServletRequest对象,以便获取请求的URL。
然后,定义一个包含需要放行的URL的数组。
接下来,将当前请求的URL与数组中的每个URL进行比较,如果匹配其中任何一个URL,那么直接通过chain.doFilter(request, response)将请求传递给下一个过滤器或Servlet。
如果请求的URL不匹配任何放行的URL,则获取当前会话中的用户对象。
如果用户对象存在(即已登录),则通过chain.doFilter(request, response)继续执行下一个过滤器或Servlet。
如果用户对象不存在(即未登录),则将一个登录提示信息设置到请求属性中,然后使用req.getRequestDispatcher("/login.jsp").forward(req,response)将请求重定向到登录页面。
init方法和destroy方法:分别用于过滤器的初始化和销毁操作,您可以在这两个方法中进行一些特定的初始化或清理操作。
整合了之前的servlet写法进行修改
之前:
import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.IOException; import java.util.List; @WebServlet("/selectAll") public class SelectAll extends HttpServlet { private BrandService service = new BrandService(); @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); String method = request.getParameter("method"); if (method == null) { method = "selectAll"; } switch (method) { case "selectAll": // 调用BrandService的selectAll方法获取所有品牌数据 List<Brand> brands = service.selectAll(); // 将品牌数据设置为请求属性,以便在JSP页面中使用 request.setAttribute("brands", brands); // 转发请求到brand.jsp页面,显示品牌数据 request.getRequestDispatcher("brand.jsp").forward(request, response); break; case "add": // 获取表单提交的品牌名称、公司名称、订购数、描述和状态 String brandName = request.getParameter("brandName"); String companyName = request.getParameter("companyName"); String ordered = request.getParameter("ordered"); String description = request.getParameter("description"); String status = request.getParameter("status"); // 根据获取的数据创建Brand对象 Brand b = new Brand(null, brandName, companyName, Integer.parseInt(ordered), description, Integer.parseInt(status)); // 调用BrandService的add方法将Brand对象添加到数据库 service.add(b); // 重定向到当前Servlet,刷新品牌数据显示 response.sendRedirect(request.getContextPath() + "/selectAll?method=selectAll"); break; } } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // POST请求统一委派给doGet方法处理 this.doGet(request, response); } }
修改后:
import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * 基础的Servlet类,通过URL路径动态调用相应的方法处理请求 */ public class BaseServlet extends HttpServlet { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String uri = request.getRequestURI(); int index = uri.lastIndexOf("/"); String method = uri.substring(index + 1); Class<? extends BaseServlet> cls = this.getClass(); try { // 通过反射获取指定方法对象 Method method1 = cls.getMethod(method, HttpServletRequest.class, HttpServletResponse.class); // 调用方法处理请求 method1.invoke(this, request, response); } catch (NoSuchMethodException e) { // 如果找不到对应的方法,则抛出异常 throw new RuntimeException(e); } catch (InvocationTargetException e) { // 如果调用方法发生异常,则抛出异常 throw new RuntimeException(e); } catch (IllegalAccessException e) { // 如果无法访问方法,则抛出异常 throw new RuntimeException(e); } } }
import com.alibaba.fastjson.JSON; import crud.pojo.Brand; import crud.pojo.PageBean; import crud.service.Brandserv; import crud.service.implBrand; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.IOException; import java.util.List; @WebServlet("/brand/*") public class BrandServlet extends BaseServlet { private Brandserv service = new implBrand(); /** * 查询所有品牌信息 */ public void selectAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<Brand> brands = service.selectAll(); String jsonString = JSON.toJSONString(brands); response.setContentType("text/json;charset=utf-8"); response.getWriter().write(jsonString); } /** * 添加品牌 */ public void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { BufferedReader reader = request.getReader(); String params = reader.readLine(); Brand brand1 = JSON.parseObject(params, Brand.class); service.add(brand1); response.getWriter().write("success"); } /** * 删除品牌 */ public void delete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { BufferedReader reader = request.getReader(); String params = reader.readLine(); String id = JSON.parseObject(params, String.class); service.delete(Integer.parseInt(id)); response.getWriter().write("success"); } }
获取请求的URI
通过最后一个斜杠的索引截取出方法名
使用反射获取当前BaseServlet类的字节码对象
通过反射的getMethod方法查找指定的方法对象,传入HttpServletRequest和HttpServletResponse参数
调用Method对象的invoke方法来执行对应的方法,传入当前BaseServlet实例、HttpServletRequest和HttpServletResponse对象
如果找不到对应的方法,抛出NoSuchMethodException异常
如果调用方法发生异常,抛出InvocationTargetException异常
如果无法访问方法,抛出IllegalAccessException异常