使用Spring Boot和Vue进行有益的开发

“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证。

Vue是一个Web框架,由于它的精简和刻薄,最近引起了很多关注。 它的基准框架成本约为4万,被称为简约Web框架。 随着最近对Web性能的关注以及移动优先,移动快速的关注,Vue变得越来越流行也就不足为奇了。 如果您花时间学习AngularJS,很可能会在Vue.js中找到老朋友。

Spring Boot是Java生态系统中我最喜欢的框架之一。 是的,我有偏见。 自2004年以来,我就一直是Spring Framework的爱好者。能够使用Spring MVC编写Java Webapp真是太好了,但是大多数人都使用XML进行配置。 尽管Spring支持JavaConfig,但直到Spring Boot(在2014年)才真正起步。 如今,您再也看不到Spring教程,该教程向您展示了如何使用XML进行配置。 做得好,Spring Boot团队!

我之所以写本教程,是因为我是Vue的忠实拥护者。 如果您了解我,就会知道我是一个Web框架爱好者。 也就是说,我是Web框架的忠实拥护者。 就像NBA球迷有一些喜欢的球员一样,我也有一些喜欢的框架。 Vue最近成为其中之一,我想向您展示原因。

在本文中,我将向您展示如何使用Spring Data JPA和Hibernate构建Spring Boot API。 然后,我将向您展示如何创建Vue PWA并对其进行自定义以显示API中的数据。 然后,您将添加一些动画gif,一些认证,并祝您玩得开心!

使用Spring Boot构建REST API

要开始使用Spring Boot,请导航至start.spring.io并选择版本2.1.1+。 在“搜索依赖项”字段中,选择以下内容:

  • H2 :内存数据库
  • Lombok(Lombok) :因为没有人喜欢生成(甚至更糟糕的是编写!)getter和setter。
  • JPA :Java的标准ORM
  • 其余存储库 :允许您将JPA存储库公开为REST端点
  • Web :具有Jackson(用于JSON),Hibernate Validator和嵌入式Tomcat的Spring MVC
引导发展

如果您更喜欢命令行,请安装HTTPie并运行以下命令以下载demo.zip

http https://start.spring.io/starter.zip dependencies==h2,lombok,data-jpa,data-rest,web \packageName==com.okta.developer.demo -d

创建一个名为spring-boot-vue-example 。 将demo.zip的内容demo.zip到其server目录中。

mkdir spring-boot-vue-example
unzip demo.zip -d spring-boot-vue-example/server

在您喜欢的IDE中打开“服务器”项目,然后运行DemoApplication或使用./mvnw spring-boot:run从命令行启动它。

创建一个com.okta.developer.demo.beer程序包和其中的Beer.java文件。 此类将是保存您的数据的实体。

package com.okta.developer.demo.beer;import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;@Data
@NoArgsConstructor
@Entity
class Beer {public Beer(String name) {this.name = name;}@Id@GeneratedValueprivate Long id;@NonNullprivate String name;
}

添加一个利用Spring Data在此实体上执行CRUD的BeerRepository类。

package com.okta.developer.demo.beer;import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;@RepositoryRestResource
interface BeerRepository extends JpaRepository<Beer, Long> {
}

添加@RepositoryRestResource注释BeerRepository暴露了其所有的CRUD操作的REST端点。

添加使用此存储库的BeerCommandLineRunner并创建一组默认数据。

package com.okta.developer.demo.beer;import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;import java.util.stream.Stream;@Component
public class BeerCommandLineRunner implements CommandLineRunner {private final BeerRepository repository;public BeerCommandLineRunner(BeerRepository repository) {this.repository = repository;}@Overridepublic void run(String... strings) throws Exception {// Top beers from https://www.beeradvocate.com/lists/us, November 2018Stream.of("Kentucky Brunch Brand Stout", "Marshmallow Handjee", "Barrel-Aged Abraxas","Hunahpu's Imperial Stout", "King Julius", "Heady Topper","Budweiser", "Coors Light", "PBR").forEach(name ->repository.save(new Beer(name)));repository.findAll().forEach(System.out::println);}
}

重新启动您的应用程序,您应该会在终端上看到印刷的啤酒列表。

引导发展

添加一个BeerController类来创建一个端点,该端点过滤出的啤酒数量少于大啤酒。

package com.okta.developer.demo.beer;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.Collection;
import java.util.stream.Collectors;@RestController
public class BeerController {private BeerRepository repository;public BeerController(BeerRepository repository) {this.repository = repository;}@GetMapping("/good-beers")public CollectiongoodBeers() {return repository.findAll().stream().filter(this::isGreat).collect(Collectors.toList());}private boolean isGreat(Beer beer) {return !beer.getName().equals("Budweiser") &&!beer.getName().equals("Coors Light") &&!beer.getName().equals("PBR");}
}

重新构建您的应用程序并导航到http://localhost:8080/good-beers 。 您应该在浏览器中看到优质啤酒的列表。

引导发展

使用HTTPie时,您也应该在终端窗口中看到相同的结果。

http :8080/good-beers

使用Vue CLI创建项目

这些天来,创建API似乎很容易,这在很大程度上要归功于Spring Boot。 在本节中,我希望向您展示使用Vue创建UI也非常简单。 我还将向您展示如何使用TypeScript开发Vue应用。 如果您按照以下步骤操作,则将创建一个新的Vue应用,从API获取啤酒名称和图像,并创建组件以显示其数据。

要创建Vue项目,请确保已安装Node.js和Vue CLI 3 。 创建本教程时,我使用了Node 11.3.0。

npm install -g @vue/cli@3.2.1

在终端窗口中,使用cd进入spring-boot-vue-example目录的根目录并运行以下命令。 该命令将创建一个新的Vue应用程序并提示您选择。

vue create client

当提示您选择礼物时,选择手动选择功能

引导发展

检查TypeScriptPWARouter功能。 选择其余问题的默认值(按Enter )。

在终端窗口中,cd进入client目录,然后在您喜欢的编辑器中打开package.json 。 添加与serve脚本相同的start脚本。

"scripts": {"start": "vue-cli-service serve","serve": "vue-cli-service serve","build": "vue-cli-service build","lint": "vue-cli-service lint"
},

现在,您可以使用npm start Vue应用npm start 。 您的Spring Boot应用程序仍应在端口8080上运行,这将导致您的Vue应用程序使用端口8081。我希望您在本教程中始终在8081上运行您的Vue应用程序。 为确保它始终在此端口上运行,请创建一个client/vue.config.js文件,并向其中添加以下JavaScript。

module.exports = {devServer: {port: 8081}
};

在浏览器中打开http://localhost:8081 ,您应该会看到类似下面的页面。

引导发展

在Vue中创建良好的Beers UI

到目前为止,您已经创建了一个好的啤酒API和一个Vue客户端,但是尚未创建UI来显示API中的啤酒列表。 为此,请打开client/src/views/Home.vue并添加一个created()方法。

import axios from 'axios';
...private async created() {const response = await axios.get('/good-beers');this.beers = await response.data;
}

Vue的组件生命周期将调用created()方法。

John Papa的带有TypeScript的Vue.js对弄清楚如何将TypeScript与Vue一起使用提供了很大的帮助。 Vue的TypeScript文档也很有帮助。

您需要安装axios才能编译此代码。

npm i axios

您会看到这会将响应数据放入本地beers变量中。 要正确定义此变量,请创建一个Beer接口并将Home类的beers变量初始化为一个空数组。

export interface Beer {id: number;name: string;giphyUrl: string;
}@Component({components: {HelloWorld,},
})
export default class Home extends Vue {public beers: Beer[] = [];private async created() {const response = await axios.get('/good-beers');this.beers = await response.data;}
}

敏锐的眼睛会注意到,这会在与Vue应用程序相同的端口上向/good-beers发出请求(因为它是相对URL)。 为此,您需要修改client/vue.config.js以使其具有将此URL发送到Spring Boot应用程序的代理。

module.exports = {devServer: {port: 8081,proxy: {"/good-beers": {target: "http://localhost:8080",secure: false}}}
};

修改client/src/views/Home.vue的模板,以显示API中的优质啤酒列表。

<template><div class="home"><img alt="Vue logo" src="../assets/logo.png"><h1>Beer List</h1><div v-for="beer in beers">{{ beer.name }}</div></div>
</template>

使用npm start重新启动Vue应用,并在http://localhost:8081上刷新您的应用。 您应该从Spring Boot API中看到啤酒列表。

引导发展

创建一个BeerList组件

为了使此应用程序易于维护,请将啤酒清单逻辑和渲染移至其自己的BeerList组件。 创建client/src/components/BeerList.vue并用Home.vue的代码填充它。 删除Vue徽标,自定义模板的主类名称,然后删除HelloWorld组件。 完成后,它应该如下所示。

<template><div class="beer-list"><h1>Beer List</h1><div v-for="beer in beers">{{ beer.name }}</div></div>
</template><script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import axios from 'axios';export interface Beer {id: number;name: string;giphyUrl: string;
}@Component
export default class BeerList extends Vue {public beers: Beer[] = [];private async created() {const response = await axios.get('/good-beers');this.beers = await response.data;}
}
</script>

然后更改client/src/views/Home.vue ,使其仅包含徽标和对<BeerList/>的引用。

<template><div class="home"><img alt="Vue logo" src="../assets/logo.png"><BeerList/></div>
</template><script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import BeerList from '@/components/BeerList.vue';@Component({components: {BeerList,},
})
export default class Home extends Vue {}
</script>

创建一个GiphyImage组件

为了使外观看起来更好一点,添加GIPHY组件以根据啤酒的名称获取图像。 创建client/src/components/GiphyImage.vue并将以下代码放入其中。

<template><img :src=giphyUrl v-bind:alt=name height="200"/>
</template><script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import axios from 'axios';@Component
export default class GiphyImage extends Vue {@Prop() private name!: string;private giphyUrl: string = '';private async created() {const giphyApi = '//api.giphy.com/v1/gifs/search?api_key=dc6zaTOxFJmzC&limit=1&q=';const response = await axios.get(giphyApi + this.name);const data = await response.data.data;if (data.length) {this.giphyUrl = data[0].images.original.url;} else {this.giphyUrl = '//media.giphy.com/media/YaOxRsmrv9IeA/giphy.gif';}}
}
</script><!-- The "scoped" attribute limits CSS to this component only -->
<style scoped>
img {margin: 10px 0 0;
}
</style>

更改BeerList.vue以在其模板中使用<GiphyImage/>组件:

<div v-for="beer in beers">{{ beer.name }}<br/><GiphyImage :name="beer.name"/>
</div>

并将其添加到<script>块中的components列表中:

import GiphyImage from '@/components/GiphyImage.vue';@Component({components: {GiphyImage},
})
export default class BeerList extends Vue { ... }

在同一文件中,在底部添加<style>部分,然后使用CSS Grid布局将啤酒按行组织。

<style scoped>
.grid {display: grid;grid-template-columns: repeat(3, 1fr);grid-gap: 10px;grid-auto-rows: minmax(100px, auto);
}
</style>

您需要将div环绕在啤酒清单模板上,以使其生效。

<div class="grid"><div v-for="beer in beers">{{ beer.name }}<br/><GiphyImage :name="beer.name"/></div>
</div>

进行这些更改后,您的用户界面应类似于以下啤酒名称和匹配图像列表。

引导发展

您刚刚创建了一个与Spring Boot API对话的Vue应用。 恭喜你! 🎉

添加PWA支持

Vue CLI开箱即用地支持渐进式Web应用程序(PWA)。 创建Vue应用程序时,您选择了PWA作为功能。

PWA功能仅在生产中启用,因为在开发中缓存资产可能是一个真正的难题。 在client目录中运行npm run build来创建一个可以投入生产的版本。 然后使用serve创建一个Web服务器并显示您的应用程序。

npm i -g serve
serve -s dist -p 8081

您应该能够打开浏览器,并在http://localhost:8081看到您的应用程序。 第一次尝试时,我发现加载页面没有呈现任何啤酒名称,并且所有图像均相同。 这是因为客户端尝试向/good-beers发出请求,并且在生产模式下未配置任何代理。

要解决此问题,您需要在客户端中更改URL并将Spring Boot配置为允许从http://localhost:8081进行跨域访问。

修改client/src/components/BeerList.vue以使用Spring Boot API的完整URL。

private async created() {const response = await axios.get('http://localhost:8080/good-beers');this.beers = await response.data;
}

如果进行这些更改后,您在用户界面中看不到任何更改,那是因为您的浏览器已缓存您的应用程序。 使用隐身窗口或清除缓存(在Chrome中: 开发者工具 > 应用程序 > 清除存储 > 清除网站数据 )可解决此问题。

为Spring Boot配置CORS

在服务器项目中,打开src/main/java/…​/demo/beer/BeerController.java并添加一个@CrossOrigin批注以启用来自客户端的跨域资源共享(CORS)( http://localhost:8081 ) 。

import org.springframework.web.bind.annotation.CrossOrigin;
...@GetMapping("/good-beers")@CrossOrigin(origins = "http://localhost:8081")public Collection<Beer> goodBeers() {

进行这些更改后,重建Vue应用以进行生产,刷新浏览器,一切都应按预期呈现。

使用Lighthouse查看您的PWA分数

我在Chrome中进行了Lighthouse审核,发现此应用目前得分为81/100。 该报告最突出的抱怨是我没有使用HTTPS。 为了查看该应用使用HTTPS时的评分,我将其部署到Pivotal Cloud Foundry和Heroku 。 我很兴奋地发现它在两个平台上都得分很高。

引导发展
引导发展

得分为96的原因是因为The viewport size is 939px, whereas the window size is 412px. 我不确定是什么引起了这个问题,也许是CSS Grid布局?

要查看我用来部署所有内容的脚本,请参阅heroku.sh随附的GitHub存储库中的heroku.shcloudfoundry.sh

您将需要在运行部署脚本之前初始化Git。 运行rm -rf client/.git ,然后运行git commit -a "Add project"

使用Okta添加身份验证

您可能会想,“这很酷,很容易看出人们为什么挖Vue。” 尝试过后,您可能还会挖掘其他工具:使用Okta进行身份验证! 为什么选择Okta? 因为您可以免费获得1,000个每月活跃用户 ! 值得一试,尤其是当您看到使用Okta将auth添加到Spring Boot和Vue如此容易时。

Okta Spring启动启动器

为了保护您的API,可以使用Okta的Spring Boot Starter 。 要集成此启动器,请将以下依赖项添加到server/pom.xml

<dependency><groupId>com.okta.spring</groupId><artifactId>okta-spring-boot-starter</artifactId><version>0.6.1</version>
</dependency>
<dependency><groupId>org.springframework.security.oauth.boot</groupId><artifactId>spring-security-oauth2-autoconfigure</artifactId><version>2.1.1.RELEASE</version>
</dependency>

现在,您需要配置服务器以使用Okta进行身份验证。 为此,您需要在Okta中创建OIDC应用。

在Okta中创建OIDC应用

登录到您的1563开发者帐户(或者注册 ,如果你没有一个帐户)并导航到应用程序 > 添加应用程序 。 单击“ 单页应用程序” ,再单击“ 下一步” ,然后为该应用程序命名。 将localhost:8080所有实例更改为localhost:8081 ,然后单击完成

将客户端ID复制到您的server/src/main/resources/application.properties文件中。 在其中时,添加与您的Okta域匹配的okta.oauth2.issuer属性。 例如:

okta.oauth2.issuer=https://{yourOktaDomain}/oauth2/default
okta.oauth2.client-id={yourClientId}

{yourOktaDomain}替换为您的组织机构网址,您可以在开发人员控制台的仪表板上找到它。 确保在值中不包括-admin

更新server/src/main/java/…​/demo/DemoApplication.java以将其启用为资源服务器。

import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;@EnableResourceServer
@SpringBootApplication

进行了这些更改之后,您应该能够重新启动服务器,并在尝试导航到http://localhost:8080时看到访问被拒绝。

引导发展

Okta的Vue支持

Okta的Vue SDK可让您将OIDC集成到Vue应用程序中。 您可以在npmjs.com上找到有关Okta的Vue SDK的更多信息。 要安装,请在client目录中运行以下命令:

npm i @okta/okta-vue@1.0.7
npm i -D @types/okta__okta-vue


Okta的Vue SDK的类型可能会包含在将来的版本中。 我创建了一个添加请求的拉取请求 。

打开client/src/router.ts并添加您的Okta配置。 该router.ts下面还包含了一个路径BeerList ,这是需要进行身份验证的回调,以及导航后卫需要认证/beer-list路径。 用这个替换您的,然后更新yourClientDomainyourClientId以匹配您的设置。 确保删除{}因为它们只是占位符。

import Vue from 'vue';
import Router from 'vue-router';
import Home from './views/Home.vue';
import OktaVuePlugin from '@okta/okta-vue';
import BeerList from '@/components/BeerList.vue';Vue.use(Router);
Vue.use(OktaVuePlugin, {issuer: 'https://{yourOktaDomain}/oauth2/default',client_id: '{yourClientId}',redirect_uri: window.location.origin + '/implicit/callback',scope: 'openid profile email',
});const router = new Router({mode: 'history',base: process.env.BASE_URL,routes: [{path: '/',name: 'home',component: Home,},{path: '/about',name: 'about',// route level code-splitting// this generates a separate chunk (about.[hash].js) for this route// which is lazy-loaded when the route is visited.component: () => import(/* webpackChunkName: "about" */ './views/About.vue'),},{path: '/beer-list',name: 'beer-list',component: BeerList,meta: {requiresAuth: true,},},{ path: '/implicit/callback', component: OktaVuePlugin.handleCallback() },],
});router.beforeEach(Vue.prototype.$auth.authRedirectGuard());export default router;

由于您具有BeerList的路由,因此请从client/src/views/Home.vue删除它。

<template><div class="home"><img alt="Vue logo" src="../assets/logo.png"></div>
</template><script lang="ts">
import { Component, Vue } from 'vue-property-decorator';@Component
export default class Home extends Vue {}
</script>

client/src/App.vue链接添加到>BeerList client/src/App.vue 。 您还需要添加代码来检测用户是否已登录。 替换<template>部分,并将下面的<script>添加到您的App.vue

<template><div id="app"><div id="nav"><router-link to="/">Home</router-link> |<router-link to="/about">About</router-link><template v-if="authenticated"> |<router-link to="/beer-list">Good Beers</router-link></template></div><button v-if="authenticated" v-on:click="logout">Logout</button><button v-else v-on:click="$auth.loginRedirect()">Login</button><router-view/></div>
</template><script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator';@Component
export default class App extends Vue {public authenticated: boolean = false;private created() {this.isAuthenticated();}@Watch('$route')private async isAuthenticated() {this.authenticated = await this.$auth.isAuthenticated();}private async logout() {await this.$auth.logout();await this.isAuthenticated();// Navigate back to homethis.$router.push({path: '/'});}
}
</script>

重新启动Vue应用程序,您应该看到一个登录按钮。

引导发展

单击它,您将被重定向到Okta。 输入您用来注册Okta的凭据,您将被重定向回该应用程序。 您应该看到一个注销按钮和一个链接,以查看一些优质啤酒。

引导发展

如果单击“ Good Beers”链接,您将看到组件的标题,但没有数据。 如果您查看JavaScript控制台,则会看到CORS错误。

发生此错误是因为Spring的@CrossOrigin在Spring Security中不能很好地发挥作用。 要解决此问题,请在DemoApplication.java的主体中添加一个simpleCorsFilter bean。

package com.okta.developer.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;import java.util.Collections;@EnableResourceServer
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}@Beanpublic FilterRegistrationBean<CorsFilter> simpleCorsFilter() {UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();CorsConfiguration config = new CorsConfiguration();config.setAllowCredentials(true);config.setAllowedOrigins(Collections.singletonList("http://localhost:8081"));config.setAllowedMethods(Collections.singletonList("*"));config.setAllowedHeaders(Collections.singletonList("*"));source.registerCorsConfiguration("/**", config);FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));bean.setOrder(Ordered.HIGHEST_PRECEDENCE);return bean;}
}

进行此更改后,重新启动服务器。 要使其在客户端上全部client/src/components/BeerList.vue ,请修改client/src/components/BeerList.vuecreated()方法以设置授权标头。

private async created() {const response = await axios.get('http://localhost:8080/good-beers',{headers: {Authorization: `Bearer ${await this.$auth.getAccessToken()}`,},},);this.beers = await response.data;
}

现在,您应该能够以经过身份验证的用户身份查看优质啤酒清单。

引导发展

如果可行,那就太好了! 👍

了解有关Spring Boot和Vue的更多信息

本教程向您展示了如何构建使用诸如Spring Boot和Vue之类的现代框架的应用程序。 您学习了如何使用Okta的Vue SDK添加OIDC身份验证和保护路由。 如果您想观看本教程的视频,我将其作为截屏视频发布到YouTube上 。

如果您想了解有关Vue现象的更多信息,我推荐了几篇文章。 首先,我认为这很不错,它不是由公司(例如Angular + Google和React + Facebook)赞助的,这主要是由社区推动的。 挑战Google和Facebook的Solo JavaScript开发人员是《连线》杂志的一篇文章,解释了为什么这样做如此惊人。

关于JavaScript框架的性能,JavaScript框架的基准成本是Anku Sethi的一篇有趣的博客文章。 我喜欢他写这本书的动力:

上周,我对仅在页面上包含React会产生多少性能影响感到好奇。 因此,我在廉价的Android手机上运行了一些数字,并对此进行了撰写。

要了解有关Vue,Spring Boot或Okta的更多信息,请查看以下资源:

  • 使用Spring Boot和Vue.js构建一个简单的CRUD应用
  • 使用Vue.js和Node构建基本的CRUD应用
  • 使用Go和Vue构建单页应用
  • Spring Boot 2.1:出色的OIDC,OAuth 2.0和反应式API支持

您可以在GitHub上找到与本文相关的源代码。 主要示例(无身份验证)在master分支中,而Okta集成在okta分支中。 要签出本地计算机上的Okta分支,请运行以下命令。

git clone -b okta https://github.com/oktadeveloper/spring-boot-vue-example.git

如果您发现任何问题,请在下面添加评论,我们将尽力为您提供帮助。 如果您喜欢本教程,则应该在Twitter上关注我的团队 。 我们还有一个YouTube频道 ,我们在其中发布屏幕录像。


该教程有Angular和React版本。

“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证。

使用Spring Boot和Vue进行Bootiful开发最初于2018年12月3日发布在Okta开发人员博客上。

翻译自: https://www.javacodegeeks.com/2019/01/bootiful-development-spring-boot-vue.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/345167.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql mydumper_系统运维|Mydumper-MySQL数据库备份工具

Mydumper 是 MySQL 数据库服务器备份工具&#xff0c;它比 MySQL 自带的 mysqldump 快很多。它还有在转储的同时获取远程服务器二进制日志文件的能力。Mydumper 的优势并行能力 (因此有高速度) 和性能 (高效的代码避免了耗费 CPU 处理能力的字符集转换过程)更容易管理输出 (每个…

vue调用手机相机相册_详解Vue调用手机相机和相册以及上传

组件选中{{imgList.length}}张文件&#xff0c;共{{bytesToSize(this.size)}}javaScript代码export default {name: "cameras-and-albums",data(){return{imgList: [],datas: new FormData(),files:0,size:0}},methods:{//调用相册&相机fileClick() {$(#upload_f…

红旗linux mysql_恢复 - 红旗Linux案例精选:Amanda集中备份实例详细讲解_数据库技术_Linux公社-Linux系统门户网站...

五、恢复假定我们需要恢复cp3上一些丢失的数据&#xff0c;首先用amandabackup帐号登录cp2机器&#xff0c;创建/etc/amanda/amanda-client.conf文件&#xff0c;内容如下&#xff1a;## amanda.conf - sample Amanda client configuration file.## This file normally goes in…

linuxpip安装python包_Windows+Linux安装Python包管理工具pip

WindowsLinux安装Python包管理工具pipWindows安装Python包管理工具pippip是一个Python包管理工具&#xff0c;主要是用于安装PyPI上的软件包&#xff0c;可以替代easy_install工具。一、前期准备首先确认windows机器上面是否已经安装好了python。在cmd中输入python --version和…

mysql 深胡_Mysql胡说八道

mysql索引今天看了一些关于MySQL相关的东西&#xff0c;来做一些碎碎念&#xff0c;写这些可能只是觉得自己看东西老爱忘23333.先来看一组MySQL数据&#xff0c;如图我们要查看最后id11的数据&#xff0c;如果我们不加索引的话会怎样呢&#xff1f;他会一条一条的比对&#xff…

java public main_实例分析Java中public static void main(String args[])是什么意思

本文实例讲述了Java中public static void main(String args[])的来龙去脉。分享给大家供大家参考&#xff0c;具体如下&#xff1a;public static void main(String[] args)这绝对不是凭空想出来的&#xff0c;也不是没有道理的死规定&#xff0c;而是java程序执行的需要。jvm在…

java浏览文件夹_一个用java实现简单的文件浏览器

[java]代码库import java.awt.*;import java.awt.event.*;import java.net.URL;import javax.swing.*;//文件浏览器public class HTTPBrowserDemo extends JFrame {private static final long serialVersionUID -5794029080886644211L;JTextField jtfAddress; // 输入文件地址…

java奥运会安排赛程问题_记录奥运-当今五大Java记录框架之间的竞赛

java奥运会安排赛程问题开发人员&#xff1a;Takipi会告诉您何时新代码在生产中中断– Log4J vs SLF4J简单vs Logback vs Java Util日志记录vs LOG4J2 日志记录实际上是每个服务器端应用程序中古老且固有的部分。 这是应用程序以持久且可读的方式输出实时状态的主要方法。 某些…

为什么在子类中不重写超类的实例变量

当我们在父类和子类中创建一个具有相同名称的变量&#xff0c;并尝试使用持有子类对象的父类引用访问它时&#xff0c;我们会得到什么&#xff1f; 为了理解这一点&#xff0c;让我们考虑下面的示例&#xff0c;其中在Parent和Child类中声明一个具有相同名称的变量x 。 class…

cocos lua调用java_【Tech-Lua】Cocos-2dx-Lua调用java的小白教程(三)

上周五下班前&#xff0c;打包成功了。我很高兴&#xff0c;周六去踢场足球&#xff0c;周日去现场看了最后一分钟掉球的恒大&#xff0c;度过了一个愉快的周末。然后&#xff0c;噩梦的周一开始了。我再次打包&#xff0c;打算打包就安装&#xff0c;但结果是失败的。为何&…

github上java项目_GitHub上10,000个最受欢迎的Java项目-以下是他们使用的顶级库

github上java项目随着Java开发人员使用既成熟又高度发展的语言来工作&#xff0c;无论何时编写新代码&#xff0c;我们都将面临一个持续的困境–使用大家都在谈论的热门新技术&#xff0c;或者坚持使用久经考验的库&#xff1f; 由于Java应用程序的很大一部分是商业性质的&…

char java 回文_LeetCode刷题笔记(Java)---第1-18题

题目来自LeetCode文章目录全部章节1-18题19-40题41-60题61-80题81-100题101-120题121-140题1.两数之和2.两数相加3.无重复字符串的最长子串4.寻找两个有序数组的中位数5.最长回文子串6.Z 字形变换7.整数反转8.字符串转换整数 (atoi)9.回文数10.正则表达式匹配11.盛最多水的容器…

使用PostgreSQL使用Spring Boot和JPA构建基本应用

“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕&#xff1f; 尝试使用Okta API进行托管身份验证&#xff0c;授权和多因素身份验证。 每个不平凡的应用程序都需要一种保存和更新数据的方法&#xff1a;可通过HTTP访问的资…

通过示例了解Apache Ignite Baseline拓扑

点燃基准拓扑或BLT表示群集中的一组服务器节点&#xff0c;这些服务器节点将数据持久存储在磁盘上。 其中&#xff0c;N1-2和N5服务器节点是具有本机持久性的Ignite集群的成员&#xff0c;这些集群使数据能够持久存储在磁盘上。 N3-4和N6服务器节点是Ignite群集的成员&#x…

Spring Boot集成测试中@ContextConfiguration和@SpringApplicationConfiguration之间的区别

即使同时使用ContextConfiguration和SpringApplicationConfiguration批注以及SpringJUnit4ClassRunner来指定如何加载Spring应用程序上下文&#xff0c;它们之间也存在细微的差异。 尽管ContextConfiguration在加载应用程序上下文方面表现出色&#xff0c;但没有充分利用Spring…

vert.x_使用vert.x 2.0,RxJava和mongoDB创建simpe RESTful服务

vert.x中断了将近半年后发表了一篇新文章。 在本文中&#xff0c;我们将快速了解如何开始使用vert.x&#xff0c;更有趣的是&#xff0c;如何使用RxJava简化异步系统的编程。 我们将涵盖以下主题&#xff1a; 使用Maven创建一个空的vert.x项目 导入IntelliJ并创建一个简单的H…

如何通过Rultor将Maven工件部署到CloudRepo

在我以前的文章中 &#xff0c;我描述了如何在Amazon S3中设置私有Maven存储库并通过Rultor进行部署。 如果您熟悉管理Amazon Web Services&#xff08;AWS&#xff09;&#xff0c; S3和AWS Identity and Access Management&#xff08;IAM&#xff09;的话&#xff0c;这是一…

java里面自行车的属性_11、Java基础知识

1、安装jdk&#xff0c;配置环境变量2、public class HelloWorld{publicstatic void main(String[] args){System.out.println(‘HelloWorld’);}}3、编译过程&#xff1a;通过javac编译java文件&#xff0c;生成.class文件&#xff0c;使用java命令运行class文件&#xff0c;注…

布线问题分支限界法java_大型布线:Java云应用程序缺少的技术

布线问题分支限界法java您是否曾经想过&#xff0c;为什么大多数Java框架中的依赖项注入仅用于本地进程内服务而不是分布式服务&#xff1f; 我最近在2013年EMC世界大会上遇到了Paul Maritz的主题演讲 &#xff08;跳至第32分钟&#xff09;&#xff0c;这使我在云平台的背景下…

Spring Boot微服务,Docker和Kubernetes研讨会–第2部分

在上一篇文章中&#xff0c;我们使用SpringBoot和Docker创建了第一个微服务“ ProductService”。 在这一部分中&#xff0c;我们将详细介绍如何使用Spring Cloud&#xff0c;netflix库&#xff0c;API网关来管理多个微服务。 假设对于我们的订单管理系统&#xff0c;最小关系…