服务器响应:.m.m.a.ExceptionHandlerExceptionResolver:已解决[java.lang.NullPointerException]

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

我正在构建一个用户登录页面。当我输入正确的用户手机和密码时,服务器返回以下空指针异常(如下)。从 GlobalExceptionHandler 打印“其他异常”

.m.m.a.ExceptionHandlerExceptionResolver:已解决 [java.lang.NullPointerException] enter image description here

此外,LoginController 下的 public RespBean doLogin(@Valid LoginVo loginVo, HttpServletRequest request, HttpServletResponse response) 函数也不会运行。 (System.out.println(“LoginController doLogin running”);不会打印出来)。空指针异常发生在从服务器接收到手机和密码之前。

在添加 HttpServletRequest 请求、HttpServletResponse 响应作为函数的输入之前,用户登录工作正常,并且 doLogin 函数得到完整执行。添加这两个输入后,出现空指针异常。

我能否获得一些有关如何识别导致空指针异常的原因的指导?

登录.html

<!DOCTYPE HTML>
<html lang = "en"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Login</title>


    <!-- jquery -->
    <script type="text/javascript" th:src="@{/js/jquery.min.js}"></script>
    <!-- bootstrap -->
    <link rel="stylesheet" type="text/css" th:href="@{/bootstrap/css/bootstrap.min.css}" />
    <script type="text/javascript" th:src="@{/bootstrap/js/bootstrap.min.js}"></script>
    <!-- jquery-validator -->
    <script type="text/javascript" th:src="@{/jquery-validation/jquery.validate.min.js}"></script>
    <script type="text/javascript" th:src="@{/jquery-validation/localization/messages_zh.min.js}"></script>
    <!-- layer -->
        <!-- pop ups-->
    <script type="text/javascript" th:src="@{/layer/layer.js}"></script>
    <!-- md5.js -->
    <script type="text/javascript" th:src="@{/js/md5.min.js}"></script>
    <!-- common.js -->
    <script type="text/javascript" th:src="@{/js/common.js}"></script>

    <style type="text/css">
        html,body{
            height:100%;
            width:100%;
        }
        body{
            background:url('@{/img/bg.jpg}') no-repeat;
            background-size:100% 100%;
            padding-top:100px;
        }
    </style>

</head>
<body>

<form name="loginForm" id="loginForm" method="post"  style="width:50%; margin:0 auto;">

    <h2 style="text-align:center; margin-bottom: 20px">User Login</h2>

    <div class="form-group">
        <div class="row">
            <label class="form-label col-md-4">Please input your mobile number</label>
            <div class="col-md-5">
                <!-- mobile len requirement 11 digits-->
                <input id="mobile" name = "mobile" class="form-control" type="text" placeholder="mobile-number" required="true"  minlength="11" maxlength="11" />
            </div>
            <div class="col-md-1">
            </div>
        </div>
    </div>

    <div class="form-group">
        <div class="row">
            <label class="form-label col-md-4">Please input your password</label>
            <div class="col-md-5">
                <!-- password len requirement 6-16 digits-->
                <input id="password" name="password" class="form-control" type="password"  placeholder="password" required="true" minlength="6" maxlength="16" />
            </div>
        </div>
    </div>

    <div class="row" style="margin-top:40px;">
        <div class="col-md-5">
            <button class="btn btn-primary btn-block" type="reset" onclick="reset()">reset</button>
        </div>
        <div class="col-md-5">
            <button class="btn btn-primary btn-block" type="submit" onclick="login()">login</button>
        </div>
    </div>

</form>
</body>
<script>


    function login(){
        // validate content in the table first, after validation passes, call doLogin function
        $("#loginForm").validate({
            submitHandler:function(form){
                doLogin();
            }
        });
    }
    function doLogin(){
        g_showLoading();

        //get password input from user and do the first MD5 encoding
        var inputPass = $("#password").val();
        var salt = g_passsword_salt;
        var str = "" + salt.charAt(0) + salt.charAt(2) + inputPass + salt.charAt(5) + salt.charAt(4);
        var password = md5(str);

        $.ajax({
            url: "/login/doLogin",
            type: "POST",
            data:{
                mobile:$("#mobile").val(),
                password: password
            },
            success:function(data){

                layer.closeAll();
                if(data.code == 200){
                    layer.msg("login successful");
    
                    window.location.href="/goods/toList";
                }else{
                    layer.msg("something wrong")
                    layer.msg(data.message); // data.msg won't work
                }
            },
            error:function(){
                layer.closeAll();
            }
        });
    }
</script>
</html>

LoginController.java

package com.xxxx.seckill.controller;

import com.xxxx.seckill.service.IUserService;
import com.xxxx.seckill.vo.LoginVo;
import com.xxxx.seckill.vo.RespBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

@Controller
//should not use RestController, should use Controller; RestController will add response body to all methods under this class, will return a body, not jumping to another page
@RequestMapping("/login")
@Slf4j //lombok, for logging output e.g. log infor, log warning, log error
public class LoginController {

    @Autowired
    private IUserService userService;

    @RequestMapping("/toLogin") //to log in page 跳转登录页
    public String toLogin(){
        return "login";
    }

    
    @RequestMapping("/doLogin")
    @ResponseBody
    //公用返回对象 response bean, to return response bean, need to @ResponseBody
    public RespBean doLogin(@Valid LoginVo loginVo, HttpServletRequest request, HttpServletResponse response) {
        System.out.println("LoginController doLogin running");
        // 接受传参 receive parameter from users with LoginVo
        log.info("{}", loginVo); //log can be used directly as it is included in Slf4j
        return userService.doLogin(loginVo, request, response);
//        return null;
    }
}

用户服务 doLogin 函数不会被执行。 System.out.println 都没有被打印。

public interface IUserService extends IService<User> {


    RespBean doLogin(LoginVo loginVo, HttpServletRequest request, HttpServletResponse response);

}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public RespBean doLogin(LoginVo loginVo, HttpServletRequest request, HttpServletResponse response) {
        System.out.println("userService doLogin");
        String mobile = loginVo.getMobile();
        String password = loginVo.getPassword();


        // find user with mobile
        User user = userMapper.selectById(mobile);
        System.out.println("user is not null, user mapper injected");
        if (null == user) {
            System.out.println("user doesn't exist");
            throw new GlobalException(RespBeanEnum.LOGIN_ERROR);
        }

        // verify whether user password is correct
        if (!MD5Util.frontPassToDBPass(password, user.getSalt()).equals(user.getPassword())) {

            System.out.println("wrong password");
            throw new GlobalException(RespBeanEnum.LOGIN_ERROR);

        }
        System.out.println("generating cookie");
        //generate cookie
        String ticket = UUIDUtil.uuid();
        request.getSession().setAttribute(ticket, user);
        CookieUtil.setCookie(request, response, "userTicket", ticket);
        return RespBean.success();
    }
}

全局异常处理程序


@RestControllerAdvice // will return a response body
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public RespBean ExceptionHangler(Exception e) {
        if (e instanceof GlobalException) {
            System.out.println("GlobalException");
            GlobalException ex = (GlobalException) e;
            return RespBean.error(ex.getRespBeanEnum());
        } else if (e instanceof BindException) {
            System.out.println("BindException");
            BindException ex = (BindException) e;
            RespBean respBean = RespBean.error(RespBeanEnum.BIND_ERROR);
            respBean.setMessage("Validation error: " + ex.getBindingResult().getAllErrors().get(0).getDefaultMessage());
            return respBean;
        }
        System.out.println("Other Exception");
        return RespBean.error(RespBeanEnum.ERROR);

    }
}

我尝试在IDEA中重建项目。我添加了所有这些 system.out.println 来确定原因。除了 GlobalExceptionHandler 中的“其他异常”之外,没有打印任何 system.out.println。

java spring-boot authentication servlets nullpointerexception
1个回答
0
投票

我想通了。空指针异常来自public RespBean doLogin(@Valid LoginVo loginVo, HttpServletRequest request, HttpServletResponse response)中的loginVo = null。如果没有“@Valid”,程序运行正常。所以问题发生在验证/异常处理过程中。我意识到 ExceptionHangler(Exception e) 中有一个类型。应该是“异常处理程序”。 ExceptionHandler 和 ControllerAdvice 等注释使用反射来发现和应用类中定义的功能。这些注释依赖正确命名的方法来处理特定的异常。

© www.soinside.com 2019 - 2024. All rights reserved.