在React中获取数据

React初学者经常从不需要获取数据的应用开始。他们经常面临一个计数器,任务列表获取井字棋游戏应用。这是很好的,因为在开始学习React的时候,数据获取在你的应用中添加了另一层复杂度。

然而,有些时候你想要从自己的或者第三方API请求真实世界的数据。这个文章给你一个怎么在React中获取数据的演练。这没有外部状态管理的解决方案,像Redux或者MobX参与存储你获取到的数据。相反你将要使用React的本地状态管理。

内容列表

  • 在React组件树的什么位置获取数据?
  • 如何在React中获取数据?
  • 怎么展示加载标识和处理错误呢?
  • 如何在React中使用Axios获取数据
  • 在React怎么测试数据获取?
  • 怎么在React中使用Async/Await获取数据?
  • 如何在高阶组件中获取数据?
  • 怎么在渲染属性里获取数据?
  • 在React中怎么从GraphQL获取数据?

在React组件树的什么位置获取数据?

想象你已经有一个组件树,在它的层级中有多个级别的组件。现在你将要从第三方API获取一个列表项。现在,在你组件级别的哪个等级,更精确的讲,哪个特定组件,应该获取数据?这个基本上取决于三个标准:

1.谁对这个数据感兴趣?获取数据的组件应该是这些组件的公共父组件。

1. Who is interested in this data? The fetching component should be a common parent component for all these components.

                      +---------------+|               ||               ||               ||               |+------+--------+|+---------+------------+|                      ||                      |+-------+-------+     +--------+------+|               |     |               ||               |     |               ||  Fetch here!  |     |               ||               |     |               |+-------+-------+     +---------------+|+-----------+----------+---------------------+|                      |                     ||                      |                     |
+------+--------+     +-------+-------+     +-------+-------+
|               |     |               |     |               |
|               |     |               |     |               |
|    I am!      |     |               |     |     I am!     |
|               |     |               |     |               |
+---------------+     +-------+-------+     +---------------+||||+-------+-------+|               ||               ||     I am!     ||               |+---------------+

2.当异步请求数据的时候你想在哪里展示一个加载标识(加载标志,进度条)? 根据第一个标准,这个加载标识可以展示在公共父组件中。然后这个公共父组件还是获取数据的组件。

                      +---------------+|               ||               ||               ||               |+------+--------+|+---------+------------+|                      ||                      |+-------+-------+     +--------+------+|               |     |               ||               |     |               ||  Fetch here!  |     |               ||  Loading ...  |     |               |+-------+-------+     +---------------+|+-----------+----------+---------------------+|                      |                     ||                      |                     |
+------+--------+     +-------+-------+     +-------+-------+
|               |     |               |     |               |
|               |     |               |     |               |
|    I am!      |     |               |     |     I am!     |
|               |     |               |     |               |
+---------------+     +-------+-------+     +---------------+||||+-------+-------+|               ||               ||     I am!     ||               |+---------------+

**2.1.**但是当加载标识需要在更高级的组件中,数据获取也需要被提升到这个组件中。

                      +---------------+|               ||               ||  Fetch here!  ||  Loading ...  |+------+--------+|+---------+------------+|                      ||                      |+-------+-------+     +--------+------+|               |     |               ||               |     |               ||               |     |               ||               |     |               |+-------+-------+     +---------------+|+-----------+----------+---------------------+|                      |                     ||                      |                     |
+------+--------+     +-------+-------+     +-------+-------+
|               |     |               |     |               |
|               |     |               |     |               |
|    I am!      |     |               |     |     I am!     |
|               |     |               |     |               |
+---------------+     +-------+-------+     +---------------+||||+-------+-------+|               ||               ||     I am!     ||               |+---------------+

2.2. 当加载标识应该在公共父组件的每个子组件展示,不是每个子组件都需要数据,公共父组件应该还是获取数据的组件。然后这个加载标识状态可以传下来给那些感兴趣,需要展示加载标识的子组件。

                      +---------------+|               ||               ||               ||               |+------+--------+|+---------+------------+|                      ||                      |+-------+-------+     +--------+------+|               |     |               ||               |     |               ||  Fetch here!  |     |               ||               |     |               |+-------+-------+     +---------------+|+-----------+----------+---------------------+|                      |                     ||                      |                     |
+------+--------+     +-------+-------+     +-------+-------+
|               |     |               |     |               |
|               |     |               |     |               |
|    I am!      |     |               |     |     I am!     |
|  Loading ...  |     |  Loading ...  |     |  Loading ...  |
+---------------+     +-------+-------+     +---------------+||||+-------+-------+|               ||               ||     I am!     ||               |+---------------+

**3. 当请求失败的时候,你想在哪里展示可选的错误信息?**这个和第二个加载标识的标准使用一样的规则。
这基本上就是在React组件层次结构中获取数据的所有内容。但是什么时候获应该取数据,一旦公共父组件达成一致应该如何获取数据?

如何在React中获取数据?

React的ES6类组件有生命周期方法。render()生命周期方法强制返回一个React元素,因为毕竟你可能想在某一点展示获取到的数据。

另一个生命周期方法是获取数据的完美选择:componentDidMount()。当这个方法执行的时候,这个组件已经通过render()方法渲染了一次,但是将会在获取数据并通过组件的setState()方法将数据存储在本地后再次渲染。之后,本地状态可以被render()方法使用去展示,或者通过props向下传递。

componentDidMount()生命周期方法是获取数据最好的地方。但是怎么去获取数据? React的生态系统是一个灵活的框架

从而你可以选择你自己的方法去获取数据。为了简单起见,这篇文章将会使用浏览器原生fetch API展示它。它使用了JavaScript promise作为异步函数的结果。这是获取数据的最小示例,像下面这样:

import React, { Component } from 'react';class App extends Component {constructor(props) {super(props);this.state = {data: null,};}componentDidMount() {fetch('https://api.mydomain.com').then(response => response.json()).then(data => this.setState({ data }));}...
}export default App;

这是一个最基本React.js fetch API的例子。这个例子向你展示了在React怎么从API中获取JSON。然而,这边文章将要演示怎么从一个真实世界中第三方API中获取数据。

import React, { Component } from 'react';// -----------------------------------
const API = 'https://hn.algolia.com/api/v1/search?query=';
const DEFAULT_QUERY = 'redux';
// -----------------------------------class App extends Component {constructor(props) {super(props);this.state = {// -----------------------------------hits: [],// -----------------------------------};}componentDidMount() {// -----------------------------------fetch(API + DEFAULT_QUERY)// -----------------------------------.then(response => response.json())// -----------------------------------.then(data => this.setState({ hits: data.hits }));// -----------------------------------}...
}export default App;

这个例子使用Hacker News API,但是你可以使用你自己的API。当数据获取成功,数据将通过React的 this.setState()方法被存在本地状态中。然后 render方法将再次触发并且你可以展示获取到的数据。

...class App extends Component {...render() {const { hits } = this.state;return (<ul>{hits.map(hit =><li key={hit.objectID}><a href={hit.url}>{hit.title}</a></li>)}</ul>);}
}export default App;

即使render()方法已经在 componentDidMount()方法之前执行过一次,你不会遇到任何空指针异常,因为你在本地状态里有一个初始的空数组hits属性。

**注意:**如果你想知道怎么通过React Hooks特性获取数据,查看这个全面的指南如何在ReactHooks中获取数据(翻译)

怎么展示加载标识和处理错误呢?

当然你需要获取数据到你本地状态。但是还有什么?这里还有两个属性你可以存储在状态里:加载状态和错误状态。这些将提升你应用的用户体验。

加载状态应该用于指示一个异步请求在进行中。在render()方法之间,由于异步到达,获取数据在等待中。从而你可以在等待期间添加一个加载标识。在你获取数据的生命周期方法里,你必须将这个属性从false切换到true,当数据被获取到应该从true切换到false。

...class App extends Component {constructor(props) {super(props);this.state = {hits: [],// -----------------------------------isLoading: false,// -----------------------------------};}componentDidMount() {// -----------------------------------this.setState({ isLoading: true });// -----------------------------------fetch(API + DEFAULT_QUERY).then(response => response.json())// -----------------------------------.then(data => this.setState({ hits: data.hits, isLoading: false }));// -----------------------------------}...
}export default App;

在你的render()方法里你可以使用React的条件渲染去展示加载标识或者加载到的数据。

...class App extends Component {...render() {// -----------------------------------const { hits, isLoading } = this.state;// -----------------------------------// -----------------------------------if (isLoading) {return <p>Loading ...</p>;}// -----------------------------------return (<ul>{hits.map(hit =><li key={hit.objectID}><a href={hit.url}>{hit.title}</a></li>)}</ul>);}
}

一个加载标识可以向Loading…消息一样简单,但是你也可以使用第三方库区展示一个标识或者待定组件内容。你可以通过信号通知用户数据提取正在等待中。

你可以保持在你本地的第二个状态将是一个错误状态。当你的应用中发生一个错误,没什么比不给用户关于错误的标识更差的了。

...class App extends Component {constructor(props) {super(props);this.state = {hits: [],isLoading: false,// -----------------------------------error: null,// -----------------------------------};}...}

使用promise的时候经常在then()后面使用catch()块去处理错误。这就是为什么可以在原生的fetch API上使用catch()块。

...class App extends Component {...componentDidMount() {this.setState({ isLoading: true });fetch(API + DEFAULT_QUERY).then(response => response.json()).then(data => this.setState({ hits: data.hits, isLoading: false }))// -----------------------------------.catch(error => this.setState({ error, isLoading: false }));// -----------------------------------}...}

不幸的是,这个原生的fetch API不能使用catch块捕获每个错误的状态码。例如,当一个HTTP 404 发生了,并不会执行到catch块里。但是当你没有在结果中匹配到你希望的数据时,你可以通过抛出一个错误强制执行到catch块。

...class App extends Component {...componentDidMount() {this.setState({ isLoading: true });fetch(API + DEFAULT_QUERY)// -----------------------------------.then(response => {if (response.ok) {return response.json();} else {throw new Error('Something went wrong ...');}})// -----------------------------------.then(data => this.setState({ hits: data.hits, isLoading: false })).catch(error => this.setState({ error, isLoading: false }));}...}

最后但也很重要的是,你可以再次通过条件渲染在你的render()方法展示一个错误消息。

...class App extends Component {...render() {// -----------------------------------const { hits, isLoading, error } = this.state;// -----------------------------------// -----------------------------------if (error) {return <p>{error.message}</p>;}// -----------------------------------if (isLoading) {return <p>Loading ...</p>;}return (<ul>{hits.map(hit =><li key={hit.objectID}><a href={hit.url}>{hit.title}</a></li>)}</ul>);}
}

这就是使用简单的React获取数据的基础知识。你可以阅读有关在React的本地状态中管理所获取数据的更多信息,或者在React中独自管理状态诸如Redux之类的库。

如何在React中使用Axios获取数据

就像已经提到的,你可以使用其它库替代原生的fetch API。例如,另一个库可能每一个错误的请求都会到catch块中,不需要你自己向原先那样抛出一个错误。一个获取数据好的选择是axios库。你可以通过npm install axios在你的项目中安装axios,然后在你的项目中使用它替代原生的fetch API。让我们使用axios取代原生的fetch API在React中获取数据重构上一个项目。

import React, { Component } from 'react';
// -----------------------------------
import axios from 'axios';
// -----------------------------------const API = 'https://hn.algolia.com/api/v1/search?query=';
const DEFAULT_QUERY = 'redux';class App extends Component {constructor(props) {super(props);this.state = {hits: [],isLoading: false,error: null,};}componentDidMount() {this.setState({ isLoading: true });// -----------------------------------axios.get(API + DEFAULT_QUERY).then(result => this.setState({hits: result.data.hits,// -----------------------------------isLoading: false})).catch(error => this.setState({error,isLoading: false}));}...
}export default App;

就像你看到的,axios也返回了一个JavaScript promise对象。但是现在你不能解决这个promise两次,因为axios已经给你返回了一个JSON响应。

此外,当使用axios你可以确定所有错误都会在catch()块被捕捉。另外,你需要略微调整axios返回的数据结构就行。

在上一个例子里向你展示了怎么在React的componentDidMount生命周期方法里通过一个HTTP的GET方法获取数据。然而,你也可以通过一个按钮的点击来触发请求。然后你不需要使用生命周期方法,但是你可以使用自己的类方法。

import React, { Component } from 'react';
import axios from 'axios';const API = 'https://hn.algolia.com/api/v1/search?query=';
const DEFAULT_QUERY = 'redux';class App extends Component {constructor(props) {super(props);this.state = {hits: [],isLoading: false,error: null,};}// -----------------------------------getStories() {// -----------------------------------this.setState({ isLoading: true });axios.get(API + DEFAULT_QUERY).then(result => this.setState({hits: result.data.hits,isLoading: false})).catch(error => this.setState({error,isLoading: false}));}...
}export default App;

但是这只是React里的GET方法的使用。怎么通过API写入数据?当使用axios的时候,你也可以在React发送一个post请求。你也需要将axios.get()换成axios.post()

在React怎么测试数据获取?

所以怎么在React组件中测试数据获取呢?这里有一个关于测试话题的广泛的React测试教程,当你使用create-react-app建立你的应用,它已经带来了Jest测试框架和断言库。除此之外你也可以使用Mocha(测试框架)和Chai(断言库)来实现这些目的(记住功能会因为测试框架和断言库而变化)

当测试React组件的时候,在我的测试用例中,我经常依赖Enzyme去渲染组件。此外,当测试异步数据获取,Sinon有助于检查和模拟数据。

npm install enzyme enzyme-adapter-react-16 sinon --save-dev

首先你有你的测试体系,你可以在React脚本中写你第一个数据获取的测试套件

import React from 'react';
import axios from 'axios';import sinon from 'sinon';
import { mount, configure} from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';import App from './';configure({ adapter: new Adapter() });describe('App', () => {beforeAll(() => {});afterAll(() => {});it('renders data when it fetched data successfully', (done) => {});it('stores data in local state', (done) => {});
});

而一个测试用例应该在数据获取后在React组件成功渲染数据,提测测试用例验证数据被存储在本地状态里。或许测试两种情况是冗余的,因为当数据被渲染了,那么数据也应该被存在本地状态里了,但是只是为了展示,你会看到两个用例。

在所有测试之前,你希望使用模拟数据来存储您的axios请求。你可以为请求创建自己的JavaScript promise 并且之后可以使用它细腻的控制promise的解决。

...describe('App', () => {const result = {// -----------------------------------data: {hits: [{ objectID: '1', url: 'https://blog.com/hello', title: 'hello', },{ objectID: '2', url: 'https://blog.com/there', title: 'there', },],}};// -----------------------------------const promise = Promise.resolve(result);beforeAll(() => {// -----------------------------------sinon.stub(axios, 'get').withArgs('https://hn.algolia.com/api/v1/search?query=redux').returns(promise);// -----------------------------------});afterAll(() => {// -----------------------------------axios.get.restore();// -----------------------------------});...
});

在所有测试之后你应该再次确认移除了所有axios的存根。这句是异步数据获取测试的建立。现在让我们实现第一个测试:

...describe('App', () => {...it('stores data in local state', (done) => {const wrapper = mount(<App />);expect(wrapper.state().hits).toEqual([]);promise.then(() => {wrapper.update();expect(wrapper.state().hits).toEqual(result.data.hits);done();});});...
});

在测试中,你通过Enzyme的mount()函数开始渲染React组件,这个方法确保所有生命生命周期方法执行,并且所有子组件被渲染。

最初你可以在你组件本地状态的hit是一个空数组的时候有一个断言。这应该是正确的,因为你通过一个空数组初始化你的本地状态的hits属性。首先你解决了promise并且手动触发了组件的渲染,这个状态应该在数据获取后改变。

接下来,你可以测试所有内容是否相应呈现。这个测试和之前测试很像。

...describe('App', () => {...it('renders data when it fetched data successfully', (done) => {const wrapper = mount(<App />);expect(wrapper.find('p').text()).toEqual('Loading ...');promise.then(() => {wrapper.update();expect(wrapper.find('li')).toHaveLength(2);done();});});
});

在测试开始前,加载中标识应该被渲染。再次,一旦你解决了promise并且手动触发组件的渲染,应该有两个列表元素用于请求数据。

这些基本上就是React中关于数据获取测试你需要知道的。它不需要复杂。当有自己的promise,你可以精细控制合适解决promise和更新组件。之后你可以进行断言。之前展示的测试场景只是一个方法。例如,关于测试工具你不一定需要使用Sinon和Enzyme。

怎么在React中使用Async/Await获取数据?

至今,你只通过通用的方法then()catch()块去处理JavaScript promise。使用JavaScript中下一代异步请求怎么样?让我们使用async/await重构上一个数据获取的例子。

import React, { Component } from 'react';
import axios from 'axios';const API = 'https://hn.algolia.com/api/v1/search?query=';
const DEFAULT_QUERY = 'redux';class App extends Component {...// -----------------------------------async componentDidMount() {// -----------------------------------this.setState({ isLoading: true });// -----------------------------------try {const result = await axios.get(API + DEFAULT_QUERY);// -----------------------------------this.setState({hits: result.data.hits,isLoading: false});// -----------------------------------} catch (error) {// -----------------------------------this.setState({error,isLoading: false});// -----------------------------------}// -----------------------------------}...
}export default App;

当在React中获取数据的时候你可以使用async/await语句取代then()。async语句用于表示函数是异步执行的。它也可以使用在(React)类组件的方法上。await语句是在async函数内部每当执行异步函数时使用的。所以在等待的请求解决前下一行是不会执行的。此外,如果请求失败,一个try catch块可以用于捕获错误。

如何在高阶组件中获取数据?

在许多组件中使用它时,之前展示的获取数据的方法可以复用。一旦一个组件挂载,你想去获取数据并且展示条件加载标识和错误标识。这个组件入境可以分出两个职责:通过条件渲染展示获取到的数据和获取到远程数据之后存在本地状态里。而前者只用于渲染目的,后者可以通过高阶组件被重用。

注意:当你要去阅读链接的文章,你也将会看到你怎么在高阶组件中抽象条件渲染。在那之后,你的组件将只关心展示获取到的数据,没有任何条件渲染。

所以你怎样引入抽象高阶组件处理在React中的数据获取。首先你将会分离所有获取和存储逻辑到高阶组件中。

const withFetching = (url) => (Component) =>class WithFetching extends React.Component {constructor(props) {super(props);this.state = {data: null,isLoading: false,error: null,};}componentDidMount() {this.setState({ isLoading: true });axios.get(url).then(result => this.setState({data: result.data,isLoading: false})).catch(error => this.setState({error,isLoading: false}));}render() {return <Component { ...this.props } { ...this.state } />;}}

除了渲染,高阶组价中每个其他部分都取自上一个组件的数据正确提取的部分。另外,高阶组件使用接受到的一个url获取请求数据。如果你需要传递更多参数给告诫组件,你也可以扩展函数签名的参数列表。

const withFetching = (url, query) => (Comp) =>...

另外,告诫组件使用一个名叫data的通过用数据包裹本地状态。它不再像之前一样了解具体的属性名(e.g hits)

第二步,你可以部署所有来自你的App组件的数据获取和状态逻辑,因为它再也没有本地状态和生命周期方法。你可以通过函数式无状态组件重用它。传入的属性从特定命名改为通用数据属性。

const App = ({ data, isLoading, error }) => {if (!data) {return <p>No data yet ...</p>;}if (error) {return <p>{error.message}</p>;}if (isLoading) {return <p>Loading ...</p>;}return (<ul>{data.hits.map(hit =><li key={hit.objectID}><a href={hit.url}>{hit.title}</a></li>)}</ul>);
}

最后但也很重要的是,你可以使用高阶组件区包裹你的App组件。

const API = 'https://hn.algolia.com/api/v1/search?query=';
const DEFAULT_QUERY = 'redux';...const AppWithFetch = withFetching(API + DEFAULT_QUERY)(App);

基本上这就是在React中的抽离数据获取。通过使用告诫组件去获取数据,你可以轻松配置任何需要url获取数据的任何组件。另外,你可以扩展它通过查询参数就像之前展示过得。


#怎么在渲染属性里获取数据?

在React中可以在高阶组件和渲染属性里二选一。在React中使用渲染属性去数据获取也是可以的。

class Fetcher extends React.Component {constructor(props) {super(props);this.state = {data: null,isLoading: false,error: null,};}componentDidMount() {this.setState({ isLoading: true });axios.get(this.props.url).then(result => this.setState({data: result.data,isLoading: false})).catch(error => this.setState({error,isLoading: false}));}render() {return this.props.children(this.state);}
}

然后你可以再次向下面这样在你的App组件中使用渲染属性。

const API = 'https://hn.algolia.com/api/v1/search?query=';
const DEFAULT_QUERY = 'redux';...const RenderPropApproach = () =><Fetcher url={API + DEFAULT_QUERY}>{({ data, isLoading, error }) => {if (!data) {return <p>No data yet ...</p>;}if (error) {return <p>{error.message}</p>;}if (isLoading) {return <p>Loading ...</p>;}return (<ul>{data.hits.map(hit =><li key={hit.objectID}><a href={hit.url}>{hit.title}</a></li>)}</ul>);}}</Fetcher>

通过使用React的children属性作为渲染苏醒,你也可以从Fetcher组件传递所有本地状态。这就是你让所有条件渲染和最终渲染在你的属性渲染中的办法。

在React中怎么从GraphQL获取数据?

最后但也很重要的是,这篇文章应该很快提到React的GraphQL API。在React组件中你怎么用使用GraphQL API取代REST API获取数据(如今你使用的是哪个)?基本上它可以以同样的方式实现,因为GraphQL对网络层没有要求。大多数GraphQL API都是通过HTTP公开的,无论是否使用原生的fetch API还是axios进行查询。如果你感兴趣在React中如何通过GraphQL API获取数据,前往这篇文章:A complete React with GraphQL Tutorial。

你可以在这个github仓库找到完成的项目。你还有对于React中数据获取的建议吗?请联系我。你将这篇文章分享给其他学习如何在React中获取数据的人对我很有意义。

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

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

相关文章

使用Project Lombok减少Java应用程序中的样板代码

对Java编程语言最常提出的批评之一是它需要大量的样板代码 。 对于简单的类尤其如此&#xff0c;该类只需要存储一些值就可以。 您需要这些值的getter和setter&#xff0c;也许您还需要一个构造函数&#xff0c;覆盖equals&#xff08;&#xff09;和 hashcode&#xff08;&am…

DOM之城市二级联动

1、HTML内容 <select id"province"><option>请选择</option><option>山东省</option><option>吉林省</option><option>上海市</option></select><select id"city"><option>请选择…

跳转指令-JMP

page 60,132TITLE A0405Jump(EXE) JMP跳转指令.MODEL SMALL.STACK 64.DATAORG 100H ;规定程序的起始地址A10MAIN PROC NEARMOV AX,00MOV BX,00MOV CX,1A20: ADD AX,01ADD BX,AXSHL CX,1 ;左移一位JMP A20 ;跳转到A20A10MAIN endp jmp格式 [label:] jmp short/near/far/address…

java输出毫秒时间

SimpleDateFormat df new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");// 输出字符串System.out.println(df.format(new Date()));转载于:https://www.cnblogs.com/longchang/p/11139947.html

Three.js制作360度全景图

这是个基于three.js的插件&#xff0c;预览地址&#xff1a;戳这里 使用方法&#xff1a; 1、这个插件的用法很简单&#xff0c;引入如下2个js <script src"js/three.min.js"></script><script src"js/photo-sphere-viewer.min.js">&l…

C++资源库不完全版本

http://www.360doc.com/content/10/0414/20/59141_23072568.shtml boost graph...转载于:https://www.cnblogs.com/seon/archive/2011/08/08/2131246.html

babel6和babel7中关于polyfill和preset-env和babel-plugin-transform-runtime等总结

记录自己零散的收获&#xff0c;随笔。 一些基础 babel的作用是转换JS新的特性代码为大部分浏览器能运行的代码。 babel转码又分为两部分&#xff0c;一个是语法转换&#xff0c;一个是API转换。 对于API的转换又分为两部分&#xff0c;一个是全局API例如Promise&#xff0c…

十六、CI框架之数据库操作get用法

一、使用数据库的Get方法读取内容&#xff0c;如下代码&#xff1a; 二、数据库如下&#xff1a; 二、效果如下&#xff1a; 转载于:https://www.cnblogs.com/tianpan2019/p/11141809.html

使用Spring Boot和Spring MVC自定义HttpMessageConverters

为Spring Boot应用程序或直接的Spring MVC应用程序公开基于REST的终结点很简单&#xff0c;以下是一个控制器&#xff0c;该终结点公开了一个终结点&#xff0c;用于基于其发布的内容创建实体&#xff1a; RestController RequestMapping("/rest/hotels") public cl…

JS如何禁止别人查看网站源码

四种查看路径&#xff1a; 查看效果&#xff1a;猛戳 1、直接按F12 2、Ctrl Shift I查看 3、鼠标点击右键查看 4、Ctrl uview-source: url 把以上三种状态都屏蔽掉就可以了&#xff0c;document有onkeydown(键盘按键事件)&#xff0c;该事件里面找到对应的keycode并处理就…

JS相关知识总结(一)

总结下这段时间吸收的许多小知识&#xff0c;以备忘记后翻阅。 关于面向对象 面向对象特征&#xff1a; 具有唯一标识性具有状态具有行为 JS的面向对象和JAVA的实现思路不一样&#xff0c;JS是基于原型并非基于类。但是JS为了看起来更像JAVA&#xff0c;为此添加了一些特性…

WCF系列(二) -- 使用配置文件构建和使用WCF服务

当然&#xff0c;配置一个ServiceHost除了上面说的完全使用代码的方式&#xff0c;更好的方式是使用配置文件&#xff0c;把一些可能需要修改的属性跟代码分离&#xff0c;放到配置文件中&#xff0c;这样可以提供服务配置的灵活性&#xff0c;也更容易维护。 看看前面那个不用…

java读取文件方法

一、多种方式读文件内容。1、按字节读取文件内容2、按字符读取文件内容3、按行读取文件内容4、随机读取文件内容 Java代码 import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.io.IOExcept…

如何使用github搭建个人博客

1、去github官网注册个人帐号&#xff1a;没有的&#xff1a;猛戳这里去注册&#xff0c;比如我的账户名&#xff1a;wjf444128852&#xff0c;我的已经汉化(可在github里搜索github如何汉化有插件) 2、点击仓库-新建&#xff0c;仓库名字必须是&#xff1a;你的github帐号.git…

Spring Boot和Spring Data REST –通过REST公开存储库

使用Spring Boot和Spring Data REST&#xff0c;通过REST公开Spring Data存储库非常容易。 使用最少的代码&#xff0c;您可以创建遵循HATEOAS原理的JPA实体的REST表示。 我决定重用Spring PetClinic的JPA实体&#xff08;业务层&#xff09;作为本文的基础。 应用基础 PetCli…

记录一次cookie导致登录失败的惨案

现象描述&#xff1a; 前端登录成功后并没有从后端那里拿到登录信息&#xff0c;换句话说登录服务告诉我们登录成功了&#xff0c;但是后端却说我们没有登录成功。 背景&#xff1a; 因为前后端分离&#xff0c;所以前后端项目部署在两个子域名下。 因为要打通登录态&#…

sql中的遇到的有问题的

----题5&#xff1a;求出住在同一城市的顾客对--select city,count(cid) as 顾客的个数 from customers group by city--select --select distinct c1.cname,c2.cname,c1.city from customers c1, customers c2 where c1.cityc2.city and c1.cname<c2.cname select c1.cid,c…

nyoj 55 懒省事的小明 优先队列 multiset 还有暴力

懒省事的小明 时间限制&#xff1a; 3000 ms | 内存限制&#xff1a; 65535 KB难度&#xff1a; 3描述小明很想吃果子&#xff0c;正好果园果子熟了。在果园里&#xff0c;小明已经将所有的果子打了下来&#xff0c;而且按果子的不同种类分成了不同的堆。小明决定把所有的果子…

css3之3d导航

css3的新属性非常不错&#xff0c;目前IE除外其他浏览器都已支持 实现原理:比如元素a在hover时候可以改变元素b的状态。 效果如本农导航&#xff0c;欢迎采用和建议~ a:hover b{ 执行简单动画效果 } HTML <!DOCTYPE html><html lang"en"><head&…

jQuery Ajax – Servlets集成:构建完整的应用程序

网上有很多教程&#xff0c;它们解释了有关使用servlet和JSP页面进行Java Web开发的一些知识&#xff0c;但是&#xff0c;我从来没有找到对于初学者来说足够简洁&#xff0c;简单的教程。 这样的教程应该解释创建一个简单的Web应用程序的整个过程&#xff0c;包括前端&#xf…