首页 文章 精选 留言 我的

精选列表

搜索[网站开发],共10000篇文章
优秀的个人博客,低调大师

Linux(乌班图 )系统下安装jdk 和eclipse开发IDE

 自己在安装过程中遇到的一些坑记录下来,以及自己的安装过程做记录 1、下载jdk , jdk-8u144-linux-x64.tar.gz 2.下载 eclipse, eclipse-jee-mars-2-linux-gtk-x86_64.tar.gz 3.将jdk解压到 /usr/local/文件夹中 操作步骤: sudo tar zxvf jdk-8u144-linux-x64.tar.gz 4.配置jdk的环境变量,打开 /etc/profile文件(sudo vim /etc/profile),在文件末尾添加下语句: export JAVA_HOME=/usr/local/jdk1.8.0_144/ export JRE_HOME=${JAVA_HOME}/jre export JAVA_BIN=$JAVA_HOME/bin export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin 保存后退出。 使其立即生效:sudo source /etc/profile 查看是否安装成功:java -version 出现 java version "1.8.0_144" Java(TM) SE Runtime Environment (build 1.8.0_144-b01) Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode) 到此时,你在随意打开一个shell窗口,执行java -version命令,如果出现下面的内容,请不要按照提示进行安装 rootzhi@ubuntu:~/opt$ java -version The program 'java' can be found in the following packages: * default-jre * gcj-4.9-jre-headless * gcj-5-jre-headless * openjdk-8-jre-headless * gcj-4.8-jre-headless * openjdk-9-jre-headless Try: sudo apt install <selected package> 这里提示缺少安装包执行命令,但是请不要这么做! sudo apt-get install openjdk-6-jre-headless 5、这是因为乌班图默认安装了OpenJD看,我们想用自己的jdk,不需要默认,所以保险起见,在多执行一步命令,不管有还是没有openJdk先卸载 执行命令 sudo apt-get remove openjdk* 这条命令会卸载所有关于openjdk的东西,卸载的很干净,这样就可以在命令行下使用你自己的java版本了 设置默认jdk(假如有openjdk的话) 由于Ubuntu中可能会有默认的jdk,如openjdk。假如有openjdk的话,所以,为了使默认使用的是我们安装的jdk,还要进行如下工作(可以使用该命令安装其他命令,例如 eclipse)。 执行代码: sudo update-alternatives --install /usr/bin/java java /usr/local/jdk1.8.0_144/bin/java 300 sudo update-alternatives --install /usr/bin/javac javac /usr/local/jdk1.8.0_144/bin/javac 300 通过这一步将我们安装的jdk加入java选择单。 然后执行代码: sudo update-alternatives --config java sudo update-alternatives --config javac 6、最后到etc/目录下,在执行一次 source profile命令 7.安装 eclipse 将其解压到/opt/文件夹中 sudo tar zxvf eclipse-jee-mars-2-linux-gtk-x86_64.tar.gz -C /home/rootzhoukai/opt/ 8.创建eclipse桌面快捷方式图标。 cd 桌面乌班图Desktop目录 sudo touch eclipse.desktop sudo vim eclipse.desktop 输入以下内容: [Desktop Entry] Encoding=UTF-8 Name=Eclipse Coment=Eclipse Exec=/home/rootzhoukai/opt/eclipse/eclipse Icon=/home/rootzhoukai/opt/eclipse/icon.xpm Terminal=false StartupNotify=true Categories=Application;Development; 保存。 执行:sudo chmod u+x eclipse.desktop 将其变为可执行文件. 在桌面打开 eclipse ,结果提示没有安装JDK,JRE环境,明明我们安装过。 解决方法:在/opt/eclipse/文件夹中创建一个指向JRE路径的软链接。 sudo ln -sf $JRE_HOME jre 到此eclipse就全部安装完!

优秀的个人博客,低调大师

iOS开发实战 - 完美解决UIScrollView嵌套滑动手势冲突

我们应该都有用过这个功能,你的朋友微信给你分享了一个淘宝里面的商品链接,然后当你复制这个链接打开淘宝APP的时候,就会弹出一个弹窗,像这样: example.PNG 这个功能想必大家都挺熟悉,受这个启发我们产品也想在我们APP上添加这样一个功能,与这个不一样的是,当我们复制一段网址的时候打开我们的APP会弹出框填一些信息后上传到我们的“资源库”。大体功能就这样,所以记录一下实现的过程。 一、弹窗视图功能 .h中:两个信号一个是确定信号一个是取消信号 两个方法,一个显示一个隐藏方法 1 2 3 4 5 @property(nonatomic,strong)RACSubject*uploadSureSignal; //确定上传信号 @property(nonatomic,strong)RACSubject*hideSucSignal; //隐藏 -( void )show; -( void )hide; .m中:主要是两个textview,还有涉及到在keywindow上,IQKeyboard的一些操作 1 2 3 @property(nonatomic,assign)CGFloatkeyboardHeight; //键盘高度 @property(nonatomic,strong)CustomUITextView*nameTV; @property(nonatomic,strong)CustomUITextView*desTV; 因为发现IQKeyboard在这个弹出界面有问题,所以在显示这个界面的时候,将IQKeyboard禁用取之使用系统的keyboard监听方法 在(void)show方法中: 1 2 3 4 5 6 7 8 -( void )show{ //键盘通知 NSNotificationCenter*defaultCenter=[NSNotificationCenterdefaultCenter]; [defaultCenteraddObserver:selfselector:@selector(keyboardWillShowOrHide:)name:UIKeyboardWillShowNotificationobject:nil]; [defaultCenteraddObserver:selfselector:@selector(keyboardWillShowOrHide:)name:UIKeyboardWillHideNotificationobject:nil]; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 //监听方法 -( void )keyboardWillShowOrHide:(NSNotification*)notification{ //获取通知名 NSString*notificationName=notification.name; //获取通知内容 NSDictionary*keyboardInfo=notification.userInfo; //键盘弹出时,让画面整体稍稍上移,并伴随动画 //键盘回收时反之 CGRectkeyboardFrame=[notification.userInfo[UIKeyboardFrameEndUserInfoKey]CGRectValue]; CGFloatheight=keyboardFrame.size.height; self.keyboardHeight=height; //动画结束后self.view的frame值 CGRectselfViewFrame=self.bgView.frame; //通过通知名字判断弹出还是回收 if ([notificationNameisEqualToString:UIKeyboardWillShowNotification]){ selfViewFrame.origin.y=SCREEN_HEIGHT-PANELHEIGHT-height; } else { selfViewFrame.origin.y=SCREEN_HEIGHT-PANELHEIGHT; } //取出动画时长 NSTimeIntervalduration=[keyboardInfo[UIKeyboardAnimationDurationUserInfoKey]doubleValue]; //使用动画更改self.view.frame [UIViewanimateWithDuration:durationanimations:^{ //这里填入一些view的最终状态属性设置,即会自动产生过渡动画 self.bgView.frame=selfViewFrame; }]; } 同时在show方法中显示keyWindow,进而改变界面的frame进行显示 1 2 3 4 5 6 7 8 9 10 -( void )show{ UIWindow*keyWindow=[UIApplicationsharedApplication].keyWindow; [keyWindowaddSubview:self]; CGRectframe=self.bgView.frame; if (frame.origin.y==SCREEN_HEIGHT){ frame.origin.y=SCREEN_HEIGHT-PANELHEIGHT; [UIViewanimateWithDuration: 0.4 animations:^{ self.bgView.frame=frame; }]; } hide方法这里要考虑到键盘弹出后将self.bgView向上提高后frame的变化。 1 2 3 4 5 6 7 8 9 10 11 12 13 CGRectselfFrame=self.bgView.frame; if (selfFrame.origin.y==SCREEN_HEIGHT-PANELHEIGHT||selfFrame.origin.y==SCREEN_HEIGHT-PANELHEIGHT-self.keyboardHeight){ [selfresignFirstResponder]; selfFrame.origin.y=SCREEN_HEIGHT; [UIViewanimateWithDuration: 0.4 animations:^{ self.bgView.frame=selfFrame; }completion:^(BOOLfinished){ [IQKeyboardManagersharedManager].enable=YES; [[NSNotificationCenterdefaultCenter]removeObserver:self]; //[self.hideSucSignalsendNext:nil]; [selfremoveFromSuperview]; }]; } delegate中的操作 这里首先要弄懂APPdelegate中的这几个代理方法的意思: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 //App已经启动 -(BOOL)application:(UIApplication*)applicationdidFinishLaunchingWithOptions:(NSDictionary*)launchOptions{ //Overridepointforcustomizationafterapplicationlaunch. return YES; } //App挂起状态 -( void )applicationWillResignActive:(UIApplication*)application{ //Sentwhentheapplicationisabouttomovefromactivetoinactivestate.Thiscanoccurforcertaintypesoftemporaryinterruptions(suchasanincomingphonecallorSMSmessage)orwhentheuserquitstheapplicationanditbeginsthetransitiontothebackgroundstate. //Usethismethodtopauseongoingtasks,disabletimers,andinvalidategraphicsrenderingcallbacks.Gamesshouldusethismethodtopausethegame. } //APP进入后台 -( void )applicationDidEnterBackground:(UIApplication*)application{ //Usethismethodtoreleasesharedresources,saveuserdata,invalidatetimers,andstoreenoughapplicationstateinformationtorestoreyourapplicationtoitscurrentstateincaseitisterminatedlater. //Ifyourapplicationsupportsbackgroundexecution,thismethodiscalledinsteadofapplicationWillTerminate:whentheuserquits. } //APP将重新回到前台 -( void )applicationWillEnterForeground:(UIApplication*)application{ //Calledaspartofthetransitionfromthebackgroundtotheactivestate;hereyoucanundomanyofthechangesmadeonenteringthebackground. } //APP进入活跃状态 -( void )applicationDidBecomeActive:(UIApplication*)application{ //Restartanytasksthatwerepaused(ornotyetstarted)whiletheapplicationwasinactive.Iftheapplicationwaspreviouslyinthebackground,optionallyrefreshtheuserinterface. } //系统时间发生改变时执行 -( void )applicationWillTerminate:(UIApplication*)application{ //Calledwhentheapplicationisabouttoterminate.Savedataifappropriate.SeealsoapplicationDidEnterBackground:. } 在上面的这些代理方法中,我们需要用到的是 applicationDidBecomeActive方法。在这个方法中我们去检查系统的粘贴板UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 if (pasteboard.string){ NSLog(@ "string:%@" ,pasteboard.string); NSString*urlStr=pasteboard.string; if ([urlStrhasPrefix:@ "https://" ]||[urlStrhasPrefix:@ "http://" ]){ //如果粘贴板中的字符串包含https或http字段,我们去检查当前的控制器如果当前的控制器是我们弹出做操作的控制器的话isPopVC=NO; BOOLisPopVC=NO; UIViewController*Rootvc=self.window.rootViewController; if ([RootvcisKindOfClass:[UINavigationController class ]]){ UINavigationController*nav=(UINavigationController*)Rootvc; UIViewController*v=[nav.viewControllerslastObject]; if ([visKindOfClass:[UploadResCofingVC class ]]){ isPopVC=YES; } } //如果popView==nil并且isPopVC==NO弹出popView弹窗视图进行操作 if (!self.popView&&!isPopVC){ UploadResourcesPopupView*popView=[UploadResourcesPopupView new ]; [popViewshow]; self.popView=popView; [self.popView.hideSucSignalsubscribeNext:^(idx){ @strongify(self); self.popView=nil; }]; } } } } 总结 以上大体就是实现这个功能的基本思路,细节方面因项目而异了,比如我们需要判断当前用户的角色,当前用户是否登录,对弹窗视图后续的一些操作。当然并不完美,欢迎批评指正。 转自:http://www.cocoachina.com/ios/20180508/23307.html

优秀的个人博客,低调大师

Unity与安卓开发的一些路径知识

文章目录[点击展开](?)[+] APK安装之后找不到路径 公司的测试机(安卓)基本都是不带SD卡的。 APK在安卓手机上安装之后,使用手机助手类的软件打开文件管理,打开内置SDK卡/Android/data/ 在这个目录下却发现找不到以应用的包名(com.xxx.xxx) 开头的文件夹,那比如要打开这个目录查看里面的文件呢? 但是却能看到一些其它APP的目录,那么请检查以下设置: 1、打开File-Build Settings- 选择Player Settings,请确认已经切换到了Android 平台,找到Configuration这一部分设置 2、Install Location 选择 Automatic Write Permission 选择 External (SDCard) 3、重新打包APK,并安装,就可以在文件管理中找到这个目录了。 安卓的写入路径 比如你想在安装目录下创建一个目录并往里面写入文件,路径建议这样写:(和windows下的路径符号不同,而是和浏览器中网络的路径符号相同) string savePath = Application.persistentDataPath + "/" + "SaveTextures/"; 而如果你这样写,那么极有可能出现错误! string savePath = Application.persistentDataPath + "\\SaveTextures\\" 我在安卓上测试,会出现文件名变成:files\SaveTextures\2017-01-13_02-12-54.png也就是说文件名变成了路径,所以当你使用路径加载时,就会报文件不存在。 WWW加载的文件协议 使用WWW 加载非Assetbundle文件,比如原始的音乐文件(mp3,wav),原始的贴图文件(png,jpg) 比如这个文件放在应用程序的沙盒内或SD卡内:Application.persistentDataPath public static string GetFileProtocol() { string fileProtocol = "file://"; if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer #if !UNITY_5_4_OR_NEWER || Application.platform == RuntimePlatform.WindowsWebPlayer #endif ) { fileProtocol = "file:///"; } return fileProtocol; } 使用 www 加载示例: public static IEnumerator LoadByWWW(string fullFilePath, Action<Texture2D> callback) { string loadPath = GetFileProtocol() + fullFilePath; WWW www = new WWW(loadPath); yield return www; if (www != null && string.IsNullOrEmpty(www.error)) { //获取Texture Texture2D texture = www.texture; if (callback != null) callback(texture); } else { Log.LogError("www 加载图片失败:{0}", www.error); if (callback != null) callback(null); } } 测试环境 本文的测试环境如下: Unity 5.5.0f3 安卓4.2.3 本文转自赵青青博客园博客,原文链接:http://www.cnblogs.com/zhaoqingqing/p/6283763.html,如需转载请自行联系原作者 posted @ 2017-01-13 18:31 赵青青阅读( 315) 评论( 0) 编辑 收藏

优秀的个人博客,低调大师

SpringBoot+MyBatis开发环境搭建并实现登录权限过滤

最近尝试了一下SpringBoot,发现在controller和service数量相同的时候,比之前用Tomcat启动SpringMVC快了一大半,配置也更少了,很多东西不去重新覆盖设置的话直接会以默认配置启动。 首先搭建一个同时支持RESTful和传统MVC的服务。完成后的项目目录结构如下: 建一个默认Maven工程,新建src/main/resources目录,并添加到classpath。修改pom.xml,这里说明一下,以下设定是基于1.5.X版本的,由于2.0.0版本开始使用的是Spring5,设置会不一样。SpringBoot不建议使用JSP,thymeleaf模板是SpringBoot使用的一种前端静态模板,当然也可以不要前端模板,直接通过前端框架搭建一个。 <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> <mybatis-spring-boot>1.2.0</mybatis-spring-boot> <mysql-connector>5.1.39</mysql-connector> </properties> <!-- Spring Boot 启动父依赖 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> </parent> <dependencies> <!-- Spring Boot Web 依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring Boot Test 依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- thymeleaf模板 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <!-- Spring Boot Mybatis 依赖 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>${mybatis-spring-boot}</version> </dependency> <!-- MySQL 连接驱动依赖 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> </dependencies> SpringBoot默认会使用Tomcat容器启动,要设置一个启动类 1 //Spring Boot 应用的标识 2 @SpringBootApplication 3 public class App { 4 public static void main(String[] args) { 5 SpringApplication.run(App.class, args); 6 } 7 } 然后是controller层,同样的如果@RestController则所有请求会自动返回json对象,如果是@Controller则默认会返回页面模板,如果再加上@ResponseBody则是json对象。 1 @RestController 2 public class HelloController { 3 4 @RequestMapping("/HelloWorld") 5 public String hello() { 6 return "Hello World!"; 7 } 8 9 @RequestMapping("/HelloBean") 10 public HelloBean hellobean() { 11 HelloBean hello = new HelloBean(); 12 hello.setId("123"); 13 hello.setPassword("456"); 14 hello.setName("小明"); 15 return hello; 16 } 17 18 @RequestMapping("/HelloBean/{id}") 19 public HelloBean hellobean(@PathVariable("id") String id) { 20 HelloBean hello = new HelloBean(); 21 hello.setId(id); 22 hello.setPassword("456"); 23 hello.setName("小明"); 24 return hello; 25 } 26 } 1 @Controller 2 public class HtmlController { 3 4 @GetMapping("/login") 5 public String login(Model model) { 6 model.addAttribute("success", true); 7 return "static/login"; 8 } 9 10 @GetMapping("/register") 11 public String register(Model model) { 12 return "static/register"; 13 } 14 } thymeleaf模板的默认路径是src/main/resources/templates,而首页会自动设置为/static/index,所以我把所有模板放在了static目录下,上面controller返回的路径也就是static/login这样的格式。添加login.html 1 <!DOCTYPE HTML> 2 <html xmlns:th="http://www.thymeleaf.org"> 3 <head> 4 <title>Login</title> 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 6 </head> 7 <body> 8 <form class="form-signin" role="form" th:action="@{/user/login}" 9 th:method="post"> 10 <input type="text" class="form-control" placeholder="用户名" 11 required="required" name="username" /> <input type="password" 12 class="form-control" placeholder="密码" required="required" 13 name="password" /> 14 <button class="btn btn-lg btn-warning btn-block" type="submit">登录</button> 15 <label class="checkbox"> <input type="checkbox" 16 value="remember-me" /> 记住我 17 </label> 18 </form> 19 <a href="/register">注册</a> 20 <p th:if="${success} == false">登录失败</p> 21 <p th:text="${info}" /> 22 </body> 23 </html> 因为默认设置下模板是不能热修改启动的,所以要把它打开,recources目录下添加文件application.properties ## 页面动态编译 spring.thymeleaf.cache=false 直接对启动类运行启动,效果如下: 然后是MyBatis的集成。application.properties再添加设置如下,mybatis.mapperLocations是xml文件在recources目录下的路径 ## 数据源配置 spring.datasource.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8 spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver ## Mybatis 配置 mybatis.typeAliasesPackage=org.spring.springboot.domain mybatis.mapperLocations=classpath:mapper/*.xml 启动类添加对dao层的扫描 1 //Spring Boot 应用的标识 2 @SpringBootApplication 3 //mapper 接口类扫描包配置 4 @MapperScan("graywind.shop.dao") 5 public class App { 6 public static void main(String[] args) { 7 SpringApplication.run(App.class, args); 8 } 9 } 添加Mapper类和Bean类,以及xml文件 1 package graywind.shop.dao; 2 3 import java.util.List; 4 5 import graywind.shop.bean.TestBean; 6 7 public interface TestMapper { 8 public List<TestBean> getTest(); 9 } 1 package graywind.shop.bean; 2 3 public class TestBean { 4 private String id; 5 private String txt; 6 7 public String getId() { 8 return id; 9 } 10 11 public void setId(String id) { 12 this.id = id; 13 } 14 15 public String getTxt() { 16 return txt; 17 } 18 19 public void setTxt(String txt) { 20 this.txt = txt; 21 } 22 } <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="graywind.shop.dao.TestMapper"> <select id="getTest" resultType="graywind.shop.bean.TestBean"> select id,txt from test </select> </mapper> 然后就和以前一样注入使用 @Autowired private TestMapper testMapper; @Override public void test() { List<TestBean> list = testMapper.getTest(); } 接下来做一个权限过滤,我们希望某些页面是登录后才能查看的,需要用到过滤器。首先定义@Auth,在类或方法上添加该注解之后,就会被过滤器拦截验证。 package graywind.shop.interceptor; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 在类或方法上添加@Auth就验证登录 * @author Administrator * */ @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Auth { } 然后添加过滤器LoginInterceptor和一些辅助类,这里拦截之后会进入preHandle方法,如果返回true,则页面会继续执行,否则会被重定向到login页面。验证通过的方法是session里面有username信息,后续可以扩展成通过从缓存中取session信息验证达到分布式服务登录验证。 1 package graywind.shop.interceptor; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.stereotype.Component; 5 import org.springframework.web.method.HandlerMethod; 6 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 7 8 import graywind.shop.bean.SessionData; 9 import graywind.shop.service.UserService; 10 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 13 import java.lang.reflect.Method; 14 import java.util.Optional; 15 16 import static graywind.shop.interceptor.Constants.MOBILE_NUMBER_SESSION_KEY; 17 import static graywind.shop.interceptor.Constants.SESSION_KEY; 18 import static graywind.shop.interceptor.Constants.USER_CODE_SESSION_KEY; 19 20 @Component 21 public class LoginInterceptor extends HandlerInterceptorAdapter { 22 private final static String SESSION_KEY_PREFIX = "session:"; 23 24 @Autowired 25 private UserService userSvc; 26 27 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 28 throws Exception { 29 String username = (String) request.getSession().getAttribute("username"); 30 if (Optional.ofNullable(username).map(String::length).orElse(0) > 0) { 31 return true; 32 } 33 34 if (!handler.getClass().isAssignableFrom(HandlerMethod.class)) { 35 return true; 36 } 37 38 final HandlerMethod handlerMethod = (HandlerMethod) handler; 39 final Method method = handlerMethod.getMethod(); 40 final Class<?> clazz = method.getDeclaringClass(); 41 if (clazz.isAnnotationPresent(Auth.class) || method.isAnnotationPresent(Auth.class)) { 42 if (request.getAttribute(USER_CODE_SESSION_KEY) == null) { 43 response.sendRedirect(request.getContextPath() + "/login"); 44 return false; 45 } else { 46 return true; 47 } 48 } 49 return true; 50 } 51 } package graywind.shop.interceptor; public interface Constants { int MAX_FILE_UPLOAD_SIZE = 5242880; String MOBILE_NUMBER_SESSION_KEY = "sessionMobileNumber"; String USER_CODE_SESSION_KEY = "userCode"; String SESSION_KEY = "sessionId"; } package graywind.shop.bean; public class SessionData { private Integer userCode; private String mobileNumber; public Integer getUserCode() { return userCode; } public void setUserCode(Integer userCode) { this.userCode = userCode; } public String getMobileNumber() { return mobileNumber; } public void setMobileNumber(String mobileNumber) { this.mobileNumber = mobileNumber; } } 最后添加一个MVC设置,代替原先的web.xml 1 package graywind.shop.interceptor; 2 3 import org.slf4j.Logger; 4 import org.slf4j.LoggerFactory; 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.context.annotation.ComponentScan; 7 import org.springframework.context.annotation.Configuration; 8 import org.springframework.context.annotation.PropertySource; 9 import org.springframework.web.servlet.config.annotation.CorsRegistry; 10 import org.springframework.web.servlet.config.annotation.EnableWebMvc; 11 import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 12 import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 13 14 @Configuration 15 @EnableWebMvc 16 @ComponentScan(basePackages = "graywind.shop.controller") 17 @PropertySource(value = "classpath:application.properties", 18 ignoreResourceNotFound = true,encoding = "UTF-8") 19 public class MvcConfig extends WebMvcConfigurerAdapter { 20 private static final Logger logger = LoggerFactory.getLogger(MvcConfig.class); 21 22 @Autowired 23 LoginInterceptor loginInterceptor; 24 25 @Override 26 public void addInterceptors(InterceptorRegistry registry) { 27 // 注册监控拦截器 28 registry.addInterceptor(loginInterceptor) 29 .addPathPatterns("/**") 30 .excludePathPatterns("/configuration/ui"); 31 32 } 33 34 @Override 35 public void addCorsMappings(CorsRegistry registry) { 36 registry.addMapping("/**") 37 .allowedOrigins("*") 38 .allowedHeaders("*/*") 39 .allowedMethods("*") 40 .maxAge(120); 41 } 42 } 现在就可以在controller层通过@Auth注解来控制权限。最后还要在登录验证成功之后将用户信息写入到session里面,这个比较常规就不写了。个人GitHub地址: https://github.com/GrayWind33

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

用户登录
用户注册