简体   繁体   English

ConcurrentHashMap卡在我的Java Web应用程序的无限循环中吗?

[英]ConcurrentHashMap Stuck in infinite loop in my java web app?

I am new to web development in general but so far am doing basic stuff so I don't know why this doesn't work. 我是Web开发的新手,但到目前为止我正在做一些基本的工作,所以我不知道为什么这不起作用。 My servlet receives a request to add new users to my database, but before that I first want to check the values using regular expressions. 我的servlet收到一个向数据库添加新用户的请求,但是在此之前,我首先要使用正则表达式检查值。

So my idea was to have all the parameter names and regex patterns in a hashmap, and then iterate that map, get the parameter from the request object and return an array(for now) containing only the invalid fields. 因此,我的想法是将所有参数名称和正则表达式模式存储在哈希图中,然后进行迭代,从请求对象中获取参数,并返回仅包含无效字段的数组(目前)。 However, it seems that I might get stuck in an infinite loop because I can't find a different explanation why this doesn't work. 但是,似乎我可能陷入无限循环,因为我找不到其他解释来解释为什么这行不通。

I am not sure if this has anything to do with threads as I will only read it and never modify it at runtime, but I switched from HashMap to Concurrent anyway. 我不确定这是否与线程有关,因为我只会读取它,并且永远不会在运行时对其进行修改,但是无论如何我还是从HashMap切换到Concurrent。 It seemed too simple to go wrong. 看起来太容易出错了。 So here it is: 所以这里是:

public class FormValidator {

    public ArrayList<String> Validate(HttpServletRequest request) {
        ArrayList<String> invalidFields = new ArrayList<String>();
        ConcurrentHashMap<String, String> fieldRegexMap = new ConcurrentHashMap<String, String>();
        fieldRegexMap.put("username", ".{8,}");
        fieldRegexMap.put("email", "(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$)");
        fieldRegexMap.put("password", "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[$@$!%*#?&])[A-Za-z\\d$@$!%*#?&]{8,10}$");
        //fieldRegexMap.put("confirmPassword", "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[$@$!%*#?&])[A-Za-z\\d$@$!%*#?&]{8,10}$");
        fieldRegexMap.put("firstname", ".{1,20}");
        fieldRegexMap.put("lastname", ".{4,20}");
        fieldRegexMap.put("DOB", "^(?:(?:31(\\/|-|\\.)(?:0?[13578]|1[02]))\\1|(?:(?:29|30)(\\/|-|\\.)(?:0?[1,3-9]|1[0-2])\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:29(\\/|-|\\.)0?2\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\\d|2[0-8])(\\/|-|\\.)(?:(?:0?[1-9])|(?:1[0-2]))\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$\\");

        fieldRegexMap.put("city", ".{2,20}");
        fieldRegexMap.put("address", ".{2,20}");
        fieldRegexMap.put("profession", ".{2,20}");
        fieldRegexMap.put("interests", ".{,100}");
        fieldRegexMap.put("moreinfo", ".{,500}");

        //Get all parameters from the request and validate them key:parametername value:regex
        for (Map.Entry<String, String> entry : fieldRegexMap.entrySet()) {
            if (!(request.getParameter(entry.getKey()).matches(entry.getValue()))) {
                invalidFields.add(entry.getKey());
            }

        }

        return invalidFields;
    }
}

Then my servlet's doPost calls ProcessRequest: 然后我的servlet的doPost调用ProcessRequest:

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    try (PrintWriter out = response.getWriter()) {

        ArrayList<String> results = new ArrayList<String>();

        out.println("<h1>Servlet lqRegisterServlet at " + 
        request.getContextPath() + "</h1>");

        out.println("<h2>Method: " + request.getMethod() + "</h2>");
        out.println("This Shows up");

        FormValidator validator = new FormValidator();

        out.println("Everything shows up to this point!");
        results = validator.Validate(request);
        out.println("This does not show");
        for (String param : results) {

            out.println("<p>Field:" + param + "</p>");
        }

    }
    response.getOutputStream().println("This is servlet response");
}

I don't know if this is the best way to check the fields, this is a project for me to learn java web development. 我不知道这是否是检查字段的最佳方法,这是我学习Java Web开发的项目。 But it's the only way I could think of that made sense to me and seemed reusable. 但这是我想到的唯一可行的方法。 I plan to create and populate the hashmap outside the validate function. 我计划在validate函数之外创建并填充哈希图。

Thank you for your time 感谢您的时间

You servlet-call isn't stuck but fails with an error because at least the regular expression for DOB is wrong. 您的Servlet调用不会停滞,但会失败并显示错误,因为至少DOB的正则表达式是错误的。 I found that out by writing a short main method: 我通过写一个简短的main方法发现了这一点:

public static void main(String[] args) {
    ArrayList<String> invalidFields = null;
    ConcurrentHashMap<String, String> fieldRegexMap = new ConcurrentHashMap<String, String>();
    fieldRegexMap.put("username", ".{8,}");
    fieldRegexMap.put("email", "(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$)");
    fieldRegexMap.put("password", "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[$@$!%*#?&])[A-Za-z\\d$@$!%*#?&]{8,10}$");
    //fieldRegexMap.put("confirmPassword", "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[$@$!%*#?&])[A-Za-z\\d$@$!%*#?&]{8,10}$");
    fieldRegexMap.put("firstname", ".{1,20}");
    fieldRegexMap.put("lastname", ".{4,20}");
    fieldRegexMap.put("DOB", "^(?:(?:31(\\/|-|\\.)(?:0?[13578]|1[02]))\\1|(?:(?:29|30)(\\/|-|\\.)(?:0?[1,3-9]|1[0-2])\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:29(\\/|-|\\.)0?2\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\\d|2[0-8])(\\/|-|\\.)(?:(?:0?[1-9])|(?:1[0-2]))\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$\\");

    fieldRegexMap.put("city", ".{2,20}");
    fieldRegexMap.put("address", ".{2,20}");
    fieldRegexMap.put("profession", ".{2,20}");
    fieldRegexMap.put("interests", ".{,100}");
    fieldRegexMap.put("moreinfo", ".{,500}");

    fieldRegexMap.entrySet().stream()
        .forEach(elem -> {
            System.out.println(elem.getKey());
            System.out.println(Pattern.compile(elem.getValue()));
        });
}

This results into the following output: 结果为以下输出:

profession
.{2,20}
password
^(?=.*[A-Za-z])(?=.*\d)(?=.*[$@$!%*#?&])[A-Za-z\d$@$!%*#?&]{8,10}$
firstname
.{1,20}
address
.{2,20}
city
.{2,20}
DOB
Exception in thread "main" java.util.regex.PatternSyntaxException: Unexpected internal error near index 325
^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$\
                                                                                                                                                                                                                                                                                                                                     ^
    at java.util.regex.Pattern.error(Pattern.java:1955)
    at java.util.regex.Pattern.compile(Pattern.java:1702)
    at java.util.regex.Pattern.<init>(Pattern.java:1351)
    at java.util.regex.Pattern.compile(Pattern.java:1028)
    at IntArraySplitter.lambda$0(IntArraySplitter.java:30)
    at IntArraySplitter$$Lambda$1/1995265320.accept(Unknown Source)
    at java.util.concurrent.ConcurrentHashMap$EntrySpliterator.forEachRemaining(ConcurrentHashMap.java:3606)
    at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
    at IntArraySplitter.main(IntArraySplitter.java:28)

The reason why you don't see this is the fact that you already send a response to the client. 之所以看不到它,是因为您已经向客户端发送了响应。 Because the server already returned an HTTP 200 response code it can't change that to HTTP 500 and therefor just closes the connection to the client when reaching this point. 因为服务器已经返回了HTTP 200响应代码,所以它无法将其更改为HTTP 500,因此仅在到达这一点时关闭与客户端的连接。 You should see some error message in the server's log, though. 不过,您应该在服务器日志中看到一些错误消息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM