在Spring Boot中,可以通过编写拦截器(Interceptor)来对请求进行拦截与处理。下面是一个简单的拦截器实现示例:
创建一个类并实现HandlerInterceptor接口
public class AuthInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 在请求处理之前进行拦截处理String token = request.getHeader("Authorization");if (StringUtils.isEmpty(token)) {// 如果请求头中没有携带token,则返回错误信息response.setContentType("application/json;charset=UTF-8");response.getWriter().write("{"code":401,"msg":"未授权访问"}");return false;}// 如果token验证通过,则放行return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {// 请求处理之后进行拦截处理}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 请求完成之后进行拦截处理}
} 在Spring Boot配置类中注册拦截器
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {/*** 注册拦截器*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 注册AuthInterceptor拦截器,并设置拦截路径为/api/**registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/api/**");}} 在上面的示例代码中,我们编写了一个名为AuthInterceptor的拦截器,对所有以/api/开头的请求进行拦截,并进行token验证。如果token验证不通过,则返回错误信息,否则放行。
接着,在Spring Boot的配置类WebMvcConfig中,我们通过重写addInterceptors方法来注册AuthInterceptor拦截器,并将其设置拦截路径为/api/。
需要注意的是,在拦截器中可能会有一些资源需要释放,例如数据库连接等,这时可以在afterCompletion方法中进行资源释放操作。
springboot写验证器
在Spring Boot中,可以通过编写验证器(Validator)来对表单数据进行校验。下面是一个简单的验证器实现示例:
创建一个类并实现Validator接口
public class UserValidator implements Validator {/*** 判断当前支持的验证类型*/@Overridepublic boolean supports(Class<?> clazz) {return User.class.equals(clazz);}/*** 执行具体的验证逻辑*/@Overridepublic void validate(Object target, Errors errors) {User user = (User) target;if (StringUtils.isEmpty(user.getUsername())) {// 如果用户名为空,则添加错误信息errors.rejectValue("username", "username.empty");}if (StringUtils.isEmpty(user.getPassword())) {// 如果密码为空,则添加错误信息errors.rejectValue("password", "password.empty");}}
} 在Controller中使用验证器进行表单校验
@RestController
@RequestMapping("/api")
public class UserController {/*** 使用UserValidator验证表单数据*/@PostMapping("/login")public ResponseEntity<String> login(@Validated @RequestBody User user, BindingResult result) {if (result.hasErrors()) {// 如果表单数据不符合要求,则返回错误信息StringBuilder sb = new StringBuilder();result.getAllErrors().forEach(error -> sb.append(error.getDefaultMessage()).append(";"));return ResponseEntity.badRequest().body(sb.toString());}// 如果表单数据验证通过,则进行登录操作// ...return ResponseEntity.ok("登录成功");}
} 在上面的示例代码中,我们创建了一个名为UserValidator的验证器,并在其中实现了对User对象中的username和password字段进行非空校验的逻辑。
接着,在Controller中的login方法中,我们使用@Validated注解将User对象标记为需要进行表单验证的对象,并将BindingResult对象作为参数传入。在方法中先判断BindingResult对象是否存在错误信息,如果存在则说明表单数据不符合要求,返回相应的错误信息;否则说明表单数据验证通过,进行登录操作。
需要注意的是,在使用@Validated注解时需要在Controller类上添加@Validated注解,以启用Spring Boot的表单验证机制。
springboot写权限拦截
在Spring Boot中,可以通过编写拦截器(Interceptor)来对请求进行权限拦截。下面是一个简单的权限拦截器实现示例:
创建一个类并实现HandlerInterceptor接口
public class AuthInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 在请求处理之前进行权限拦截处理String token = request.getHeader("Authorization");if (StringUtils.isEmpty(token)) {// 如果请求头中没有携带token,则返回错误信息response.setContentType("application/json;charset=UTF-8");response.getWriter().write("{"code":401,"msg":"未授权访问"}");return false;}// 获取用户权限,并与当前请求的URL进行比对String permission = getUserPermission(token);String requestUrl = getRequestUrl(request);if (!hasPermission(permission, requestUrl)) {// 如果用户没有访问此URL的权限,则返回错误信息response.setContentType("application/json;charset=UTF-8");response.getWriter().write("{"code":403,"msg":"无权访问"}");return false;}// 如果权限验证通过,则放行return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {// 请求处理之后进行拦截处理}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 请求完成之后进行拦截处理}/*** 获取用户权限*/private String getUserPermission(String token) {// 根据token获取用户信息,包括用户权限// ...return "admin,user";}/*** 判断用户是否有访问此URL的权限*/private boolean hasPermission(String permission, String requestUrl) {// 将用户权限字符串转换为数组,便于比对String[] permissions = permission.split(",");for (String p : permissions) {if (AntPathMatcher.match(p, requestUrl)) {return true;}}return false;}/*** 获取请求的URL*/private String getRequestUrl(HttpServletRequest request) {String url = request.getRequestURI();String contextPath = request.getContextPath();return url.replaceFirst(contextPath, "");}
} 在Spring Boot配置类中注册拦截器
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {/*** 注册拦截器*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 注册AuthInterceptor拦截器,并设置拦截路径为/api/**registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/api/**");}} 在上面的示例代码中,我们编写了一个名为AuthInterceptor的拦截器,对所有以/api/开头的请求进行权限拦截。在拦截器中,我们先获取请求头中携带的token,并根据该token获取到当前用户对应的权限信息。
接着,我们将用户权限字符串转换为数组,遍历数组并使用AntPathMatcher工具类对用户权限和当前请求的URL进行比对,判断用户是否有访问此URL的权限。如果用户没有访问此URL的权限,则返回错误信息;否则说明权限验证通过,放行。
需要注意的是,在使用AntPathMatcher对URL进行比对时,可以使用通配符*和**,其中*匹配任意字符,匹配任意多级目录。例如:
/api/user/* 匹配 /api/user/list、/api/user/add 等URL;
/api/user/** 匹配 /api/user/list、/api/user/detail/1 等URL。
springboot写短信发送
在Spring Boot中,可以通过调用第三方短信服务商提供的接口来实现短信发送功能。下面以阿里云短信服务为例,展示如何在Spring Boot中实现短信发送功能。
添加依赖
在pom.xml文件中添加阿里云SDK依赖:
<dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-core</artifactId><version>4.5.0</version>
</dependency>
<dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-dysmsapi</artifactId><version>1.0.0</version>
</dependency> 添加配置
在application.yml文件中添加阿里云短信服务的相关配置信息:
aliyun:access-key-id: <your-access-key-id>access-key-secret: <your-access-key-secret>sms:sign-name: <your-sms-sign-name>template-code: <your-sms-template-code> 需要将上面的 <your-access-key-id>、<your-access-key-secret>、<your-sms-sign-name> 和 <your-sms-template-code> 分别替换成真正的值。其中,access-key-id 和 access-key-secret 是阿里云账号的访问密钥ID和密钥,sign-name 是在阿里云短信控制台中设置的签名名称,template-code 是在阿里云短信控制台中创建的短信模板ID。
编写发送短信的代码
在需要发送短信的地方,可以使用以下代码来调用阿里云短信服务的API:
@Autowired
private AliyunSmsConfig smsConfig;public void sendSms(String phone, String code) throws ClientException {// Step 1. 初始化DefaultAcsClientIClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", smsConfig.getAccessKeyId(), smsConfig.getAccessKeySecret());DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", "Dysmsapi", "dysmsapi.aliyuncs.com");IAcsClient client = new DefaultAcsClient(profile);// Step 2. 构造请求CommonRequest request = new CommonRequest();request.setMethod(MethodType.POST);request.setDomain("dysmsapi.aliyuncs.com");request.setVersion("2017-05-25");request.setAction("SendSms");// Step 3. 设置请求参数request.putQueryParameter("PhoneNumbers", phone);request.putQueryParameter("SignName", smsConfig.getSignName());request.putQueryParameter("TemplateCode", smsConfig.getTemplateCode());request.putQueryParameter("TemplateParam", "{"code":"" + code + ""}");// Step 4. 发送请求并解析响应CommonResponse response = client.getCommonResponse(request);JSONObject object = JSON.parseObject(response.getData());String codeValue = object.getString("Code");if (!StringUtils.equals(codeValue, "OK")) {throw new RuntimeException("短信发送失败:" + object.getString("Message"));}
} 在上面的示例代码中,我们先通过Autowired注解将阿里云短信服务的配置信息注入到smsConfig变量中,然后调用sendSms方法来发送短信。具体步骤如下:
Step 1. 初始化DefaultAcsClient:创建一个IAcsClient对象,并传入阿里云账号的访问密钥ID和密钥。
Step 2. 构造请求:设置请求的域名、版本号和操作名称。
Step 3. 设置请求参数:设置接收短信的手机号码、短信签名、短信模板ID以及短信模板中的变量值。
Step 4. 发送请求并解析响应:调用IAcsClient对象的getCommonResponse方法发送请求,并将响应结果转换为JSONObject对象进行解析。如果发送成功,则返回的Code值为OK;否则返回的
快捷键
AMapLoader.load({key: "key", // 申请好的Web端开发者Key,首次调用 load 时必填version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15plugins: ["AMap.moveAnimation"], // 需要使用的的插件列表,如比例尺'AMap.Scale'等AMapUI: {// 是否加载 AMapUI,缺省不加载version: "1.1", // AMapUI 版本plugins: [], // 需要加载的 AMapUI ui插件}, const map = new AMap.Map("container", {//设置地图容器idviewMode: "3D", //是否为3D地图模式zoom: 13, //初始化地图级别center: current_position.value, //初始化地图中心点位置mapStyle: "amap://styles/fresh",}) AMap.plugin(["AMap.ToolBar","AMap.Scale","AMap.HawkEye","AMap.Geolocation","AMap.MapType","AMap.MouseTool","AMap.Polyline",],function () {//异步同时加载多个插件// 添加地图插件// map.addControl(new AMap.ToolBar()) // 工具条控件;范围选择控件map.addControl(new AMap.Scale()) // 显示当前地图中心的比例尺// map.addControl(new AMap.HawkEye()) // 显示缩略图// map.addControl(new AMap.Geolocation()) // 定位当前位置// map.addControl(new AMap.MapType()) // 实现默认图层与卫星图,实时交通图层之间切换// 以下是鼠标工具插件const mouseTool = new AMap.MouseTool(map)// mouseTool.rule();// 用户手动绘制折线图,测量距离// mouseTool.measureArea() // 测量面积} // 实例化点标记const marker = new AMap.Marker({icon: "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",position: current_position.value, // 这里我们通过上面的点击获取经纬度坐标,实时添加标记// 通过设置 offset 来添加偏移量offset: new AMap.Pixel(-26, -54),})
//这里监听标注点的点击事件,触发实现动画效果marker.on("click", function () {animationMove()})marker.setMap(map)// 历史轨迹动画function animationMove() {AMap.plugin("AMap.MoveAnimation", function () {var marker,lineArr = [[116.478935, 39.997761],[116.478939, 39.997825],[116.478912, 39.998549],[116.478912, 39.998549],[116.478998, 39.998555],[116.478998, 39.998555],[116.479282, 39.99856],[116.479658, 39.998528],[116.480151, 39.998453],[116.480784, 39.998302],[116.480784, 39.998302],[116.481149, 39.998184],[116.481573, 39.997997],[116.481863, 39.997846],[116.482072, 39.997718],[116.482362, 39.997718],[116.483633, 39.998935],[116.48367, 39.998968],[116.484648, 39.999861],]var map = new AMap.Map("container", {resizeEnable: true,center: [116.397428, 39.90923],zoom: 17,})marker = new AMap.Marker({map: map,position: [116.478935, 39.997761],icon: "https://a.amap.com/jsapi_demos/static/demo-center-v2/car.png",offset: new AMap.Pixel(-13, -26),})// 绘制轨迹var polyline = new AMap.Polyline({map: map,path: lineArr,showDir: true,strokeColor: "#28F", //线颜色// strokeOpacity: 1, //线透明度strokeWeight: 6, //线宽// strokeStyle: "solid" //线样式})var passedPolyline = new AMap.Polyline({map: map,strokeColor: "#AF5", //线颜色strokeWeight: 6, //线宽})marker.on("moving", function (e: any) {passedPolyline.setPath(e.passedPath)map.setCenter(e.target.getPosition(), true)})map.setFitView()marker.moveAlong(lineArr, {// 每一段的时长duration: 500, //可根据实际采集时间间隔设置// JSAPI2.0 是否延道路自动设置角度在 moveAlong 里设置autoRotation: true,})})}}).catch((e) => {console.log(e)})
} AMapLoader.load({"key": "", // 申请好的Web端开发者Key,首次调用 load 时必填"version": "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15"plugins": [] // 需要使用的的插件列表,如比例尺'AMap.Scale'等"AMapUI": { // 是否加载 AMapUI,缺省不加载"version": '1.1', // AMapUI 缺省 1.1"plugins":[], // 需要加载的 AMapUI ui插件},"Loca":{ // 是否加载 Loca, 缺省不加载"version": '1.3.2' // Loca 版本,缺省 1.3.2},
}).then(()=>{window.AMap.xx;window.AMapUI.xx;window.Loca.xx
}); 已加载插件:fastestmirror、langpacks、product-id、search-disabled-repos、subscription-manager
此系统未注册到授权服务器。您可以使用 subscription-manager 注册。
仓库 epel 在配置中列出了多次。
Repodata 已超过两周未更新。安装 yum-cron?或运行:yum makecache fast 未安装组文件。
可能需要运行:yum groups mark convert(参见 man yum)
确定最快的镜像
可用的环境组:最小安装计算节点基础设施服务器文件和打印服务器Cinnamon 桌面MATE 桌面基本 Web 服务器虚拟化主机带 GUI 的服务器GNOME 桌面KDE Plasma Workspaces开发和创意工作站
可用的组:备份客户端基本Cinnamon兼容性库控制台互联网工具开发工具电子邮件服务器教育软件电子实验室Fedora 打包工具字体通用桌面图形管理工具图形创建工具硬件监控实用程序Haskell输入法互联网应用程序KDE 桌面LXQt 桌面传统 UNIX 兼容性MATEMilkymist网络基础设施服务器网络工具办公套件和生产力性能工具科学支持安全工具智能卡支持系统管理系统管理工具技术写作TurboGears 应用程序框架Web 服务器Web Servlet 引擎Xfce
● sshd.service - OpenSSH server daemonLoaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)Active: active (running) since Wed 2023-08-16 01:44:00 CST; 4 months 21 days agoDocs: man:sshd(8)man:sshd_config(5)Main PID: 1306 (sshd)Tasks: 4Memory: 6.7MCGroup: /system.slice/sshd.service├─ 1306 /usr/sbin/sshd -D├─11566 sshd: root@pts/0├─11824 -bash└─22367 systemctl status sshd
加群联系作者vx:xiaoda0423
仓库地址:https://github.com/webVueBlog/JavaGuideInterview