[web开发]vue+springboot+echart微博爬虫展示平台

aoru45      2022-04-16     794

关键词:

1.微博登录

2.爬取数据

3.mysql存储

4.pyechart本地展示

5.用vue搭建网站web展示

 

1.微博登录

新浪微博的登录不是简单的post就能解决的,他的登录有加密,所以我们要使用一定的解密算法才能正常登录微博,得到我们想要的数据。

先不要慌,第一步当然是import我们需要的库

from urllib import request,parse
import http.cookiejar
import base64
import json
import rsa
import binascii
from PIL import Image
from bs4 import BeautifulSoup
import pymysql

要登录,那肯定要先拿到验证码

    def GetCode(self):
        url="https://login.sina.com.cn/cgi/pin.php?r=694905&s=0&p=gz-52086a8a846fadcdacf4fb058324aa387858"#验证码地址
        img=self.opener.open(url)
        f=open(vv.png,wb)
        f.write(img.read())
        f.close()
        im=Image.open(vv.png)
        im.show()

拿到了验证码还不够,登录之前还有个预登录,拿到我们后面加密需要的参数

def prelogin(self):
        url="https://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=NDc5MTkyNzQyJTQwcXEuY29t&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.19)&_=1529471491358"
        a=self.opener.open(url).read().decode(utf-8)
        a=a[a.find("(")+1:a.find(")")]
        b=json.loads(a)
        return b
‘’‘
sinaSSOController.preloginCallBack({"retcode":0,"servertime":1540617565,"pcid":"gz-65c55b3534f8a1df1330b4708fb6d1b57273","nonce":"ONED4A","pubkey":"EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443","rsakv":"1330428213","is_openlock":0,"showpin":0,"exectime":10})’‘’

然后用这些参数对登录参数进行加密,说实在话具体的加密细节我也不记得了,当时做的时候拿了个记事本把所有东西记下来然后分析,也查了很多博客的资料才做好。

def GetMixUser(self,username,password):
        username_struct={username:username}
        rsaPubkey=int(self.pre[pubkey],16)
        key=rsa.PublicKey(rsaPubkey, 65537)
        message = str(self.pre[servertime]) + 	 + self.pre[nonce] + 
 + password
        passwd = rsa.encrypt(message.encode(utf-8), key)
        upass = binascii.b2a_hex(passwd)
        uname=base64.b64encode(parse.urlencode(username_struct).encode(utf-8)).decode(utf-8)[12:]
        mix={uname:uname,upass:upass.decode(utf-8)}
        return mix

拿到加密后的登录参数,可以提交了

def login(self,username,password,code):
        mix=self.GetMixUser(username,password)
        uname=mix[uname]
        upass=mix[upass]
        url="https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)"
        print("登录中……")
        postData={
            "door":code,
            "encoding":"utf-8",
            "entry":"weibo",
            "from":"null",
            "gateway":1,
            "nonce":self.pre[nonce],
            "prelt":72,
            "pwencode":"rsa2",
            "qrcode_flag":False,
            "returntype":"META",
            "savestate":7,
            "servertime":self.pre[servertime],
            "service":"miniblog",
            "rsakv":self.pre[rsakv],
            "su":uname,
            "sp":upass,
            "url":"https://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack",
            "useticket":1,
            "vsnf":1
        }
        postData=parse.urlencode(postData).encode(utf-8)
        result=self.opener.open(url,postData).read().decode(gbk)
        url1=result[result.find("replace")+9:result.find())-1]
        result=self.opener.open(url1).read().decode("gbk")
        if(result.find("身份")!=-1):
            return False
        result=result[result.find(location)+18:]
        url2=result[:result.find())-1]
        self.opener.open(url2).read().decode("gbk")
        return True

2.爬取信息

先得到用户follow的列表

    def GetUserList(self,uid,pageNum):
        url="https://weibo.com/"+str(uid)+"/follow?page="+str(pageNum)
        try:
            result=self.opener.open(url).read().decode(utf-8)
            html = result.replace(\n, ‘‘).replace(\t, ‘‘).replace(\r, ‘‘).replace(\, ‘‘)
            html = html[html.find("<!--关注/粉丝列表-->"):html.find("<!--关欧盟隐私协议弹窗-->")]
            soup = BeautifulSoup(html, "html.parser")
            list_a = soup.findAll(name=div, attrs={"class": "info_name W_fb W_f14"})
            name = []
            uid = []
            for a in list_a:
                try:
                    b = a.find(name="a")
                    b = b[usercard]
                    b = b[3:13:]
                    uid.append(b)
                    name.append(a.text)
                    print("加入用户:" + a.text)
                except:
                    print("No Data")
            dic = {"name": name, "uid": uid}
            return dic
        except:
            pass

再拿到这些用户的主页微博言论,我们得到他们发的所有博文

def GetTalks(self,uid):
        rlist = []
        i=0
        html=""
        while(True):
            try:
                result=self.opener.open("https://weibo.com/u/"+str(uid)+"?page="+str(i)).read().decode("utf-8")
                html = result.replace("\t", "").replace("\n", "").replace("\r", "").replace("\", "")
                html = html[html.find("<div class="WB_feed WB_feed_v3 WB_feed_v4""):]
            except:
                pass
            soup=BeautifulSoup(html,"html.parser")
            list_a = soup.find_all(name="div", attrs={"class": "WB_text W_f14"})
            i = i + 1
            if list_a:
                print("" + str(i) + "")
                for a in list_a:
                    at=a.text
                    at=at.replace(" ","")
                    if at:
                        rlist.append(at)
                        print("内容存入:"+at)
            else:
                break
        return rlist

3.数据存储

我暂时只做了这些,然后存储到数据库吧。mysql的基础语句很简单,我也就会这么几句,不会的百度吧。。

def sqllogin(self):
        db=pymysql.connect(host=localhost,user=root,db=weibouser,passwd=root,charset=utf8mb4)
        return db
    def sqlProcess(self,db):
        while(True):
            cursor=db.cursor()
            cursor.execute("SELECT * FROM USERS WHERE TAG =1")           #1 表示 未处理 2 表示 正在处理 3 表示完成处理
            result=cursor.fetchone()
            if(result):
                cursor.execute("UPDATE USERS SET TAG=2 WHERE USERID=‘%s‘" % (result[2]))
                talks=self.GetTalks(uid=result[2])
                for i in range(1,4):
                   uids=""
                   names=""
                   userlist = self.GetUserList(uid=result[2], pageNum=i)
                   try:
                        uids=userlist[uid]
                        names=userlist[name]
                   except:
                       break
                   if int(result[4])!=3:
                       for t in range(len(uids)):
                           try:
                               if self.IfExist(db,"users","name",names[t])==False:
                                    cursor.execute("INSERT INTO USERS (NAME,USERID,TAG,CLASS) VALUES (‘%s‘,‘%s‘,%d,%d)" % (names[t], uids[t], 1, int(result[4])+1))  # 数据库写userlist
                                    cursor.execute("INSERT INTO FOLLOWS (USERID,FUID,FUNAME) VALUES (‘%s‘,‘%s‘,‘%s‘)" % (result[2], uids[t],names[t]))
                           except:
                               print("Error")
                for talk in talks:
                    try:
                        cursor.execute("INSERT INTO USERTALKS (USERID,NAME,TALK)VALUES (‘%s‘,‘%s‘,‘%s‘)" % (result[2],result[1],talk))#数据库写评论
                    except:
                        print("Error")
                cursor.execute("UPDATE USERS SET TAG=3 WHERE USERID=‘%s‘"%(result[2]))
            else:
                break
    def AnotherProcess(self,db):
        cursor=db.cursor();
        cursor.execute("SELECT * FROM USERS WHERE 1");
        results=cursor.fetchall()
        for result in results:
            sex=""
            try:
                r = self.opener.open("https://weibo.com/u/"+result[2]).read().decode("utf-8")
                html = r.replace("\t", "").replace("\n", "").replace("\r", "").replace("\", "")
                if html.find("female") == -1:
                    sex=""
            except:
                pass
            soup = BeautifulSoup(html, "html.parser")
            keywords=soup.find(attrs={"name":"keywords"})[content]
            description=soup.find(attrs={"name":"description"})[content]
            cursor.execute("INSERT INTO USERDETAILS (NAME,DESCRIPTION,KEYWORDS,SEX)VALUES(‘{}‘,‘{}‘,‘{}‘,‘{}‘)".format(result[1],description,keywords,sex))

4.echart本地展示

import pymysql
from pyecharts import Graph
class DrawCharts:
    raw_nodes = []
    links = []
    def __init__(self):
        self.CreatRelation()
        self.DrawCharts()
    def CreatRelation(self):
        db=pymysql.connect(host=localhost,user=root,db=weibouser,passwd=root,charset=utf8mb4)
        cursor=db.cursor()
        cursor.execute("SELECT * FROM USERS WHERE 1");
        users=cursor.fetchall()
        for user in users:#上海大学
            cursor.execute("SELECT * FROM FOLLOWS WHERE USERID=‘%s‘"%(user[2]));
            results=cursor.fetchall()
            if results:
                for result in results:
                    links.append({"source":user[1],"target":result[4]})
                    print(user[1]+"->"+result[4])
        for i in range(3):
            cursor.execute("SELECT * FROM USERS WHERE CLASS=%d"%(i+1))
            results=cursor.fetchall()
            for result in results:
                self.raw_nodes.append({"name": result[1], "symbolSize": 30-i*13,"category":i})


        db.close()
    def DrawCharts(self):
        graph = Graph("微博关注关系图", width=1200, height=600)
        categories=[
            {
            "name":"一级深度",
            "itemStyle":
                {
                    "normal":{
                        "color":#CC0033,
                        "borderColor": "#5182ab",
                        "borderWidth": 1.8,
                        "show":"True"
                    }
                }
            },
            {
                "name": "二级深度",
                "itemStyle":
                    {
                        "normal": {
                            "color": #f44242,
                            "borderColor": "#5182ab",
                            "borderWidth": 1.8,
                            "show":"True"
                        }
                    }
            },
            {
                "name": "三级深度",
                "itemStyle":
                    {
                        "normal": {
                            "color": #663366,
                            "borderColor": "#5182ab",
                            "borderWidth": 1.8,
                            "show":"True"
                        }
                    }
            }
        ]
        graph.add("",self.raw_nodes,self.links,label_pos="right",graph_repulsion=10, is_legend_show=False,categories=categories,
                  label_text_color=None,is_label_show=True)
        graph.render()

效果就不发了,运行起来比较卡,因为节点太多了,当时老师说怎么怎么加速,也不说细节,我当时一脸懵逼,也就没管了,大不了减少节点数量嘛。

5.web展示

前端两段关键代码。。

<style scoped>
  .layout-con{
    height: 100%;
    width: 100%;
  }
  .menu-item span{
    display: inline-block;
    overflow: hidden;
    width: 69px;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
    transition: width .2s ease .2s;
  }
  .menu-item i{
    transform: translateX(0px);
    transition: font-size .2s ease, transform .2s ease;
    vertical-align: middle;
    font-size: 16px;
  }
  .collapsed-menu span{
    width: 0px;
    transition: width .2s ease;
  }
  .collapsed-menu i{
    transform: translateX(5px);
    transition: font-size .2s ease .2s, transform .2s ease .2s;
    vertical-align: middle;
    font-size: 22px;
  }
</style>
<template>
  <div class="layout">
    <Layout :style="{minHeight: ‘100vh‘}">
      <Sider collapsible :collapsed-width="78" v-model="isCollapsed">
        <Menu active-name="1-1" theme="dark" width="auto" :class="menuitemClasses">
          <MenuItem name="1-1" @click.native="tab_search_onclick()">
            <Icon type="search"></Icon>
            <span>搜索</span>

          </MenuItem>
          <MenuItem name="1-2" @click.native="tab_follow_onclick()">
            <Icon type="person"></Icon>
            <span>follow关系</span>
          </MenuItem>
          <MenuItem name="1-3" @click.native="tab_words_onclick()">
            <Icon type="cloud"></Icon>
            <span >热词云图</span>
          </MenuItem>
        </Menu>
      </Sider>
      <Layout>
        <Header :style="{background: ‘#fff‘, boxShadow: ‘0 2px 3px 2px rgba(0,0,0,.1)‘,height:‘100px‘}">
          <img src="../assets/logo.png" style="height: 100%"/>
        </Header>
        <Content :style="{padding: ‘0 16px 16px‘}">

          <Card style="margin-top: 20px">
            <p slot="title">{{Content_Title}}</p>
            <div style="height: 650px">
              <div v-show="v_search">
                  <div style="margin-bottom: 30px;margin-top: 30px">
                    <Input v-model="input_word" icon="ios-clock-outline" placeholder="请输入微博用户名称!" style="width: 250px;margin-right: 10px"></Input>
                    <Button type="primary" shape="circle" icon="ios-search" @click="fs_search">查询</Button>
                  </div>
                  <div style="width: 50%;margin: auto">
                    <Card :bordered="true" style="height: 350px;text-align: left">
                      <p slot="title">{{Search_Card_Title}}</p>
                      <p v-for="item in items" style="height: 70px">{{item.message}}</p>
                    </Card>
                  </div>
              </div>
              <div v-show="v_follows">
                <div style="width: 80%;margin: auto">
                  <Card :bordered="true" style="height: 580px;width: 100%;margin-top: 50px">
                    <p slot="title">{{Follow_Card_Title}}</p>
                    <div id="Follow_Chart" style="height: 500px;width:800px;margin: auto;"></div>
                  </Card>
                </div>

              </div>
              <div v-show="v_words">
                <div style="width: 50%;margin: auto">
                  <Card :bordered="true" style="height: 330px;margin-top:50px ">
                    <p slot="title">{{Words_Card_Title}}</p>
                    <div id="Words_Chart" style="height: 250px;width:500px;margin: auto"></div>
                  </Card>
                </div>
              </div>
            </div>
          </Card>
        </Content>
      </Layout>
    </Layout>
  </div>
</template>
<script>
  let echarts = require(echarts);
  require(echarts-wordcloud);
  require("echarts/lib/chart/graph/forceLayout");
  export default {
    data () {
      return {
        isCollapsed: false,
        items:[],
        Search_Card_Title:搜索结果,
        Content_Title:"资料搜索",
        Follow_Card_Title:"关系图绘制结果",
        Words_Card_Title:"词云绘制结果",
        input_word:‘‘,
        v_search:true,
        v_follows:false,
        v_words:false
      };
    },
    computed: {
      menuitemClasses: function () {
        return [
          menu-item,
          this.isCollapsed ? collapsed-menu : ‘‘
        ]
      }
    },
    methods:{
      fs_search(){
        let axios=this.$axios;
        let word=this.input_word;
        function getDetails(){
          return axios.get("http://localhost:9090/details?name="+word);
        }
        function getUsers(){
          return axios.get("http://localhost:9090/words?name="+word);
        }
        function getNodes() {
          return axios.get("http://localhost:9090/nodes?name="+word);
        }
        function getLinks(){
          return axios.get("http://localhost:9090/links?name="+word);
        }

        axios.all([getDetails(),getUsers(),getNodes(),getLinks()]).then(axios.spread((details,users,nodes,links)=>{
          this.draw_relations(nodes.data,links.data);
          this.set_details(details.data);
          this.draw_words(users.data);
          this.$Notice.success({
            title: 绘制成功,
            desc: 您搜索的用户+word+关系图和热词已经成功绘制!
          });
        })).catch(res=>{
          this.$Notice.error({
            title: 绘制失败,
            desc: 您搜索的用户+word+关系图或热词绘制失败,请检查网络或输入信息!
          });
        })
      },
      tab_search_onclick:function(){
        this.v_search=true;
        this.v_follows=false;
        this.v_words=false;
        this.Content_Title="资料搜索"
      },
      tab_follow_onclick:function(){
        this.v_follows=true;
        this.v_words=false;
        this.v_search=false;
        this.Content_Title="follow关系";
      },
      draw_words:function(words_data){
        let mychart=echarts.init(document.getElementById(Words_Chart));
        mychart.setOption({
          tootip: {
            show: true
          },
          series: {
            name: 词云图,
            type: wordCloud,
            textStyle: {
              normal: {
                color: function () {
                  return rgb( + [
                    Math.round(Math.random() * 160),
                    Math.round(Math.random() * 160),
                    Math.round(Math.random() * 160)
                  ].join(,) + )
                }
              }
            },
            textRotation: [0, 90, -45, 45],
            autoSize: true,
            data:
            words_data
          }
        })
      },
      set_details(details){
          this.items.push({"message":"微博名:"+details["name"]});
          this.items.push({"message":"微博描述:"+details["description"]});
          this.items.push({"message":"关键词:"+details["keywords"]});
          this.items.push({"message":"用户性别:"+details["sex"]});
      },
      draw_relations:function(nodes,links){
        let mychart=echarts.init(document.getElementById("Follow_Chart"));
        let option={
          title: {                    // 图表标题
            text: "关注关系图",           // 标题文本
            left : 3%,                    // 标题距离左侧边距
            top : 3%,                     // 标题距顶部边距
            textStyle : {                       // 标题样式
              color : #000,                     // 标题字体颜色
              fontSize : 30,                    // 标题字体大小
            }
          },


          series: [{
            type: "graph",          // 系列类型:关系图
            top: 10%,             // 图表距离容器顶部的距离
            roam: true,             // 是否开启鼠标缩放和平移漫游。默认不开启。如果只想要开启缩放或者平移,可以设置成 ‘scale‘ 或者 ‘move‘。设置成 true 为都开启
            focusNodeAdjacency: true,   // 是否在鼠标移到节点上的时候突出显示节点以及节点的边和邻接节点。[ default: false ]
            force: {                // 力引导布局相关的配置项,力引导布局是模拟弹簧电荷模型在每两个节点之间添加一个斥力,每条边的两个节点之间添加一个引力,每次迭代节点会在各个斥力和引力的作用下移动位置,多次迭代后节点会静止在一个受力平衡的位置,达到整个模型的能量最小化。
              // 力引导布局的结果有良好的对称性和局部聚合性,也比较美观。
              repulsion: 1000,            // [ default: 50 ]节点之间的斥力因子(关系对象之间的距离)。支持设置成数组表达斥力的范围,此时不同大小的值会线性映射到不同的斥力。值越大则斥力越大
              // [ default: 30 ]边的两个节点之间的距离(关系对象连接线两端对象的距离,会根据关系对象值得大小来判断距离的大小),
              // 这个距离也会受 repulsion。支持设置成数组表达边长的范围,此时不同大小的值会线性映射到不同的长度。值越小则长度越长。如下示例:
              // 值最大的边长度会趋向于 10,值最小的边长度会趋向于 50      edgeLength: [10, 50]
            },
            layout: "force",            // 图的布局。[ default: ‘none‘ ]
                                        // ‘none‘ 不采用任何布局,使用节点中提供的 x, y 作为节点的位置。
                                        // ‘circular‘ 采用环形布局;‘force‘ 采用力引导布局.
            // 标记的图形
            //symbol: "path://M19.300,3.300 L253.300,3.300 C262.136,3.300 269.300,10.463 269.300,19.300 L269.300,21.300 C269.300,30.137 262.136,37.300 253.300,37.300 L19.300,37.300 C10.463,37.300 3.300,30.137 3.300,21.300 L3.300,19.300 C3.300,10.463 10.463,3.300 19.300,3.300 Z",
            symbol: circle,
            lineStyle: {            // 关系边的公用线条样式。其中 lineStyle.color 支持设置为‘source‘或者‘target‘特殊值,此时边会自动取源节点或目标节点的颜色作为自己的颜色。
              normal: {
                color: #000,          // 线的颜色[ default: ‘#aaa‘ ]
                width: 1,               // 线宽[ default: 1 ]
                type: solid,          // 线的类型[ default: solid ]   ‘dashed‘    ‘dotted‘
                opacity: 0.5,           // 图形透明度。支持从 0 到 1 的数字,为 0 时不绘制该图形。[ default: 0.5 ]
                curveness: 0            // 边的曲度,支持从 0 到 1 的值,值越大曲度越大。[ default: 0 ]
              }
            },
            label: {                // 关系对象上的标签
              normal: {
                show: true,                 // 是否显示标签
                position: "inside",         // 标签位置:‘top‘‘left‘‘right‘‘bottom‘‘inside‘‘insideLeft‘‘insideRight‘‘insideTop‘‘insideBottom‘‘insideTopLeft‘‘insideBottomLeft‘‘insideTopRight‘‘insideBottomRight‘
                textStyle: {                // 文本样式
                  fontSize: 16
                }
              }
            },
            data: nodes,
            links: links
          }],

          animationEasingUpdate: "cubicOut",          // 数据更新动画的缓动效果。[ default: cubicOut ]    "quinticInOut"
          // 数据更新动画的时长。[ default: 300 ]
        };
        mychart.setOption(option);
      },
      tab_words_onclick:function(){
        this.Content_Title="用户词云";
        this.v_words=true;
        this.v_follows=false;
        this.v_search=false;
      },

    },
    name:"HelloWorld"
  }
</script>

 

后端关键代码

//用户的具体信息domain
package
com.example.demo; import org.hibernate.engine.loading.internal.CollectionLoadContext; import javax.persistence.*; @Entity @Table(name = "userdetails") public class UserDetails { @Id @GeneratedValue(strategy = GenerationType.AUTO) private int num; @Column(name="description") public String description; @Column(name="keywords") public String keywords; @Column(name="sex") public String sex; @Column(name="name") public String name; void setName(String name){ this.name=name; } void setDescription(String description){ this.description=description; } void setKeywords(String keywords){ this.keywords=keywords; } void setSex(String sex){ this.sex=sex; } String getName(){ return this.name; } String getDescription(){ return this.description; } String getKeywords(){ return this.keywords; } String getSex(){ return this.sex; } }
//最重要的controller
package
com.example.demo; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.beans.factory.annotation.Autowired; import java.util.ArrayList; import java.util.List; @Controller @CrossOrigin public class IndexController { @Autowired private UserRepositroy userRepositroy; @RequestMapping(value="users") @ResponseBody public Object GetUser(){ List<User> userlist=userRepositroy.findAll(); return userlist; } @RequestMapping(value="links") @ResponseBody public Object GetLinks(String name){ List<Follows> followsList =followsRepositroy.findByName(name); List<RetnLinks> links =new ArrayList<RetnLinks>(); for(int i=0;i<followsList.size();i++){ RetnLinks l=new RetnLinks(); l.setSource(followsList.get(i).getName()); l.setTarget(followsList.get(i).getFuname()); links.add(l); } return links; } @RequestMapping(value="nodes") @ResponseBody public Object GetNodes(String name){ List<Follows> followsList=followsRepositroy.findByName(name); List<RetnNodes> nodes =new ArrayList<RetnNodes>(); RetnNodes r=new RetnNodes(); r.setName(name); r.setCategory(1); r.setSymbolSize(30); nodes.add(r); for(int i=0;i<followsList.size();i++){ RetnNodes rs=new RetnNodes(); rs.setName(followsList.get(i).getFuname()); rs.setCategory(2); rs.setSymbolSize(20); nodes.add(rs); } return nodes; } @RequestMapping(value="words") @ResponseBody public Object GetWords(String name){ List<User> userlist=userRepositroy.findByName(name); String word = userlist.get(0).getKeywords(); String value=userlist.get(0).getKeyvalue(); String[] array_word= word.split(","); String[] array_value= value.split(","); List<RetnWords> words=new ArrayList<RetnWords>(); for(int i=0;i<50;i++){ RetnWords w=new RetnWords(); w.setName(array_word[i]); w.setValue(Double.parseDouble(array_value[i])); words.add(w); } return words; } @Autowired private FollowsRepositroy followsRepositroy; @RequestMapping(value="follows") @ResponseBody public Object GetFollows(String name){ List<Follows> followslist=followsRepositroy.findByName(name); return followslist; } @Autowired private DetailsRepositroy detailsRepositroy; @RequestMapping(value="details") @ResponseBody public Object GetDetails(String name){ UserDetails userDetails=detailsRepositroy.findOneByName(name); return userDetails; } }

其他的都是类似的。无限重复改名。

最终结果:

技术分享图片技术分享图片技术分享图片



web开发vue+springboot项目服务器部署(环境搭建+部署流程)

前言前段时间使用Vue+Springboot写了个小项目,于是想部署到服务器上以便分享。于是,就开始了长达一天的踩坑之旅。。为了让读者(包括下一次想干这事的自己)少踩坑,把整个过程记录一下。技术选型... 查看详情

springboot+vue+electron开发qq版聊天工具

...web版,右边为PC版。二、本地搭建2.1技术栈后端技术栈:springboot:让开发人员快速开发的一款Java的微服务框架。tio:是百万级网络框架oau 查看详情

springboot的web部署,springboot开发非web程序

目录:1、SpringBoot的web项目部署为war2、SpringBoot的web项目部署为jar3、SpringBoot开发非Web程序   3.1、方式一:利用main()方法   3.2、方式二:通过springboot启动加载类CommandLineRunner#run()1、SpringBoot的web项目部署为war&... 查看详情

java高级开发面试,springboot整合vue

1、什么是Nginx,谈谈个人都理解,项目中是否用到,为什么要用,有什么优点?Nginx,是一个Web服务器和反向代理服务器用于HTTP、HTTPS、SMTP、POP3和IMAP协议。主要功能如下:1、正向、反向代理2、负载均... 查看详情

springboot的web开发

...Web开发的核心内容主要包括内嵌的Servlet容器和SpringMVC。SpringBoot使用起来非常简洁,大部分配置都有SpringBoot自动装配。SpringBoot的web支持SpringBoot提供了spring-boot-starter-web为web开发予以支持,而这个启动器内嵌了Tomcat以及Spri... 查看详情

springboot学习笔记——web开发探究(代码片段)

前置知识:SpringBoot学习笔记——SpringBoot简介与HelloWordSpringBoot学习笔记——源码初步解析SpringBoot学习笔记——配置文件yaml学习SpringBoot学习笔记——JSR303数据校验与多环境切换SpringBoot学习笔记——自动配置原理Web开发探究简介... 查看详情

springboot(二):web综合开发

SpringBoot(二):web综合开发来源:纯洁的微笑,www.ityouknow.com/springboot/2016/02/03/springboot(二)-web综合开发.html如有好文章投稿,请点击→这里了解详情上篇文章介绍了Springboot初级教程:《 springboot(一):入门篇 》... 查看详情

springboot---web开发---ssl配置

1、【生成证书】2、【SpringBoot配置SSL】3、【http转向https】 查看详情

springboot_web开发

3.19目录1.Springboot开发步骤2.Springboot对静态资源的映射规则3.模板引擎引入ThymeleafThymeleaf使用和语法4.SpringMVC自动配置原理5.修改Springboot的默认配置6.全面接管SpringMvc  1.步骤:1.创建springboot应用,选中需要的模块2.springboot已... 查看详情

springboot与web开发

简介 使用SpringBoot;1)、创建SpringBoot应用,选中我们需要的模块;比如web等等2)、SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来3)、自己编写业务代码; 参考这里:比如要连... 查看详情

springboot:web综合开发

web开发springbootweb开发非常的简单,其中包括常用的json输出、filters、property、log等json接口开发在以前的spring开发的时候需要我们提供json接口的时候需要做那些配置呢添加jackjson等相关jar包配置springcontroller扫描对接的方法添加@Resp... 查看详情

4.springboot的web开发1

一.回顾好的,同学们,那么接下来呢,我们开始学习SpringBoot与Web开发,从这一章往后,就属于我们实战部分的内容了;其实SpringBoot的东西用起来非常简单,因为SpringBoot最大的特点就是自动装配。使用SpringBoot的步骤:创建一个S... 查看详情

springboot学习开发web应用

SpringBoot非常适合web应用程序开发。可以使用嵌入式Tomcat、Jetty、Undertow或Netty创建自包含的HTTP服务器。大多数web应用程序使用spring-boot-starter-web模块来快速启动和运行。您还可以选择使用spring-boot-starter-webflux模块来构建反应性web... 查看详情

springboot用于web开发

1.使用SpringBoot;1)创建SpringBoot应用,选中我们需要的模块;2)SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来3)自己编写业务代码;自动配置原理?xxxxAutoConfiguration:帮我们给容器中... 查看详情

springboot框架学习6-springboot的web开发

...章节主要内容:通过前面的学习,我们了解并快速完成了springboot第一个应用。springboot企业级框架,那么springboot怎么读取静态资源?如js文件夹,css文件以及png/jpg图片呢?怎么自定义消息转换器呢?怎么自定义springmvc的配置呢?... 查看详情

springboot1.5.4之web开发

上一篇:springboot1.5.4入门和原理(二)springBoot之web开发更多更详细的配置参考文件:application.properties和《SpringBoot之application配置详解》(新版本新增属性缺失) 或参考官网http://projects.spring.io/spring-boot/注意:SpringBoot工程默... 查看详情

springboot:web开发-模板引擎freemarker

一、简介springboot的web应用开发,是基于springmvc。Springboot在spring默认基础上,自动配置添加了以下特性: 1、包含了ContentNegotiatingViewResolver和BeanNameViewResolverbeans。 2、对静态资源的支持,包括对WebJars的支持。 3、自动... 查看详情

springboot:web开发-错误处理

处理方式一:实现ErrorController接口原理:SpringBoot将所有的错误默认映射到/error,实现ErrorController接口代码:package com.example.demo.controller;import org.springframework.boot.autoconfigure.web.ErrorController;import&nbs 查看详情