对于使用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;
}
}
答案 0 :(得分: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
方法是classicaly:
@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
}