在构建项目和原型之后
我们可能想找到一种方法来找到React front与Java API后端的连接。下面是一个使用Spring MVC的RESTful的例子,以及我们如何使用它。
1. Java Spring MVC RESTful
配置Spring MVC控制器并不太复杂。
@RestController
public class SearchController {
BasicInfoService basicInfoService = new BasicInfoService();
JiraInfoService jiraInfoService = new JiraInfoService();
CommitInfoService commitInfoService = new CommitInfoService();
GitBlameInfoService gitBlameInfoService = new GitBlameInfoService();
@RequestMapping(value="/api/BasicInfo",method = RequestMethod.GET)
public BasicInfoVO basicInfoSearch(@RequestParam String classPath){
System.out.println(classPath);
return basicInfoService.getBasicInfo(classPath);
}
@RequestMapping(value="/api/JiraInfo",method = RequestMethod.GET)
public JiraInfoVO jiraInfoSearch(@RequestParam String location){
System.out.println(location);
return jiraInfoService.getJiraInfo(location);
}
@RequestMapping(value="/api/CommitHistory",method = RequestMethod.GET)
public List<CommitHistoryVO> commitHistorySearch(@RequestParam String location){
return commitInfoService.getCommitHistory(location);
}
@RequestMapping(value="/api/GitBlameInfo",method = RequestMethod.GET)
public GitBlameInfoVO gitBlameInfoSearch(@RequestParam String location,@RequestParam String line){
return gitBlameInfoService.getBlameData(location,line);
}
@RequestMapping(value = "/api/ClassTeamMapping",method = RequestMethod.POST, produces = "application/json")
public List<String> getGitClassTeamMapping(@RequestBody List<String> classes){
List<String> re = new ArrayList<String>();
for(int i = 0;i<classes.size();i++){
String className = classes.get(i);
List<String> classTeamInfos = basicInfoService.getClassTeamInfoByClassName(className);
for(int j = 0; j< classTeamInfos.size();j++){
re.add(classTeamInfos.get(j));
}
}
return re;
}
}
我们只需要在类注解添加@RestController。在@RequestMapping部分,我们还可以添加REST api的路由,方法。
返回值可以自动传输到JSON对象。这个Spring MVC RESTful框架将把一个对象转换成json。
这里是spring-dispatcher-servlet.xml的配置
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!-- 扫描controller(controller层注入) -->
<context:component-scan base-package="com.successfactors.classexceptionanalyze.controller"/>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"/>
<property name="maxUploadSize" value="2000000"/>
</bean>
<mvc:resources mapping="/static/**" location="/static/"/>
<mvc:default-servlet-handler />
</beans>
通过所有这些配置,我们可以轻松地获得所需的RESTful内容。
2. REACT Http call
下面是REACT使用superagent将http请求调用到其后台的示例。
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import BasicInfo from './BasicInfoPanel'
import JiraInfo from './JiraInfoPanel'
import ClassCommitHistory from './ClassCommitHistoryPanel'
import ExceptionAnalyze from './ExceptionLineAnalyzePanel'
import request from 'superagent'
import {apis} from './common'
export default class Report extends React.Component {
constructor(props) {
super(props);
this.state = {
classPath: this.props.params.classPath,
lineNumber: this.props.params.lineNumber
}
}
render() {
return (
<div>
<div className="row">
<div className="col-md-10 col-md-offset-1">
<h1 align="center">Class Exception Report</h1>
</div>
</div>
<div className="col-lg-6">
<BasicInfo info={this.state.basicInfo}/>
<JiraInfo info={this.state.jiraInfo}/>
<ClassCommitHistory info={this.state.commitHistory}/>
</div>
<div className="col-lg-6">
<ExceptionAnalyze info={this.state.exceptionAnalyze}/>
</div>
</div>
);
}
componentDidMount() {
request.get(apis.basicInfo(this.state.classPath)).end((err, resp) => {
if (err) {
return;
}
if (resp.error) {
return;
}
const result = resp.body;
console.log(result);
if (result) {
this.setState({basicInfo: result});
this.inqueryJiraInfo(result.location);
this.inqueryCommitHistoryInfo(result.location);
this.inqueryGitBlameInfo(result.location, this.state.lineNumber);
}
})
}
inqueryGitBlameInfo(location, line) {
request.get(apis.gitblameInfo(location, line)).end((err, resp) => {
if (err) {
return;
}
if (resp.error) {
return;
}
const result = resp.body;
console.log(result);
if (result) {
this.setState({exceptionAnalyze: result});
}
})
}
inqueryJiraInfo(location) {
request.get(apis.jiraInfo(location)).end((err, resp) => {
if (err) {
return;
}
if (resp.error) {
return;
}
const result = resp.body;
console.log(result);
if (result) {
this.setState({jiraInfo: result});
}
})
}
inqueryCommitHistoryInfo(location) {
request.get(apis.commitInfo(location)).end((err, resp) => {
if (err) {
return;
}
if (resp.error) {
return;
}
const result = resp.body;
console.log(result);
if (result) {
this.setState({commitHistory: result});
}
})
}
}
我们可以看看这个方法。
首次调用render()方法后,将自动调用componentDidMount()方法。下面是http请求方法:
request.get(API).end((err,resp) => {
if(err){
/** **/
}
if(resp.error){
/** **/
}
const result = resp.body;
if(result){
/** Your method **/
}
})
通过这个函数,我们将得到我们需要的信息,并更新组件的状态,这样它将再次呈现前端。
这就是我们如何使用http请求并对分离的前端和后端做出反应。
由此问题,延伸出了下一个问题,ajax跨域,详情见下节。