由于尚硅谷的视频是通过Eclipse软件来做的,其中有些操作与IDEA上有所区别,所以我在这里将IDEA区别于Eclipse的操作、操作过程中涉及的源码(与视频的源码略有出入)以及大家可能遇到的种种问题分享给大家,这些源码在我这里均是通过测试的,仅供参考!
1 短信服务 1.1 短信服务测试这部分需要自己去阿里云购买短信服务,每个人的api接口可能都不同,这里只上传我购买api的相关代码,把需要修改的几个地方标注出来的,具体操作请看视频!
修改authentication-consumerpom.xml
junit junit test org.springframework spring-test test org.springframework.boot spring-boot-test test
新建authentication-consumersrctestjavacomaiguigucrowdtestCrowdTest.java
package com.aiguigu.crowd.test;
import com.aliyun.api.gateway.demo.util.HttpUtils;
import org.apache.http.HttpResponse;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.HashMap;
import java.util.Map;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = CrowdTest.class)
public class CrowdTest {
@Test
public void testSendMessage() {
String host = "https://cxkjsms.market.alicloudapi.com";
String path = "/chuangxinsms/dxjk";
String method = "POST";
String appcode = "这部分需要自己填写";
//开通服务后 买家中心-查看AppCode
Map headers = new HashMap();
//最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
headers.put("Authorization", "APPCODE " + appcode);
Map querys = new HashMap();
querys.put("content", "【创信】你的验证码是:5873,3分钟内有效!");
querys.put("mobile", "填写自己手机号");
Map bodys = new HashMap();
try {
HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
System.out.println(response.toString());
//获取response的body
//System.out.println(EntityUtils.toString(response.getEntity()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
新建authentication-consumersrcmainjavacomaliyunapigatewaydemoutilHttpUtils.java
package com.aliyun.api.gateway.demo.util;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.NamevaluePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNamevaluePair;
public class HttpUtils {
public static HttpResponse doGet(String host, String path, String method,
Map headers,
Map querys)
throws Exception {
HttpClient httpClient = wrapClient(host);
HttpGet request = new HttpGet(buildUrl(host, path, querys));
for (Map.Entry e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue());
}
return httpClient.execute(request);
}
public static HttpResponse doPost(String host, String path, String method,
Map headers,
Map querys,
Map bodys)
throws Exception {
HttpClient httpClient = wrapClient(host);
HttpPost request = new HttpPost(buildUrl(host, path, querys));
for (Map.Entry e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue());
}
if (bodys != null) {
List namevaluePairList = new ArrayList();
for (String key : bodys.keySet()) {
namevaluePairList.add(new BasicNamevaluePair(key, bodys.get(key)));
}
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(namevaluePairList, "utf-8");
formEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
request.setEntity(formEntity);
}
return httpClient.execute(request);
}
public static HttpResponse doPost(String host, String path, String method,
Map headers,
Map querys,
String body)
throws Exception {
HttpClient httpClient = wrapClient(host);
HttpPost request = new HttpPost(buildUrl(host, path, querys));
for (Map.Entry e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue());
}
if (StringUtils.isNotBlank(body)) {
request.setEntity(new StringEntity(body, "utf-8"));
}
return httpClient.execute(request);
}
public static HttpResponse doPost(String host, String path, String method,
Map headers,
Map querys,
byte[] body)
throws Exception {
HttpClient httpClient = wrapClient(host);
HttpPost request = new HttpPost(buildUrl(host, path, querys));
for (Map.Entry e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue());
}
if (body != null) {
request.setEntity(new ByteArrayEntity(body));
}
return httpClient.execute(request);
}
public static HttpResponse doPut(String host, String path, String method,
Map headers,
Map querys,
String body)
throws Exception {
HttpClient httpClient = wrapClient(host);
HttpPut request = new HttpPut(buildUrl(host, path, querys));
for (Map.Entry e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue());
}
if (StringUtils.isNotBlank(body)) {
request.setEntity(new StringEntity(body, "utf-8"));
}
return httpClient.execute(request);
}
public static HttpResponse doPut(String host, String path, String method,
Map headers,
Map querys,
byte[] body)
throws Exception {
HttpClient httpClient = wrapClient(host);
HttpPut request = new HttpPut(buildUrl(host, path, querys));
for (Map.Entry e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue());
}
if (body != null) {
request.setEntity(new ByteArrayEntity(body));
}
return httpClient.execute(request);
}
public static HttpResponse doDelete(String host, String path, String method,
Map headers,
Map querys)
throws Exception {
HttpClient httpClient = wrapClient(host);
HttpDelete request = new HttpDelete(buildUrl(host, path, querys));
for (Map.Entry e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue());
}
return httpClient.execute(request);
}
private static String buildUrl(String host, String path, Map querys) throws UnsupportedEncodingException {
StringBuilder sbUrl = new StringBuilder();
sbUrl.append(host);
if (!StringUtils.isBlank(path)) {
sbUrl.append(path);
}
if (null != querys) {
StringBuilder sbQuery = new StringBuilder();
for (Map.Entry query : querys.entrySet()) {
if (0 < sbQuery.length()) {
sbQuery.append("&");
}
if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) {
sbQuery.append(query.getValue());
}
if (!StringUtils.isBlank(query.getKey())) {
sbQuery.append(query.getKey());
if (!StringUtils.isBlank(query.getValue())) {
sbQuery.append("=");
sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8"));
}
}
}
if (0 < sbQuery.length()) {
sbUrl.append("?").append(sbQuery);
}
}
return sbUrl.toString();
}
private static HttpClient wrapClient(String host) {
HttpClient httpClient = new DefaultHttpClient();
if (host.startsWith("https://")) {
sslClient(httpClient);
}
return httpClient;
}
private static void sslClient(HttpClient httpClient) {
try {
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] xcs, String str) {
}
public void checkServerTrusted(X509Certificate[] xcs, String str) {
}
};
ctx.init(null, new TrustManager[] { tm }, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx);
ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = httpClient.getConnectionManager();
SchemeRegistry registry = ccm.getSchemeRegistry();
registry.register(new Scheme("https", 443, ssf));
} catch (KeyManagementException ex) {
throw new RuntimeException(ex);
} catch (NoSuchAlgorithmException ex) {
throw new RuntimeException(ex);
}
}
}
测试:运行testSendMessage(),可收到短信:
1.2 加入项目修改utilsrcmainjavacomatguigucrowdutilCrowdUtil.java
public static ResultEntity2 前往注册界面 2.1 创建view-controllersendShortMessage(String phoneNumbers) { String host = "https://cxkjsms.market.alicloudapi.com"; String path = "/chuangxinsms/dxjk"; String method = "POST"; String appcode = "5ed7aeac19cf4c429048a1af7b603055";//开通服务后 买家中心-查看AppCode Map headers = new HashMap (); // 生成验证码 StringBuilder builder = new StringBuilder(); for(int i = 0; i < 4; i++) { int random = (int) (Math.random() * 10); builder.append(random); } String code = builder.toString(); //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105 headers.put("Authorization", "APPCODE " + appcode); Map querys = new HashMap (); querys.put("content", "【创信】你的验证码是:"+ code +",3分钟内有效!"); querys.put("mobile", phoneNumbers); Map bodys = new HashMap (); try { HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys); StatusLine statusLine = response.getStatusLine(); int statusCode = statusLine.getStatusCode(); String reasonPhrase = statusLine.getReasonPhrase(); if(statusCode == 200){ return ResultEntity.successWithData(code); } return ResultEntity.failed(reasonPhrase); } catch (Exception e) { e.printStackTrace(); } return null; }
新建authentication-consumersrcmainjavacomatguigucrowdconfigCrowdWebMvcConfig.java
package com.atguigu.crowd.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CrowdWebMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// 浏览器访问的地址
String urlPath = "/auth/member/to/reg/page.html";
// 目标视图的名称,将来拼接前后缀
String viewName = "member-reg";
// 添加view-controller
registry.addViewController(urlPath).setViewName(viewName);
}
}
2.2 新建注册页面
修改authentication-consumersrcmainresourcestemplatesportal.html
新建authentication-consumersrcmainresourcestemplatesmember-reg.html
2.3 发送验证码
2.3.1 前端部分
修改authentication-consumersrcmainresourcestemplatesmember-reg.html
2.3.2 后端部分
修改utilsrcmainjavacomatguigucrowdconstantCrowdConstant.java
public static final String REDIS_CODE_PREFIX = "REDIS_CODE_PREFIX_";
新建consumersrcmainjavacomatguigucrowdhandlerMemberHandler.java
package com.atguigu.crowd.handler;
import com.atguigu.crowd.api.RedisRemoteService;
import com.atguigu.crowd.config.ShortMessageProperties;
import com.atguigu.crowd.constant.CrowdConstant;
import com.atguigu.crowd.util.CrowdUtil;
import com.atguigu.crowd.util.ResultEntity;
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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.concurrent.TimeUnit;
@Controller
public class MemberHandler {
@Autowired
private ShortMessageProperties shortMessageProperties;
@Autowired
private RedisRemoteService redisRemoteService;
@ResponseBody
@RequestMapping("/auth/member/send/short/message.json")
public ResultEntity sendMessage(@RequestParam("phoneNum") String phoneNum) {
// 1.发送验证码到phoneNum手机
ResultEntity sendMessageResultEntity = CrowdUtil.sendShortMessage(
shortMessageProperties.getHost(),
shortMessageProperties.getPath(),
shortMessageProperties.getMethod(), phoneNum,
shortMessageProperties.getAppCode());
// 2.判断是否发送成功
if (ResultEntity.SUCCESS.equals(sendMessageResultEntity.getResult())) {
// 3.如果成功,则将验证码存入Redis
String code = sendMessageResultEntity.getData();
String key = CrowdConstant.REDIS_CODE_PREFIX + phoneNum;
ResultEntity saveCodeResultEntity = redisRemoteService.setRedisKeyValueRemoteWithTimeout(key, code, 15, TimeUnit.MINUTES);
// 4. 判断是否成功存入 Redis
if (ResultEntity.SUCCESS.equals(saveCodeResultEntity.getResult())) {
return ResultEntity.successWithoutData();
}else {
return saveCodeResultEntity;
}
}else {
return sendMessageResultEntity;
}
}
}
新建authentication-consumersrcmainjavacomatguigucrowdconfigShortMessageProperties.java
package com.atguigu.crowd.config;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@NoArgsConstructor
@AllArgsConstructor
@Data
@Component
@ConfigurationProperties(prefix = "short.message")
public class ShortMessageProperties {
private String host;
private String path;
private String method;
private String appCode;
}
修改authentication-consumersrcmainresourcesapplication.yml
short:
message:
app-code: 5ed7aeac19cf4c429048a1af7b603055
host: https://cxkjsms.market.alicloudapi.com
method: POST
path: /chuangxinsms/dxjk
修改authentication-consumersrcmainjavacomatguigucrowdCrowdMainClass.java
@EnableFeignClients2.3.3 测试
可以正常收到短信,并将映射记录在redis中:
注:1和2由于每个人所购买的api不同,所以代码部分也不尽相同,这部分仅供思路参考,尽量不要随意CV!
另:测试时可能会包ResultEntity类构造器缺失,可通过将lombok类import至utilsrcmainjavacomatguigucrowdutilResultEntity.java来解决:
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor3 用户注册 3.1 SQL存储
在SQLyog给loginacct增加唯一约束:
ALTER TABLE `project_crowd`.`t_member` ADD UNIQUE INDEX (`loginacct`);
修改mysql-providersrcmainjavacomatguigucrowdhandlerMemberProviderHandler.java
@RequestMapping("/save/member/remote")
public ResultEntity saveMember(@RequestBody MemberPO memberPO) {
try {
memberService.saveMember(memberPO);
return ResultEntity.successWithoutData();
} catch (Exception e) {
if (e instanceof DuplicateKeyException)
return ResultEntity.failed(CrowdConstant.MESSAGE_LOGIN_ACCT_ALREADY_IN_USE);
return ResultEntity.failed(e.getMessage());
}
}
并新增saveMember()方法及实现类:
修改mysql-providersrcmainjavacomatguigucrowdserviceimplMemberServiceImpl.java
@Transactional(
propagation = Propagation.REQUIRES_NEW,
rollbackFor = Exception.class,
readonly = false)
@Override
public void saveMember(MemberPO memberPO) {
memberPOMapper.insertSelective(memberPO);
}
修改apisrcmainjavacomatguigucrowdapiMySQLRemoteService.java
@RequestMapping("/save/member/remote")
public ResultEntity saveMember(@RequestBody MemberPO memberPO);
3.2 测试
使用Postman,设置POST地址:
http://localhost:2000/save/member/remote
请求头:
Content-Type:application/json;charset=UTF-8
请求体:
{
"loginacct":"Heygo",
"userpswd":123123
}
再次提交:
查看SQLyog:
3.3 auth-consumer修改authentication-consumersrcmainresourcestemplatesmember-reg.html
新建authentication-consumersrcmainjavacomatguigucrowdhandlerMemberHandler.java
@Autowired
private MySQLRemoteService mySQLRemoteService;
@RequestMapping("/auth/do/member/register")
public String register(MemberVO memberVO, ModelMap modelMap) {
// 1.获取用户输入的手机号
String phoneNum = memberVO.getPhoneNum();
// 2.拼接Redis中存储的Key
String key = CrowdConstant.REDIS_CODE_PREFIX + phoneNum;
// 3.从Redis读取Key对应的value
ResultEntity resultEntity = redisRemoteService.getRedisStringValueByKeyRemote(key);
// 4.检查查询操作是否有效
String result = resultEntity.getResult();
if (ResultEntity.FAILED.equals(result)) {
modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, resultEntity.getMessage());
return "member-reg";
}
String redisCode = resultEntity.getData();
if (redisCode == null) {
modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_NOT_EXISTS);
return "member-reg";
}
// 5.能从Redis查询到,则比较两者是否一致
String formCode = memberVO.getCode();
if (!formCode.equals(redisCode)) {
modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_INVALID);
return "member-reg";
}
// 6.一致,将value从Redis中删除
ResultEntity removeResultEntity = redisRemoteService.removeRedisKeyRemote(key);
// 7.执行密码加密
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
String userpswdBeforeEncode = memberVO.getUserpswd();
String userpswdAfterEncode = passwordEncoder.encode(userpswdBeforeEncode);
memberVO.setUserpswd(userpswdAfterEncode);
// 8. 执行保存
MemberPO memberPO = new MemberPO();
BeanUtils.copyProperties(memberVO, memberPO);
ResultEntity saveMemberResultEntity = mySQLRemoteService.saveMember(memberPO);
if (ResultEntity.FAILED.equals(saveMemberResultEntity)) {
modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, saveMemberResultEntity.getMessage());
return "member-reg";
}
return "redirect:/auth/member/to/login/page";
}
修改utilsrcmainjavacomatguigucrowdconstantCrowdConstant.java
public static final String MESSAGE_CODE_NOT_EXISTS = "验证码已过期!请检查手机号是否正确或重新发送!"; public static final String MESSAGE_CODE_INVALID = "验证码不正确!";
修改authentication-consumersrcmainresourcesapplication.yml
ribbon: ConnectTimeout: 10000 # 连接超时时间(ms) ReadTimeout: 10000 # 通信超时时间(ms)
修改authentication-consumersrcmainjavacomatguigucrowdconfigCrowdWebMvcConfig.java
registry.addViewController("/auth/member/to/login/page").setViewName("member-login");
新建authentication-consumersrcmainresourcestemplatesmember-login.html
不用写东西,先完成下列测试
3.4 测试输入正确验证码后,进入创建的login界面:
注册后可在SQLyog中查询到数据:
如果输入错误手机号:
如果输入错误验证码:
如果输入同样的登录账号:
4 用户登录 4.1 前端部分修改authentication-consumersrcmainresourcestemplatesmember-login.html
修改authentication-consumersrcmainresourcestemplatesportal.html
新建entitysrcmainjavacomatguigucrowdentityvoMemberLoginVO.java
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MemberLoginVO {
private Integer id;
private String username;
private String email;
}
修改authentication-consumersrcmainjavacomatguigucrowdhandlerMemberHandler.java
@RequestMapping("/auth/member/do/login")
public String doLogin(@RequestParam("loginacct") String logincacct,
@RequestParam("userpswd") String userpswd,
ModelMap modelMap,
HttpSession session) {
// 1.调用远程接口查询登录账号
ResultEntity resultEntity = mySQLRemoteService.getMemberPOByLoginAcctRemote(logincacct);
// 2.失败则返回登录页面
if (ResultEntity.FAILED.equals(resultEntity.getResult())) {
modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, resultEntity.getMessage());
return "member-login";
}
MemberPO memberPO = resultEntity.getData();
if (memberPO == null) {
modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_LOGIN_FAILED);
return "member-login";
}
// 3.比较密码
String userpswdDatabase = memberPO.getUserpswd();
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
boolean matches = passwordEncoder.matches(userpswd, userpswdDatabase);
if (!matches) {
modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_LOGIN_FAILED);
return "member-login";
}
// 4.创建MemberLoginVO对象存入Session域
MemberLoginVO memberLoginVO = new MemberLoginVO(memberPO.getId(), memberPO.getUsername(), memberPO.getEmail());
session.setAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER, memberLoginVO);
return "redirect:/auth/member/to/center/page";
}
修改utilsrcmainjavacomatguigucrowdconstantCrowdConstant.java
public static final String ATTR_NAME_LOGIN_MEMBER = "loginMember";
新建authentication-consumersrcmainresourcestemplatesmember-center.html
修改authentication-consumersrcmainjavacomatguigucrowdconfigCrowdWebMvcConfig.java
registry.addViewController("/auth/member/to/center/page").setViewName("member-center");
修改mysql-providersrcmainjavacomatguigucrowdserviceimplMemberServiceImpl.java
// 5.获取结果
if(list == null || list.size() == 0){
return null;
}
return list.get(0);
4.3 测试
如果输入错误的账号或者密码,则提示:
如果输入正确,则进入:
4.4 退出登录修改authentication-consumersrcmainresourcestemplatesmember-center.html
修改authentication-consumersrcmainjavacomatguigucrowdhandlerMemberHandler.java
@RequestMapping("/auth/member/logout")
public String logout(HttpSession session) {
session.invalidate();
return "redirect:/";
}
测试:在点击退出系统后可以退回界面
5 登录状态检查 5.1 Pom配置修改authentication-consumerpom.xml以及zuulpom.xml
5.2 Applicationorg.springframework.boot spring-boot-starter-data-redis org.springframework.session spring-session-data-redis
修改zuulsrcmainresourcesapplication.yml
spring:
application:
name: atguigu-crowd-zuul
redis:
host: 192.168.201.100
session:
store-type: redis
修改zuulsrcmainresourcesapplication.yml
spring:
application:
name: atguigu-crowd-auth
thymeleaf:
prefix: classpath:/templates/
suffix: .html
redis:
host: 127.0.0.1
session:
store-type: redis
5.3 放行静态资源
新建utilsrcmainjavacomatguigucrowdconstantAccessPassResources.java
package com.atguigu.crowd.constant;
import java.util.HashSet;
import java.util.Set;
public class AccessPassResources {
public static final Set PASS_RES_SET = new HashSet<>();
static {
PASS_RES_SET.add("/");
PASS_RES_SET.add("/auth/member/to/reg/page");
PASS_RES_SET.add("/auth/member/to/login/page");
PASS_RES_SET.add("/auth/member/logout");
PASS_RES_SET.add("/auth/member/do/login");
PASS_RES_SET.add("/auth/do/member/register");
PASS_RES_SET.add("/auth/member/send/short/message.json");
}
public static final Set STATIC_RES_SET = new HashSet<>();
static {
STATIC_RES_SET.add("bootstrap");
STATIC_RES_SET.add("css");
STATIC_RES_SET.add("fonts");
STATIC_RES_SET.add("img");
STATIC_RES_SET.add("jquery");
STATIC_RES_SET.add("layer");
STATIC_RES_SET.add("script");
STATIC_RES_SET.add("ztree");
}
public static boolean judgeCurrentServletPathWhetherStaticResource(String servletPath) {
if (servletPath == null || servletPath.length() == 0) {
throw new RuntimeException(CrowdConstant.MESSAGE_STRING_INVALIDATE);
}
String[] split = servletPath.split("/");
String firstLevelPath = split[1];
return STATIC_RES_SET.contains(firstLevelPath);
}
}
5.4 Zuul filter
新建zuulsrcmainjavacomatguigucrowdfilterCrowdAccessFilter.java
package com.atguigu.crowd.filter;
import com.atguigu.crowd.constant.AccessPassResources;
import com.atguigu.crowd.constant.CrowdConstant;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@Component
public class CrowdAccessFilter extends ZuulFilter {
@Override
public boolean shouldFilter() {
// 1.获取RequestContext对象
RequestContext requestContext = RequestContext.getCurrentContext();
// 2.通过RequestContext对象获取当前请求对象( 框架底层是借助 ThreadLocal 从当前线程上获取事先绑定的 Request 对象)
HttpServletRequest request = requestContext.getRequest();
// 3.获取 servletPath 值
String servletPath = request.getServletPath();
// 4.根据 servletPath 判断当前请求是否对应可以直接放行的特定功能
boolean containsResult = AccessPassResources.PASS_RES_SET.contains(servletPath);
// 如果当前请求是可以直接放行的特定功能请求则返回 false 放行
if (containsResult){
return false;
}
// 5.判断当前请求是否为静态资源
return !AccessPassResources.judgeCurrentServletPathWhetherStaticResource(servletPath);
}
@Override
public Object run() throws ZuulException {
// 1.获取当前请求对象
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
// 2.获取当前Session对象
HttpSession session = request.getSession();
// 3.尝试从 Session 对象中获取已登录用户
Object loginMember = session.getAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER);
// 4.判断 loginMember 是否为空
if (loginMember == null) {
// 5.从requestContext对象中获取Response对象
HttpServletResponse response = requestContext.getResponse();
// 6.将提示消息存入session域
session.setAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_ACCESS_FORBIDDEN);
// 7.重定向到 auth-consumer 工程中的登录页面
try {
response.sendRedirect("/auth/member/to/login/page");
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
}
5.5 其余改动
修改authentication-consumersrcmainresourcestemplatesmember-login.html
5.6 测试在这里显示登录失败的提示消息
直接输入http://localhost/auth/member/to/login/page或者http://localhost:4000/auth/member/to/login/page,均会被弹出并显示:




