使用控制器 servlet 过滤使用情况

问题描述 投票:0回答:1

对于带有 JSP 和 servlet 的非常简单的 MVC,过滤器的功能是什么?

下面的示例中有一个控制器 servlet,然后每个 JSP 都呈现出不同的视图。 Servlet 主要与模型(包含用户列表的属性文件)进行交互。但是,

login.jsp
会改变令牌,它是一个会话 bean。

我意识到通常 Spring、facelets 或其他一些框架会发挥作用——我只是在摸索。

servlet使用过滤器是正确的过滤器用法吗?我不确定过滤器将如何在这里发挥作用——除了可以从控制器 servlet 中提取要分派到的 JSP 的“逻辑”并单独存在于过滤器中......?

JSP 不需要访问过滤器,因为所有调度都是通过 servlet 完成的(?)。

servlet:

package net.bounceme.dur.servlets;

import filter.PropertiesReader;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebServlet("/controller")
public class Controller extends HttpServlet {

    private static final Logger log = Logger.getLogger(Controller.class.getName());

    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        log.info("controller processing request..");
        String jsp = dispatcherLogic(request.getSession());
        request.getRequestDispatcher("/WEB-INF/" + jsp).forward(request, response);
    }

    private String dispatcherLogic(HttpSession session) {
        Properties properties = PropertiesReader.getProps();
        MyToken token = (MyToken) session.getAttribute("token");
        if (token != null) {
            token.setAuthenticated(properties.containsValue(token.getName()));
        } else {
            token = new MyToken();
        }
        log.info(token.toString());
        session.setAttribute("token", token);
        if (token.isAuthenticated()) {
            return "success.jsp";
        } else {
            if (token.isAttemptedLogin()) {
                return "fail.jsp";
            } else {
                return "login.jsp";
            }
        }
    }

    private String dispatcherLogic0(HttpSession session) {
        Map<String, String> p = PropertiesReader.getPropsAsMap();
        Enumeration<String> names = session.getAttributeNames();
        for (String s : Collections.list(names)) {
            log.info(s);
        }
        MyToken t = (MyToken) session.getAttribute("token");
        for (String s : p.keySet()) {
            //  t.getName() = p.containsValue(s);
        }
        return "hello.jsp";  //always to hello page for now
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    public String getServletInfo() {
        return "controller";
    }
}

过滤器:

package net.bounceme.dur.filter;

import filter.PropertiesReader;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Properties;
import java.util.logging.Logger;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class AuthenticateFilter implements Filter {

    private static final Logger log = Logger.getLogger(AuthenticateFilter.class.getName());
    private FilterConfig filterConfig = null;

    public AuthenticateFilter() {
    }

    private void doBeforeProcessing(ServletRequest request, ServletResponse response) throws IOException, ServletException {
        log.info("do before processing..");
    }

    private void doAfterProcessing(ServletRequest request, ServletResponse response) throws IOException, ServletException {
        log.info("do after processing");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        log.info("do filter");
    }

    public FilterConfig getFilterConfig() {
        return (this.filterConfig);
    }

    public void setFilterConfig(FilterConfig filterConfig) {
        this.filterConfig = filterConfig;
    }

    @Override
    public void destroy() {
    }

    private void props() {
        log.info("properties file:");
        Properties properties = PropertiesReader.getProps();
        StringBuilder sb = new StringBuilder();
        for (String key : properties.stringPropertyNames()) {
            String value = properties.getProperty(key);
            sb.append("\n" + key + " => " + value);
        }
        log.info(sb.toString());
    }

    @Override
    public void init(FilterConfig filterConfig) {
        log.info("init");

        this.filterConfig = filterConfig;
        if (filterConfig != null) {
            log.info("SessionCheckFilter:Initializing filter");
        } else {
            log.warning("null filterConfig");
        }

        props();

    }

    @Override
    public String toString() {
        if (filterConfig == null) {
            return ("SessionCheckFilter()");
        }
        StringBuilder sb = new StringBuilder("SessionCheckFilter(");
        sb.append(filterConfig);
        sb.append(")");
        return (sb.toString());
    }

    private void sendProcessingError(Throwable t, ServletResponse response) {
        log.info("send processing error");
        String stackTrace = getStackTrace(t);

        if (stackTrace != null && !stackTrace.equals("")) {
            try {
                response.setContentType("text/html");
                try (PrintStream ps = new PrintStream(response.getOutputStream()); PrintWriter pw = new PrintWriter(ps)) {
                    pw.print("<html>\n<head>\n<title>Error</title>\n</head>\n<body>\n"); //NOI18N
                    pw.print("<h1>The resource did not process correctly</h1>\n<pre>\n");
                    pw.print(stackTrace);
                    pw.print("</pre></body>\n</html>"); //NOI18N
                }
                response.getOutputStream().close();
            } catch (Exception ex) {
            }
        } else {
            try {
                try (PrintStream ps = new PrintStream(response.getOutputStream())) {
                    t.printStackTrace(ps);
                }
                response.getOutputStream().close();
            } catch (Exception ex) {
            }
        }
    }

    public static String getStackTrace(Throwable t) {
        String stackTrace = null;
        try {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            t.printStackTrace(pw);
            pw.close();
            sw.close();
            stackTrace = sw.getBuffer().toString();
        } catch (Exception ex) {
        }
        log.warning(stackTrace);
        return stackTrace;
    }

}

登录令牌:

package net.bounceme.dur.servlets;

import java.util.logging.Logger;

public class MyToken {//should probably be immutable...

    private static Logger log = Logger.getLogger(MyToken.class.getName());

    private String name = "nemo";
    private String role = "captain";
    private String password = "abc";
    private boolean authenticated = false;
    private boolean attemptedLogin = false;

    public MyToken() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public boolean isAuthenticated() {
        return authenticated;
    }

    public void setAuthenticated(boolean authenticated) {
        this.authenticated = authenticated;
    }

    public boolean isAttemptedLogin() {
        return attemptedLogin;
    }

    public void setAttemptedLogin(boolean attemptedLogin) {
        this.attemptedLogin = attemptedLogin;
    }

    @Override
    public String toString() {
        return name + authenticated + attemptedLogin;
    }
}
jsp servlets model-view-controller servlet-filters servlet-3.0
1个回答
2
投票

servlet 不与过滤器交互。事实上,它甚至不知道是否使用了过滤器(除了副作用)。顺便说一句,你的

AuthenticateFilter.doFilter
很糟糕。如果您在 Web 应用程序中安装这样的过滤器,它将阻止所有内容,因为它永远不会传递到过滤器链!

过滤器的逻辑如下

servlet container prepares ServletRequest and ServletResponses objects and pass them to a *filter chain*
    first filter optional pre-processing pass down to next in chain
        second filter pre-processing
        ...
            Servlet processing
        ...
        second filter post-processing
    first filter optional post processing
servlet container pass (end of) data to client

doFilter
方法很经典:

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    // optional pre-processing
    // optionaly return immediately to by-pass other filters and servlet processing
    chain.doFilter(request, response); // pass down to next filter or to servlet
                                       //  if last filter in chain
    // optional post-processing
}
© www.soinside.com 2019 - 2024. All rights reserved.