Java开发全终端实战租房项目-开发GraphQL服务以及前台系统搭建

使用GraphQL开发房源接口

实现根据id查询房源的dubbo服务

定义接口方法
在itcast-haoke-manage-dubbo-server-house-resources-dubbo-interface中:
package cn.itcast.haoke.dubbo.server.api;

/**
     * 根据id查询房源数据
     *
     * @param id
     * @return
     */
    HouseResources queryHouseResourcesById(Long id);

实现接口
在itcast-haoke-manage-dubbo-server-house-resources-dubbo-service中:
package cn.itcast.haoke.dubbo.server.api;

@Override
    public HouseResources queryHouseResourcesById(Long id) {
   
        return this.houseResourcesService.queryHouseResourcesById(id);
    }

业务Service实现
在itcast-haoke-manage-dubbo-server-house-resources-dubbo-service中:
package cn.itcast.haoke.dubbo.server.service.impl;

@Override
    public HouseResources queryHouseResourcesById(Long id) {
   
        return super.queryById(id);
    }

引入graphql-java依赖

itcast-haoke-manage-api-server的pom.xml

<dependency>
            <groupId>com.graphql-java</groupId>
            <artifactId>graphql-java</artifactId>
            <version>11.0</version>
        </dependency>

编写haoke.graphqls文件

在resources目录下创建haoke.graphqls文件:

schema {
   
    query: HaokeQuery
}

type HaokeQuery {
   
    HouseResources(id:Long) : HouseResources
    HouseResourcesList(page:Int, pageSize:Int) : TableResult
    IndexAdList:IndexAdResult
}

scalar Long

type HouseResources {
   
    id:Long!
    title:String
    estateId:Long
    buildingNum:String
    buildingUnit:String
    buildingFloorNum:String
    rent:Int
    rentMethod:Int
    paymentMethod:Int
    houseType:String
    coveredArea:String
    useArea:String
    floor:String
    orientation:String
    decoration:Int
    facilities:String
    pic:String
    houseDesc:String
    contact:String
    mobile:String
    time:Int
    propertyCost:String
}

type TableResult{
   
    list:[HouseResources]
    pagination:Pagination
}

type Pagination{
   
    current:Int
    pageSize:Int
    total:Int
}

type IndexAdResult{
   
    list:[IndexAdResultData]
}

type IndexAdResultData{
   
    original:String
}

编写GraphQLController

package cn.itcast.haoke.dubbo.api.controller;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import graphql.GraphQL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@RequestMapping("graphql")
@Controller
@CrossOrigin
public class GraphQLController {
   

    @Autowired
    private GraphQL graphQL;

    private static final ObjectMapper MAPPER = new ObjectMapper();


    /**
     * 实现GraphQL查询
     *
     * @param query
     * @return
     */
    @GetMapping
    @ResponseBody
    public Map<String, Object> query(@RequestParam("query") String query) {
   
        return this.graphQL.execute(query).toSpecification();
    }

}

编写GraphQLProvider

在GraphQLProvider中,需要与Spring整合,并且将GraphQL对象载入到Spring容器。

package cn.itcast.haoke.dubbo.api.graphql;

import graphql.GraphQL;
import graphql.schema.GraphQLSchema;
import graphql.schema.idl.RuntimeWiring;
import graphql.schema.idl.SchemaGenerator;
import graphql.schema.idl.SchemaParser;
import graphql.schema.idl.TypeDefinitionRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.List;

// 实现的功能:将GraphQL对象载入到Spring容器,并且完成GraphQL对象的初始化的功能
@Component
public class GraphQLProvider {
   

    private GraphQL graphQL;

    @Autowired
    private List<MyDataFetcher> myDataFetchers;

    //实现对GraphQL对象的初始化
    @PostConstruct
    public void init() throws FileNotFoundException {
   
        File file = ResourceUtils.getFile("classpath:haoke.graphqls");
        this.graphQL = GraphQL.newGraphQL(buildGraphQLSchema(file)).build();

    }

    private GraphQLSchema buildGraphQLSchema(File file) {
   
        TypeDefinitionRegistry typeRegistry = new SchemaParser().parse(file);
        return new SchemaGenerator().makeExecutableSchema(typeRegistry, buildWiring());
    }

    private RuntimeWiring buildWiring() {
   
        return RuntimeWiring.newRuntimeWiring()
                .type("HaokeQuery", builder -> {
   
                            for (MyDataFetcher myDataFetcher : myDataFetchers) {
   
                                builder.dataFetcher(myDataFetcher.fieldName(),
                                        environment -> myDataFetcher.dataFetcher(environment));
                            }
                            return builder;
                        }

                )
                .build();
    }

    @Bean
    public GraphQL graphQL() {
   
        return this.graphQL;
    }

}

优化改进GraphQLProvider逻辑

编写MyDataFetcher接口

package cn.itcast.haoke.dubbo.api.graphql;

import graphql.schema.DataFetchingEnvironment;

public interface MyDataFetcher {
   

    /**
     * GraphQL中查询的名称
     *
     * @return
     */
    String fieldName();

    /**
     * 数据的查询
     *
     * @param environment
     * @return
     */
    Object dataFetcher(DataFetchingEnvironment environment);

}

编写实现类HouseResourcesDataFetcher

package cn.itcast.haoke.dubbo.api.graphql;

import cn.itcast.haoke.dubbo.api.service.HouseResourcesService;
import graphql.schema.DataFetchingEnvironment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class HouseResourcesDataFetcher implements MyDataFetcher {
   

    @Autowired
    private HouseResourcesService houseResourcesService;

    @Override
    public String fieldName() {
   
        return "HouseResources";
    }

    @Override
    public Object dataFetcher(DataFetchingEnvironment environment) {
   
        Long id = environment.getArgument("id");
        return this.houseResourcesService.queryHouseResourcesById(id);
    }
}

在这里插入图片描述

实现查询房源列表接口

新增HouseResourcesListDataFetcher实现

package cn.itcast.haoke.dubbo.api.graphql;

import cn.itcast.haoke.dubbo.api.service.HouseResourcesService;
import graphql.schema.DataFetchingEnvironment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class HouseResourcesListDataFetcher implements MyDataFetcher {
   

    @Autowired
    private HouseResourcesService houseResourcesService;

    @Override
    public String fieldName() {
   
        return "HouseResourcesList";
    }

    @Override
    public Object dataFetcher(DataFetchingEnvironment environment) {
   
        Integer page = environment.getArgument("page");
        if(null == page){
   
            page = 1;
        }
        Integer pageSize = environment.getArgument("pageSize");
        if(null == pageSize){
   
            pageSize = 5;
        }

        return this.houseResourcesService.queryList(null, page, pageSize);
    }
}

在这里插入图片描述

测试

{
   
HouseResourcesList(page:1, pageSize:2) {
   
list{
   
id
estateId
buildingNum
rent
contact
mobile
}
pagination{
   
current
pageSize
total
}
}
}

在这里插入图片描述

搭建前台系统

好客租房项目是采用前后端分离开发模式,前端系统由前端团队进行开发,接下来我们需要整合前端,前端是使用React+semantic-ui实现移动端web展示,后期可以将web打包成app进行发布
在这里插入图片描述

搭建工程(前台系统前端)itcast-haoke-web

第一步,将资料中的haoke-web.zip解压到项目目录
在这里插入图片描述
第二步,导入到idea中
在这里插入图片描述
在这里插入图片描述
第三步,执行命令进行初始化和导入相关依赖包

npm install #安装依赖
npm start #启动服务

测试地址:http://localhost:9000/

在这里插入图片描述

搭建api工程(前台系统后端)itcast-haoke-web-api

前端团队在开发时,没有采用mock的方式,而是采用了使用node.js开发服务端的方式进行了demo化开发。所以,我们也需要将该服务搭建起来,以便进行开发
第一步,将资料中的haoke-web-api.zip解压到项目目录,我的是:F:\code\itcast-haoke\itcast-haoke-webapi
在这里插入图片描述
第二步,创建数据库
创建myhome数据库,并且执行资料中的myhome.sql脚本。
在这里插入图片描述

第三步,修改配置文件
在这里插入图片描述
修改成自己的mysql配置:
在这里插入图片描述
第四步,输入命令进行初始化和启动服务

#脚本如下
"scripts": {
   
"test": "cross-env NODE_ENV=config-test node app.js",
"dev": "cross-env NODE_ENV=config-dev node app.js", #设置环境变量
"pro": "cross-env NODE_ENV=config-pro node app.js"
}

可以看出调用的配置文件是config-dev.js

npm cache clear --force
npm install #安装依赖
npm run dev #启动dev脚本

在这里插入图片描述
测试地址:http://127.0.0.1:8086/

登录系统进行测试

在users系统中查询到用户的信息如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
首页

前台系统实现分析

目录结构
在这里插入图片描述
加载数据流程
以首页为例,查看数据加载流程。
打开src/modules/home/home.js文件可以看到,在组件加载完成后进行加载数据:

componentDidMount = () => {
   
    let swipe = new Promise((resolve, reject) => {
   
        client.query({
   query: GET_INDEX_ADS}).then(result =>
            resolve(result.data.IndexAdList.list));
    })

    let menu = new Promise((resolve, reject) => {
   
        axios.post('/homes/menu').then((data)=>{
   
            resolve(data.data.list);
        });
    })
    let info = new Promise((resolve, reject) => {
   
      axios.post('/homes/info').then((data)=>{
   
        resolve(data.data.list);
      });
    })
    let faq = new Promise((resolve, reject) => {
   
      axios.post('/homes/faq').then((data)=>{
   
        resolve(data.data.list);
      });
    })
    let house = new Promise((resolve, reject) => {
   
      axios.post('/homes/house').then((data)=>{
   
        resolve(data.data.list);
      });
    })

  }

通过axios进行加载数据,在App.js中对axios进行了全局的配置:

//设置全局的baseUrl配置
axios.defaults.baseURL = config.apiBaseUrl;
//设置拦截器
axios.interceptors.request.use(function (config) {
   
  //在发送请求之前获取mytoken值
  if(!config.url.endsWith('/login')){
   
    config.headers.Authorization = localStorage.get
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值