Spring Boot 是在 spring 框架基础之上开发的框架, 其设计目的是用来简化应用的初始搭建以及开发过程。虽然 spring 的组件代码是轻量级的,但它的配置却是重量级的, 即使 spring 引入了注解功能,但是仍然需要编写大量的模板化配置文件. 项目的依赖管理也是一件耗时耗力的事情,在环境搭建时,需要分析要导入大量库的坐标,而且还需要分析导入与之有依赖关,一旦选错依赖的版本,随之而来的不兼容问题就会严重阻碍项目的开发进度, Spirng Boot 本身并不提供 Spring 框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于 Spring 框架的应用程序。也就是说,它并不是用来替代 Spring 的解决方案,而是和 Spring 框架紧密结合用于提升 Spring 开 发者体验的工具.
1.前端发送一个登陆请求
submitForm(form) {
this.$refs[form].validate((valid) => {
if (valid) {
this.$http.post("admin/loginCtl/login",this.form).then((resp)=>{
2.后端根据前端地址接受请求
@RequestMapping(path = "/admin/loginCtl")
public class LoginController {
@RequestMapping(path = "/login")
public CommonResult login(@RequestBody Admin admin2){
(1)跨域的配置
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
//1,允许任何来源
corsConfiguration.setAllowedOriginPatterns(Collections.singletonList("*"));
//2,允许任何请求头
corsConfiguration.addAllowedHeader(CorsConfiguration.ALL);
//3,允许任何方法
corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
//4,允许凭证
corsConfiguration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(source);
}
}
(2)验证token(token拦截器)
先进行配置
@Configuration
public class WebConfig implements WebMvcConfigurer{
public void addInterceptors(InterceptorRegistry registry) {
InterceptorRegistration inter = registry.addInterceptor(new TokenInterceptor());
inter.addPathPatterns("/admin/**"); //管理员需要拦截过滤地址
inter.excludePathPatterns("/admin/loginCtl/login");//放行地址
再验证token, 登录时前端没有token,所以要对登录请求放行,登录成功后生成token再返回给前端保存在请求头中,再次交互时进行验证
public class TokenInterceptor implements HandlerInterceptor {
//预处理
//当请求经过映射处理器检测对应的控制器是存在,判断该请求可以进入拦截器,执行调用
//返回true,继续向下执行
//返回false,请求不在向下执行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("token");
boolean res = JWTUtil.verify(token);
if (!res){
CommonResult commonResult = new CommonResult(202,"token验证失效");
JsonMapper jsonMapper = new JsonMapper();
String json = jsonMapper.writeValueAsString(commonResult);
response.getWriter().print(json);
}
return res;
}
}
(3)application.yml yml 是 YAML(YAML Ain’t Markup Language)语言的文件,以数据为中心,时springboot的配置文件
server:
port: 8080
#spring相关配置
spring:
#配置数据库连接信息,生成默认的数据源队形,生成jdbcTemplate,事务管理功能初始化
datasource:
url: jdbc:mysql://127.0.0.1:3306/ssmdb?serverTimezone=Asia/Shanghai
username: root
password: 12121212
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource #指定数据源类型,还需要创建对象
initialSize: 5 #配置数据库连接池相关的配置
maxActive: 20
main:
allow-circular-references: true #开始支持spring循环依赖
#myatis配置 创建sqlsessionFactory
mvc:
pathmatch:
matching-strategy: ant_path_matcher
mybatis:
type-aliases-package: com.ffyc.news.model
mapper-locations: classpath:mappers/*Mapper.xml
configuration: #mybatis配置 setting配置
map-underscore-to-camel-case: true
cache-enabled: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
由Druid数据源来进行读取
/*
@Configuration 配置注解 表示此类是springBoot项目中一个配置类,sprngboot启动时会扫描
*/
@Configuration
public class DruidDataSourceConfig {
/*
@Bean == <bean id="" class=""> 作用在方法上,方法中会产生一个对象,最终把此对象交给spring容器
*/
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druid() {
//创建对象,从yml配置文件读值,赋值
DruidDataSource dataSource = new DruidDataSource();
//dataSource.setInitialSize();
return dataSource;//此方法产生的当对象最终返回并交给spring容器去管理
}
}
3.交互完成后将结果返回给前端
前端将返回的数据接收并进行相应的处理,其中携带的token也被aoixs保存在请求头中
//axios 请求拦截
axios.interceptors.request.use(config =>{
//向请求头中添加一个自定义请求头
config.headers.token = sessionStorage.getItem('token');
return config;
})
1.前端发送登录请求,将用户输入的账号密码发送到后端
methods: {
submitForm(form) {
this.$refs[form].validate((valid) => {
if (valid) {
this.$http.post("admin/loginCtl/login",this.form).then((resp)=>{
console.log(resp);
if(resp.data.code==200){
//sessionStorage.setItem浏览器提供的一个会话级别的存储空间,浏览器关闭后立刻清除
sessionStorage.setItem("account",resp.data.data.account);
sessionStorage.setItem("token",resp.data.data.token);
//localStorage.setItem("key","value");//长久保存
this.$router.push("/main");
}else if(resp.data.code==201){
this.$message({message:resp.data.message,type:'warning'});
}else{
this.$message.error(resp.data.message);
}
})
}
});
},
resetForm(form) {
this.$refs[form].resetFields();
}
}
2.web层(接收.处理,响应)
@RestControllerAdvice
@RestController
@RequestMapping(path = "/admin/loginCtl")
public class LoginController {
//static Logger logger = LoggerFactory.getLogger(LoginController.class);
@Autowired
LoginService loginService;
@RequestMapping(path = "/login")
public CommonResult login(@RequestBody Admin admin2){
//将日志信息写入到一个文件中,长久保存
// logger.debug("进入到后端登录功能:account={},password={}",admin2.getAccount(),admin2.getPassword());
admin2.setPassword(DigestUtils.md5DigestAsHex(admin2.getPassword().getBytes()));
Admin admin = loginService.login(admin2);
// logger.debug("登录成功:account={},password={}",admin.getAccount(),admin.getPassword());
if(admin!=null){
CommonResult commonResult = new CommonResult(admin,200,"保存成功");
return commonResult;
}
CommonResult commonResult1 = new CommonResult(null,201,"保存失败");
return commonResult1;
}
3.service层(业务上的一些处理)
@Service(value = "loginService")
@Transactional
public class LoginService {
@Resource
LoginDao loginDao;
public Admin login(Admin admin2){
Admin admin1 = loginDao.login(admin2);
String token = new JWTUtil().token(admin1.getId(),admin1.getAccount(),admin1.getType());
admin1.setToken(token);
return admin1;
}
public List<Menu> findmenus(String token) {
DecodedJWT decodedJWT = JWTUtil.getTokenInfo(token);
Integer id = decodedJWT.getClaim("id").asInt();
Integer type = decodedJWT.getClaim("type").asInt();
List<Menu> list = loginDao.findmenus(id,type);
return list;
}
}
4.model类(封装一些用户的信息或管理员的信息)
@ApiModel(value = "管理员实体类",description = "管理员实体类2")
@Data
public class Admin {
@ApiModelProperty(value = "管理员主键")
private Integer id;
private String account;
private String password;
private Integer type;
private String token;
private String gender;
private String phone;
private Admin admin;//操作人
private int pageNum;//当前页数
private int pageSize;//页数大小
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GTM+8")
private Date operTime;
private List<Role> roles;
private Integer[] roleIds;
}
5.dao层(与数据库进行交互)
@Repository(value = "loginDao")
public interface LoginDao {
public Admin login(Admin admin);
这可能是个愚蠢的问题。但是,我是一个新手......你怎么能在交互式rubyshell中有多行代码?好像你只能有一条长线。按回车键运行代码。无论如何我可以在不运行代码的情况下跳到下一行吗?再次抱歉,如果这是一个愚蠢的问题。谢谢。 最佳答案 这是一个例子:2.1.2:053>a=1=>12.1.2:054>b=2=>22.1.2:055>a+b=>32.1.2:056>ifa>b#Thecode‘if..."startsthedefinitionoftheconditionalstatement.2.1.2:057?>puts"f
我想在随机字符串前后添加一个空格。我试过使用"Random_string".center(1,"")但它不起作用。谢谢 最佳答案 我发现这是最优雅的解决方案:padded_string="#{random_string}"走简单的路没有错。 关于ruby-在ruby中的字符串前后添加空格?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/3357897/
我的第一个想法是这样的:classAbstractBuilderattr_reader:time_takendefbuild_with_timerstarted_at=Time.nowbuild@time_taken=Time.now-started_atenddefbuildraise'Implementthismethodinasubclass'endendclassMyBuilder我怀疑有更好的方法可以提供更好的灵active,例如理想情况下,我想在MyBuilder的实例上调用“build”而不是“build_with_timer”,并且始终记录执行时间。我确实考虑过使用al
如果您希望在Spring中启用定时任务功能,则需要在主类上添加 @EnableScheduling 注解。这样Spring才会扫描 @Scheduled 注解并执行定时任务。在大多数情况下,只需要在主类上添加 @EnableScheduling 注解即可,不需要在Service层或其他类中再次添加。以下是一个示例,演示如何在SpringBoot中启用定时任务功能:@SpringBootApplication@EnableSchedulingpublicclassApplication{publicstaticvoidmain(String[]args){SpringApplication.ru
软件特点部署后能通过浏览器查看线上日志。支持Linux、Windows服务器。采用随机读取的方式,支持大文件的读取。支持实时打印新增的日志(类终端)。支持日志搜索。使用手册基本页面配置路径配置日志所在的目录,配置后按回车键生效,下拉框选择日志名称。选择日志后点击生效,即可加载日志。windows路径E:\java\project\log-view\logslinux路径/usr/local/XX历史模式历史模式下,不会读取新增的日志。针对历史文件可以分页读取,配置分页大小、跳转。历史模式下,支持根据关键词搜索。目前搜索引擎使用的是jdk自带类库,搜索速度相对较低,优点是比较简单。2G日志全文搜
1.依赖导入org.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-validation2.validation常用注解@Null被注释的元素必须为null@NotNull被注释的元素不能为null,可以为空字符串@AssertTrue被注释的元素必须为true@AssertFalse被注释的元素必须为false@Min(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值@Max(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值@D
Iparking停车收费管理系统-可商用介绍Iparking是一款基于springBoot的停车收费管理系统,支持封闭车场和路边车场,支持微信支付宝多种支付渠道,支持多种硬件,涵盖了停车场管理系统的所有基础功能。技术栈Springboot,MybatisPlus,Beetl,Mysql,Redis,RabbitMQ,UniApp功能云端功能序号模块功能描述1系统管理菜单管理配置系统菜单2系统管理组织管理管理组织机构3系统管理角色管理配置系统角色,包含数据权限和功能权限配置4系统管理用户管理管理后台用户5系统管理租户管理多租户管理6系统管理公众号配置租户公众号配置7系统管理操作日志审计日志8系统
据我了解,在Ruby和Perl之间没有“桥梁”可以让您直接从Ruby调用Perl函数。据我了解,要从Ruby调用Perl程序,只需将其放在反引号中(即result=`./helloWorld.pl`)。但是,这不允许与Perl程序交互(即您不能与提示交互或提供输入)。我的问题如下:有没有什么方法可以从Ruby向Perl程序提供输入(除了参数)?Ruby和Perl之间没有桥梁,我错了吗?在导航提示时与程序的标准输入交互似乎是错误的方式,我正在处理的程序设计良好,并且具有包含适当Perl函数的库。 最佳答案 有Inline::Ruby模
在我采用Ruby语言的过程中,我花了很多时间在IRb中。太棒了!但是,由于我不是很清楚它的功能,并且对Ruby仍然是个“笨蛋”,所以我想知道以下内容:如何在不重新启动IRb的情况下“刷新”session(或者这是不可能的)。如何配置IRb加载一堆源文件“hello.rb”和“hello_objects.rb”,即在启动时?我在这些方面投入了大量工作,如果知道加载这些类的速记,而无需再次为每个类手动键入“加载”,那就太好了。 最佳答案 我不确定是否可以“刷新”session。但是,您可以像这样加载您的类:irb-r'hello.rb'
Lisp是否适合Web编程/应用程序(交互式),就像ruby和php一样?需要考虑的事情是:易于使用可部署性难度(尤其是对于编程初学者而言)(编辑)在阅读PaulGraham'sessay之后,我特别提到了CommonLisp.将是我的第一门编程语言。在这方面。这样做合适吗?我听说Clojure的宏功能不如CommonLisp的强大,这就是我尝试学习Clojure的原因。它教授编程并且非常强大。 最佳答案 Lisp是一个语系,而不是单一的语言。为了稍微回答您的问题,是的,存在用于各种Lisp方言的Web框架,例如用于Common