1. 返回JSON
为什么要返回JSON
前后端分离成为企业应用开发中的主流,前后端分离通过json进行交互,登录成功和失败后不用页面跳转,而是给前端返回一段JSON提示, 前端根据JSON提示构建页面.
需求: 对于登录的各种状态 , 给前端返回JSON数据
1.1 在vo包下创建一个HttpResult对象, 存储返回的信息
vo即 value object值对象, 所有不存储在数据库中的对象就放在vo包下
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class HttpResult {private Integer code;private String msg;private Object data;public HttpResult(Integer code, String msg) {this.code = code;this.msg = msg;}
}
1.2 创建认证(登录)成功处理器AuthenticationSuccessHandler
当且仅当认证(登录)成功后, 该处理器开始工作, 给前端返回一个JSON
@Component
public class MyAuthenticationSuccessHandle implements AuthenticationSuccessHandler {//注入一个序列化器, 可以将JSON序列化, 反序列化@Resourceprivate ObjectMapper objectMapper;@Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {response.setCharacterEncoding("UTF-8");response.setContentType("application/json;charset=utf-8");//借助Lombok实现建造者模式, 并通过建造者模式创建对象HttpResult httpResult = HttpResult.builder().code(1).msg("登陆成功").build();/*与普通new方法一样HttpResult httpResult = new HttpResult(200, "登录成功");*HttpResult中自定义的有参构造方法只写了code和msg,因此data可以选择性传HttpResult httpResult = new HttpResult(200, "登录成功",authentication);*///将对象转化为JSONString responseJson = objectMapper.writeValueAsString(httpResult);PrintWriter writer = response.getWriter();writer.println(responseJson);}
}
在安全配置类中注入登录成功处理器
@Configuration
public class MySSWebSecurityConfig extends WebSecurityConfigurerAdapter {// 注入登陆成功的处理器@Autowiredprivate MyAuthenticationSuccessHandle successHandler;//放开登录页面权限,任何人都能尝试登录,否则登录界面都见不到http.formLogin().permitAll();}
1.3 登录失败处理器 , 无权限处理器都如法炮制
@Resourceprivate ObjectMapper objectMapper;/*** @param request 当前的请求对象* @param response 当前的响应对象* @param exception 失败的原因的异常* @throws IOException* @throws ServletException*/@Overridepublic void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {System.err.println("登陆失败");//设置响应编码response.setCharacterEncoding("UTF-8");response.setContentType("application/json;charset=utf-8");//返回JSON出去HttpResult result=new HttpResult(-1,"登陆失败");//把result序列化为JSON字符串String responseJson = objectMapper.writeValueAsString(result);//响应出去PrintWriter out = response.getWriter();out.write(responseJson);out.flush();}
}
/*** 无权限的处理器*/
@Component
public class AppAccessDeniedHandler implements AccessDeniedHandler {//声明一个把对象转成JSON的对象
@Resourceprivate ObjectMapper objectMapper;@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {//设置响应编码response.setCharacterEncoding("UTF-8");response.setContentType("application/json;charset=utf-8");//返回JSON出去HttpResult result=new HttpResult(-1,"您没有权限访问");//把result转成JSONString json = objectMapper.writeValueAsString(result);//响应出去PrintWriter out = response.getWriter();out.write(json);out.flush();}
}
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {// 注入登陆成功的处理器@Autowiredprivate AutheticationSuccessHandle successHandler;// 注入登陆失败的处理器@Autowiredprivate AppAuthenticationFailureHandler failureHandler;// 注入没有权限的处理器@Autowiredprivate AppAccessDeniedHandler accessDeniedHandler;// 注入退出成功的处理器@Autowiredprivate AppLogoutSuccessHandler logoutSuccessHandler;@Overrideprotected void configure(HttpSecurity http) throws Exception {http.exceptionHandling().accessDeniedHandler(accessDeniedHandler);http.formLogin().successHandler(successHandler).failureHandler(failureHandler).permitAll();http.logout().logoutSuccessHandler(logoutSuccessHandler);http.authorizeRequests().mvcMatchers("/teacher/**").hasRole("teacher").anyRequest().authenticated();}
}