搜索词>>65W 耗时0.0110
  • 氮化镓65W充电器购买建议

    背景注意本文的建议是从使用者角度来说,先抛弃价格/充电口/充电协议等因素背景注意本文的建议是从使用者角度来说,先抛弃价格/充电口/充电协议等因素。仅从充电插口来建议,那些产品前往不要买。因为你再好的充电协议,再多的充电接口,如果用不到多久插电口就坏了你会崩溃的。(我就是那个崩溃者)说说我的经历把,买了一个65W折叠款氮化镓(我就不指定具体了,免得说我黑啥),然后充电速度什么都好。可是用了一段时间充电口劈叉了。。。这简直是我用电器设备一来第一次。最后也得到总结,充电口保护太薄的千万不能买,你不能确定每个插板都那么容易插,总有劈叉的时候。​常规充电器插电口参考​常规插电口参考图上图可见,常规插电口的保护后座都是有那么厚的,也保证了展开后能承受的后坐力更大。65W氮化镓那些不能买 举例一部分:某思 65W氮化镓(折叠头);某*亚65W氮化镓(折叠头);某36*氮化镓65W(折叠头);某量氮化镓65W(折叠头);...更多相似的 为啥不能买,请看下图​不合格插口从上面可以看到,以上类型的65W充电器折叠充电插口相比上面的常规都是“薄如蝉翼”,且对外部的多数是没有的,裸金属在外面。可想而知能承受的后坐力多差,而本人也是买的这个,后面成功劈叉。​脆弱的差点口最后希望大家不要花重金买了个充电器还要把他当大爷供着,谨防劈叉​不合格插口 图像 小部件
  • 空调_P数_制冷量_空调P数和面积之间的关系

    空调_P数_制冷量_空调P数和面积之间的关系空调P数制冷量(W)制冷面积(㎡)制热面积(㎡)1P230011.5-15.510~11大1P 260013-17.513~181.5P 320016-21.517~232P 460023~302空调_P数_制冷量_空调P数和面积之间的关系空调P数制冷量(W)制冷面积(㎡)制热面积(㎡)1P230011.5-15.510~11大1P 260013-17.513~181.5P 320016-21.517~232P 460023~3020~22大2P500025-33.524~28大3P 720036-48㎡制冷/制热量与平方米的换算大致规则:常规住房制冷量:130-180W/平方米;常规住房制热量:150-200W/平方米;办公环境制冷量:250-300W/平方米;公共场所制冷量:300-400W/平方米;
  • Linux系统分区Linux系统挂载硬盘Linux系统Linux系统增加交换分区swap

    centos挂载硬盘和交换分区<p>Linux系统分区Linux系统挂载硬盘Linux系统Linux系统增加交换分区swap</p> <p>1.分区介绍</p> <p> Linux系统分区不同于windows,Linux下[IED]硬盘名称为hd?(?为a-d)因为IED硬盘最多4个分区;SCSI,SATA,USB硬盘名称为sd?(?a-z),硬盘主分区最多为4个,逻辑分区从sdb5开始.</p> <p>2.查看系统分区</p> <p> 命令:</p> <pre> <code class="language-html">[root@localhost ~]# fdisk -l   Disk /dev/sda: 21.5 GB, 21474836480 bytes 255 heads, 63 sectors/track, 2610 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x000706e3      Device Boot      Start         End      Blocks   Id  System /dev/sda1   *           1          39      307200   83  Linux Partition 1 does not end on cylinder boundary. /dev/sda2              39         557     4161536   82  Linux swap / Solaris Partition 2 does not end on cylinder boundary. /dev/sda3             557        2611    16501760   83  Linux   Disk /dev/sdb: 10.7 GB, 10737418240 bytes 255 heads, 63 sectors/track, 1305 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00000000   [root@localhost ~]#</code></pre> <p>从上面我们可以看出有两块硬盘 分别为 sda sdb<br />  第一块硬盘sda是装系统时候用的硬盘;<br />  另外一块sdb则是我们今天将要分区的硬盘<br /> 3.分区方法</p> <p>①进入第二块磁盘分区</p> <pre> <code class="language-html">[root@localhost ~]# fdisk /dev/sdb Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel Building a new DOS disklabel with disk identifier 0xe182f37e. Changes will remain in memory only, until you decide to write them. After that, of course, the previous content won't be recoverable.   Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)   WARNING: DOS-compatible mode is deprecated. It's strongly recommended to          switch off the mode (command 'c') and change display units to          sectors (command 'u').   Command (m for help):</code></pre> <p>②输入m获取帮助信息</p> <pre> <code class="language-html">Command (m for help): m  Command action    a   toggle a bootable flag    b   edit bsd disklabel    c   toggle the dos compatibility flag    d   delete a partition    l   list known partition types    m   print this menu    n   add a new partition    o   create a new empty DOS partition table    p   print the partition table    q   quit without saving changes    s   create a new empty Sun disklabel    t   change a partition's system id    u   change display/entry units    v   verify the partition table    w   write table to disk and exit    x   extra functionality (experts only)   Command (m for help):</code></pre> <p>③输入p查看当前分区表</p> <pre> <code class="language-html">Command (m for help): p   Disk /dev/sdb: 10.7 GB, 10737418240 bytes 255 heads, 63 sectors/track, 1305 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0xe182f37e      Device Boot      Start         End      Blocks   Id  System   Command (m for help):</code></pre> <p>④创建主分区sdb1大小为2G</p> <pre> <code class="language-html">Command (m for help): n Command action    e   extended    p   primary partition (1-4) p Partition number (1-4): 1 First cylinder (1-1305, default 1): Using default value 1 Last cylinder, +cylinders or +size{K,M,G} (1-1305, default 1305): +2G           Command (m for help): p   Disk /dev/sdb: 10.7 GB, 10737418240 bytes 255 heads, 63 sectors/track, 1305 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0xe182f37e      Device Boot      Start         End      Blocks   Id  System /dev/sdb1               1         262     2104483+  83  Linux   Command (m for help):</code></pre> <p>⑤格式化分区sdb1为linux文件类型</p> <pre> <code class="language-html">Command (m for help): t Selected partition 1 Hex code (type L to list codes): L    0  Empty           24  NEC DOS         81  Minix / old Lin bf  Solaris         1  FAT12           39  Plan 9          82  Linux swap / So c1  DRDOS/sec (FAT-  2  XENIX root      3c  PartitionMagic  83  Linux           c4  DRDOS/sec (FAT-  3  XENIX usr       40  Venix 80286     84  OS/2 hidden C:  c6  DRDOS/sec (FAT-  4  FAT16 <32M      41  PPC PReP Boot   85  Linux extended  c7  Syrinx          5  Extended        42  SFS             86  NTFS volume set da  Non-FS data     6  FAT16           4d  QNX4.x          87  NTFS volume set db  CP/M / CTOS / .  7  HPFS/NTFS       4e  QNX4.x 2nd part 88  Linux plaintext de  Dell Utility    8  AIX             4f  QNX4.x 3rd part 8e  Linux LVM       df  BootIt          9  AIX bootable    50  OnTrack DM      93  Amoeba          e1  DOS access      a  OS/2 Boot Manag 51  OnTrack DM6 Aux 94  Amoeba BBT      e3  DOS R/O         b  W95 FAT32       52  CP/M            9f  BSD/OS          e4  SpeedStor       c  W95 FAT32 (LBA) 53  OnTrack DM6 Aux a0  IBM Thinkpad hi eb  BeOS fs         e  W95 FAT16 (LBA) 54  OnTrackDM6      a5  FreeBSD         ee  GPT             f  W95 Ext'd (LBA) 55  EZ-Drive        a6  OpenBSD         ef  EFI (FAT-12/16/ 10  OPUS            56  Golden Bow      a7  NeXTSTEP        f0  Linux/PA-RISC b 11  Hidden FAT12    5c  Priam Edisk     a8  Darwin UFS      f1  SpeedStor      12  Compaq diagnost 61  SpeedStor       a9  NetBSD          f4  SpeedStor      14  Hidden FAT16 <3 63  GNU HURD or Sys ab  Darwin boot     f2  DOS secondary  16  Hidden FAT16    64  Novell Netware  af  HFS / HFS+      fb  VMware VMFS    17  Hidden HPFS/NTF 65  Novell Netware  b7  BSDI fs         fc  VMware VMKCORE 18  AST SmartSleep  70  DiskSecure Mult b8  BSDI swap       fd  Linux raid auto 1b  Hidden W95 FAT3 75  PC/IX           bb  Boot Wizard hid fe  LANstep        1c  Hidden W95 FAT3 80  Old Minix       be  Solaris boot    ff  BBT            1e  Hidden W95 FAT1 Hex code (type L to list codes): 83   Command (m for help)</code></pre> <p>:⑥创建主分区sdb2大小为6G</p> <pre> <code class="language-html">Command (m for help): n Command action    e   extended    p   primary partition (1-4) p Partition number (1-4): 2 First cylinder (263-1305, default 263): Using default value 263 Last cylinder, +cylinders or +size{K,M,G} (263-1305, default 1305): +6G   Command (m for help): p   Disk /dev/sdb: 10.7 GB, 10737418240 bytes 255 heads, 63 sectors/track, 1305 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0xe182f37e      Device Boot      Start         End      Blocks   Id  System /dev/sdb1               1         262     2104483+  83  Linux /dev/sdb2             263        1046     6297480   83  Linux   Command (m for help):</code></pre> <p>⑦格式化分区sdb2为FAT32</p> <pre> <code class="language-html">Command (m for help): t Partition number (1-4): 2 Hex code (type L to list codes): L    0  Empty           24  NEC DOS         81  Minix / old Lin bf  Solaris         1  FAT12           39  Plan 9          82  Linux swap / So c1  DRDOS/sec (FAT-  2  XENIX root      3c  PartitionMagic  83  Linux           c4  DRDOS/sec (FAT-  3  XENIX usr       40  Venix 80286     84  OS/2 hidden C:  c6  DRDOS/sec (FAT-  4  FAT16 <32M      41  PPC PReP Boot   85  Linux extended  c7  Syrinx          5  Extended        42  SFS             86  NTFS volume set da  Non-FS data     6  FAT16           4d  QNX4.x          87  NTFS volume set db  CP/M / CTOS / .  7  HPFS/NTFS       4e  QNX4.x 2nd part 88  Linux plaintext de  Dell Utility    8  AIX             4f  QNX4.x 3rd part 8e  Linux LVM       df  BootIt          9  AIX bootable    50  OnTrack DM      93  Amoeba          e1  DOS access      a  OS/2 Boot Manag 51  OnTrack DM6 Aux 94  Amoeba BBT      e3  DOS R/O         b  W95 FAT32       52  CP/M            9f  BSD/OS          e4  SpeedStor       c  W95 FAT32 (LBA) 53  OnTrack DM6 Aux a0  IBM Thinkpad hi eb  BeOS fs         e  W95 FAT16 (LBA) 54  OnTrackDM6      a5  FreeBSD         ee  GPT             f  W95 Ext'd (LBA) 55  EZ-Drive        a6  OpenBSD         ef  EFI (FAT-12/16/ 10  OPUS            56  Golden Bow      a7  NeXTSTEP        f0  Linux/PA-RISC b 11  Hidden FAT12    5c  Priam Edisk     a8  Darwin UFS      f1  SpeedStor      12  Compaq diagnost 61  SpeedStor       a9  NetBSD          f4  SpeedStor      14  Hidden FAT16 <3 63  GNU HURD or Sys ab  Darwin boot     f2  DOS secondary  16  Hidden FAT16    64  Novell Netware  af  HFS / HFS+      fb  VMware VMFS    17  Hidden HPFS/NTF 65  Novell Netware  b7  BSDI fs         fc  VMware VMKCORE 18  AST SmartSleep  70  DiskSecure Mult b8  BSDI swap       fd  Linux raid auto 1b  Hidden W95 FAT3 75  PC/IX           bb  Boot Wizard hid fe  LANstep        1c  Hidden W95 FAT3 80  Old Minix       be  Solaris boot    ff  BBT            1e  Hidden W95 FAT1 Hex code (type L to list codes): b      Changed system type of partition 2 to b (W95 FAT32)   Command (m for help):   ⑧创建主分区sdb3大小剩余的全部 Command (m for help): n Command action    e   extended    p   primary partition (1-4) p Partition number (1-4): 3 First cylinder (1047-1305, default 1047): Using default value 1047 Last cylinder, +cylinders or +size{K,M,G} (1047-1305, default 1305): Using default value 1305   Command (m for help):</code></pre> <p>⑨格式化为swap格式</p> <pre> <code>Command (m for help): t Partition number (1-4): 3 Hex code (type L to list codes): L    0  Empty           24  NEC DOS         81  Minix / old Lin bf  Solaris         1  FAT12           39  Plan 9          82  Linux swap / So c1  DRDOS/sec (FAT-  2  XENIX root      3c  PartitionMagic  83  Linux           c4  DRDOS/sec (FAT-  3  XENIX usr       40  Venix 80286     84  OS/2 hidden C:  c6  DRDOS/sec (FAT-  4  FAT16 <32M      41  PPC PReP Boot   85  Linux extended  c7  Syrinx          5  Extended        42  SFS             86  NTFS volume set da  Non-FS data     6  FAT16           4d  QNX4.x          87  NTFS volume set db  CP/M / CTOS / .  7  HPFS/NTFS       4e  QNX4.x 2nd part 88  Linux plaintext de  Dell Utility    8  AIX             4f  QNX4.x 3rd part 8e  Linux LVM       df  BootIt          9  AIX bootable    50  OnTrack DM      93  Amoeba          e1  DOS access      a  OS/2 Boot Manag 51  OnTrack DM6 Aux 94  Amoeba BBT      e3  DOS R/O         b  W95 FAT32       52  CP/M            9f  BSD/OS          e4  SpeedStor       c  W95 FAT32 (LBA) 53  OnTrack DM6 Aux a0  IBM Thinkpad hi eb  BeOS fs         e  W95 FAT16 (LBA) 54  OnTrackDM6      a5  FreeBSD         ee  GPT             f  W95 Ext'd (LBA) 55  EZ-Drive        a6  OpenBSD         ef  EFI (FAT-12/16/ 10  OPUS            56  Golden Bow      a7  NeXTSTEP        f0  Linux/PA-RISC b 11  Hidden FAT12    5c  Priam Edisk     a8  Darwin UFS      f1  SpeedStor      12  Compaq diagnost 61  SpeedStor       a9  NetBSD          f4  SpeedStor      14  Hidden FAT16 <3 63  GNU HURD or Sys ab  Darwin boot     f2  DOS secondary  16  Hidden FAT16    64  Novell Netware  af  HFS / HFS+      fb  VMware VMFS    17  Hidden HPFS/NTF 65  Novell Netware  b7  BSDI fs         fc  VMware VMKCORE 18  AST SmartSleep  70  DiskSecure Mult b8  BSDI swap       fd  Linux raid auto 1b  Hidden W95 FAT3 75  PC/IX           bb  Boot Wizard hid fe  LANstep        1c  Hidden W95 FAT3 80  Old Minix       be  Solaris boot    ff  BBT            1e  Hidden W95 FAT1 Hex code (type L to list codes): 82 Changed system type of partition 3 to 82 (Linux swap / Solaris)   Command (m for help):</code></pre> <p><br /> 到目前为止,我们只是对分区表进行了内存中编辑。我们可以用 q 命令退出,不保存更改。如果某些分区不能满足您的要求,您可以使用 d 命令来删除一个或多个分区,以便重新定义它们。如果您对设置满意,则可以使用 v 命令来验证您的设置,然后使用 w 命令来写入新的分区表并退出</p> <pre> <code>Command (m for help): w The partition table has been altered!   Calling ioctl() to re-read partition table.   WARNING: If you have created or modified any DOS 6.x partitions, please see the fdisk manual page for additional information. Syncing disks.</code></pre> <p>4.格式化分区/dev/sdb1为ext3文件类型</p> <pre> <code>[root@MiWiFi-R1CM ~]# mkfs.ext3 /dev/sdb1 mke2fs 1.41.12 (17-May-2010) Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) Stride=0 blocks, Stripe width=0 blocks 131648 inodes, 526120 blocks 26306 blocks (5.00%) reserved for the super user First data block=0 Maximum filesystem blocks=541065216 17 block groups 32768 blocks per group, 32768 fragments per group 7744 inodes per group Superblock backups stored on blocks:     32768, 98304, 163840, 229376, 294912   Writing inode tables: done                            Creating journal (16384 blocks): done Writing superblocks and filesystem accounting information: done   This filesystem will be automatically checked every 22 mounts or 180 days, whichever comes first.  Use tune2fs -c or -i to override. [root@localhost ~]#</code></pre> <p><span style="color:#27ae60"><strong>如果需要ext4类型则执行命令</strong></span><br />  </p> <pre> <code class="language-html">[root@MiWiFi-R1CM ~]# mkfs.ext3 /dev/sdb1</code></pre> <p>大硬盘快速格式化命令</p> <pre> <code>[root@MiWiFi-R1CM ~]# mkfs.ext3 -T largefile /dev/sdb1</code></pre> <p><br /> 5.挂载分区/dev/sdb1到/home</p> <pre> <code>[root@localhost ~]# mount /dev/sdb1 /home/data [root@localhost ~]# df -h Filesystem            Size  Used Avail Use% Mounted on /dev/sda3              16G  6.6G  8.2G  45% / tmpfs                 947M  276K  947M   1% /dev/shm /dev/sda1             291M   34M  242M  13% /boot /dev/sdb1             2.0G   68M  1.9G   4% /home/data      如果报错mount: you must specify the filesystem type则需要格式化一下分区  mkfs -t ext3 /dev/sdb1或  mksf.ext3 /dev/sdb1</code></pre> <p>5.1将硬盘挂载配置到系统分区配置文件/etc/fstab中<br /> 将硬盘挂载配置到系统分区配置文件/etc/fstab中,便于下次重启能自动挂载<br /> <span style="color:#27ae60"><strong><!--StartFragment --><br /> 编辑/etc/fstab 文件<br /> 添加:/dev/sdb1 /home/data ext3 defaults 1 1 </strong></span><br /> <br /> <br /> 6.将swap分区应用到系统中/取消分区</p> <pre> <code>[root@localhost ~]# free           total      used      free     shared    buffers     cached Mem:       1939084     502680    1436404        0     35616     279680 -/+ buffers/cache:187384       1751700 Swap:      4161528        0    4161528</code></pre> <pre> <code>[root@localhost ~]# mkswap -L SDBSWAP /dev/sdb3 Setting up swapspace version 1, size = 2080412 KiB LABEL=SDBSWAP, UUID=b2d1bfd4-db4a-4524-a9ca-6f8c1462ba2b [root@localhost ~]# swapon /dev/sdb3 [root@localhost ~]# free              total       used       free     shared    buffers     cached Mem:       1939084     504548    1434536          0      36424     279740 -/+ buffers/cache:     188384    1750700 Swap:      6241936          0    6241936 [root@localhost ~]# swapoff /dev/sdb3 [root@localhost ~]# free              total       used       free     shared    buffers     cached Mem:       1939084     503564    1435520          0      36484     279740 -/+ buffers/cache:     187340    1751744 Swap:      4161528          0    4161528 [root@localhost ~]# </code></pre>
  • G4560怎么样

    G4560怎么样?七代Intel处理器,双核四线程完全是奔腾系列的春天啊,具体性能表现怎么样请看本文搜集内容G4560七代Intel处理器,基本信息:<br /> 奔腾<strong><span style="color:#FF0000">双核/四线程</span></strong>/3MB/54W/DDR4 2133/2400MHz,DDR3L 1333/1600MHz @1.35V/Intel HD Graphics 610<br /> <br /> <em><strong>对,你没看错,奔腾已经进入双核四线程时代了!!!!!</strong></em><br /> <br /> g4560打破Intel公司以前的奔腾系列仅仅双核的情况<br /> <br /> 双核四线程。。。奔腾从未有过,性能如何呢?<br /> <br /> 首先CPU性能测试:<br /> <img alt="cpu-z" class="img-thumbnail" src="/assist/images/blog/ce3df7b7-65f7-405e-9c21-19f0fd47fcb3.jpg" style="height:576px; width:961px" /> <div style="text-align:center">(CPU-Z跑分图)<br />  </div>  CPU-Z的测试中可以看出,无论是单线程方面还是多线程方面,G4560与I3 7100低频相差无几,几乎不分上下,上一代奔腾则显得差距明显<br /> <br /> <img alt="国际象棋" class="img-thumbnail" src="/assist/images/blog/8b187e03-1aee-4bfd-b35a-38e3322ff126.jpg" style="height:576px; width:961px" /><br /> 国际象棋的测试结论与cpu-z差不多。这次的七代奔腾确实给力<br /> <br /> 接下来进行核显测试:<br /> <img alt="3dmax" class="img-thumbnail" src="/assist/images/blog/d1cb8901-235f-495a-b497-5fd376af06db.jpg" style="height:576px; width:961px" /><br /> 从3Dmax来看.显卡性能同样得到提升。<br /> <br /> 综合性能来看.七代的奔腾G4560已经可以代替六代I3 6100了,最近想攒机/装机的赶紧入手吧。
  • Python教程-Python找到最大的N(前N个)或最小的N个项目

    Python示例使用heapq库中的nlargest()和nsmallest()函数从元素集合中找到最大(或最小)的N个元素​1.使用heapq模块的nlargest()和nsmallest()Python heapq模块可用于从集合中查找Python示例使用heapq库中的nlargest()和nsmallest()函数从元素集合中找到最大(或最小)的N个元素​1.使用heapq模块的nlargest()和nsmallest()Python heapq模块可用于从集合中查找N个最大或最小的项目。它具有两个功能来帮助–nlargest()nsmallest()1.1。在简单的可迭代对象中查找项目$title(example1.py) >>> import heapq >>> nums = [1, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2] print(heapq.nlargest(3, nums)) >>> [42, 37, 23] print(heapq.nsmallest(3, nums)) >>> [-4, 1, 2]1.2。查找复杂的可迭代项$title(example2.py) >>> portfolio = [ {'name': 'IBM', 'shares': 100, 'price': 91.1}, {'name': 'AAPL', 'shares': 50, 'price': 543.22}, {'name': 'FB', 'shares': 200, 'price': 21.09}, {'name': 'HPQ', 'shares': 35, 'price': 31.75}, {'name': 'YHOO', 'shares': 45, 'price': 16.35}, {'name': 'ACME', 'shares': 75, 'price': 115.65} ] >>> cheap = heapq.nsmallest(3, portfolio, key=lambda s: s['price']) >> cheap >>> [ {'price': 16.35, 'name': 'YHOO', 'shares': 45}, {'price': 21.09, 'name': 'FB', 'shares': 200}, {'price': 31.75, 'name': 'HPQ', 'shares': 35} ] >>> expensive = heapq.nlargest(3, portfolio, key=lambda s: s['price']) >>> expensive >>> [ {'price': 543.22, 'name': 'AAPL', 'shares': 50}, {'price': 115.65, 'name': 'ACME', 'shares': 75}, {'price': 91.1, 'name': 'IBM', 'shares': 100} ]如果您只是想查找单个最小或最大项(N=1),则使用min()和max()函数的速度更快。Python教程 图像 小部件
  • spring boot 入门(四)数据库操作

    spring boot是一个崭新的spring框架分支项目,本文讲解基本的数据库配置<h4>一.pom.xml文件添加相关的两个依赖</h4> <pre> <code class="language-xml"><?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>demo</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- 数据库操作依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- 数据库操作依赖 --> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> </code></pre> 二.相关配置<br /> 编写配置文件application.yml <pre> <code>spring: profiles: active: prod datasource: driver-class-name: "com.mysql.jdbc.Driver" url: jdbc:mysql://127.0.0.1:3306/test username: root password: root jpa: hibernate: ddl-auto: update show-sql: true</code></pre> <h4><br /> 三.创建一个实体类</h4> <pre> <code class="language-java">package com.example; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; /** *创建一个实体 *这里的使用方法与jpa和hibernate有关 */ @Entity public class Persion { @Id @GeneratedValue private int id; private String name; private int age; public Persion(){ } /** * @return the id */ public int getId() { return id; } /** * @param id the id to set */ public void setId(int id) { this.id = id; } /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } /** * @return the age */ public int getAge() { return age; } /** * @param age the age to set */ public void setAge(int age) { this.age = age; } } </code></pre> <br /> 四.启动项目,观察数据库<br /> <img alt="jpa创建数据库表" class="img-thumbnail" src="/assist/images/blog/906aedcd-c26c-47a0-9992-83a2fa8e4c8c.jpg" style="height:109px; width:526px" /><br /> 这时候JPA已经帮助我们创建好了表<br /> <br /> 推荐:<br /> <a rel="" target="_blank"href="http://www.leftso.com/blog/64.html" rel="" target="_blank">spring boot 入门(一)hello word</a><br /> <a rel="" target="_blank"href="http://www.leftso.com/blog/65.html" rel="" target="_blank">spring boot入门(二)属性配置</a><br /> <a rel="" target="_blank"href="http://www.leftso.com/blog/66.html" rel="" target="_blank">spring boot入门(三)controller的使用</a><br /> <a rel="" target="_blank"href="http://www.leftso.com/blog/67.html" rel="" target="_blank">spring boot入门(四)数据库操作</a>
  • spring boot webflux client实战

    spring boot webflux client实战,webclient是spring webflux的一个小组件。对于Java的http通讯来说,webclient是非常简单易用的。<h2>引言</h2>     在spring 5.0发布的同时发布了webflux功能类似spring mvc。底层实现以及关注点不同。今天我们主要讲解spring webflux中的一个组件webclient。webclient是spring webflux的一个小组件。对于Java的http通讯来说,webclient是非常简单易用的。比起apache的httpclient组件更方便的集成到项目中 <h2>一.创建一个spring boot 项目包含webflux组件</h2> <h3>1.1创建Spring  boot项目并加入webflux组件依赖</h3> <img alt="选择依赖" class="img-thumbnail" src="/assist/images/blog/039cefbac57f44eaa8bed5f3e1ff1bd2.png" /> <h2>1.2项目结构图展示</h2> <img alt="项目结构图" class="img-thumbnail" src="/assist/images/blog/dbc64afd017e47e2a14e62f2c65fc74d.png" /> <h2>二.创建一个间的web服务</h2> <h3>2.1创建spring webflux基于Java的配置</h3> WebConfig: <pre> <code class="language-java">package net.xqlee.project.config; import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; import org.springframework.format.datetime.DateFormatter; import org.springframework.web.reactive.config.EnableWebFlux; import org.springframework.web.reactive.config.ResourceHandlerRegistry; import org.springframework.web.reactive.config.WebFluxConfigurer; /** * 基于Java代码配置启用Spring WebFlux * * @author xqlee * */ @Configuration @EnableWebFlux public class WebConfig implements WebFluxConfigurer { String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; /**** * 配置常用的转换器和格式化配置(与Spring MVC 5配置方式一样) */ @Override public void addFormatters(FormatterRegistry registry) { // 添加日期格式化转换 DateFormatter dateFormatter = new DateFormatter(DATE_FORMAT); registry.addFormatter(dateFormatter); } /**** * 资源路径映射配置(与Spring MVC 5一样,只是引入的类不同) */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**").addResourceLocations("/public", "classpath:/static/"); } } </code></pre> 通过spring 官方文档查询可以知道,spring webflux的配置使用和Spring mvc的配置使用方法基本相同。上面只是个简单的配置。 <h3>2.2创建一个controller用来做webclient的测试请求服务</h3> TestController: <pre> <code class="language-java">package net.xqlee.project.controller; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.ResponseBody; import net.xqlee.project.pojo.Person; @Controller public class TestController { private static final Logger log = LoggerFactory.getLogger(TestController.class); @PostMapping("persion/getPersion/{id}.json") @ResponseBody public Person getPersion(@PathVariable("id") String id) { log.info("ID:" + id); return new Person("1", "leftso", 1, "重庆.大竹林"); } } </code></pre> 上面包含一个简单对象Persion: <pre> <code class="language-java">package net.xqlee.project.pojo; public class Person { public Person() { } public Person(String id, String name, int age, String address) { super(); this.id = id; this.name = name; this.age = age; this.address = address; } String id; String name; int age; String address; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } } </code></pre> 好了一个spring boot的webflux服务已经创建完毕。接下来将进行webclient的调用方法。 <h2>三.创建webclient</h2> 3.1创建一个测试的类 <pre> <code class="language-java">package net.xqlee.project; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; import org.springframework.web.reactive.function.client.WebClient; import net.xqlee.project.pojo.Person; import reactor.core.publisher.Mono; /** * reactive webClient * * @author xqlee * */ public class TestClient { private static final Logger log = LoggerFactory.getLogger(TestClient.class); public static void main(String[] args) { WebClient client = WebClient.create("http://localhost:8080/"); Mono<Person> result = client.post()// 请求方法,get,post... .uri("persion/getPersion/{id}.json", "123")// 请求相对地址以及参数 .accept(MediaType.APPLICATION_JSON).retrieve()// 请求类型 .bodyToMono(Person.class);// 返回类型 Person person = result.block(); log.info(JSONObject.wrap(person).toString()); } } </code></pre> 上面已经创建了一个webclient的请求。请求的地址是刚才我们创建的一个简单的测试服务。<br /> 首先运行spring boot项目启动测试服务: <pre> <code class="language-html"> . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.0.0.M6) 2017-11-19 13:53:09.290 INFO 6976 --- [ main] n.x.p.DemoSpringbootWebflux2Application : Starting DemoSpringbootWebflux2Application on DESKTOP-2RG0A6O with PID 6976 (D:\workplace\eclipse_mvn\demo-springboot-webflux-2\target\classes started by xqlee in D:\workplace\eclipse_mvn\demo-springboot-webflux-2) 2017-11-19 13:53:09.295 INFO 6976 --- [ main] n.x.p.DemoSpringbootWebflux2Application : No active profile set, falling back to default profiles: default 2017-11-19 13:53:09.377 INFO 6976 --- [ main] .r.c.ReactiveWebServerApplicationContext : Refreshing org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext@59402b8f: startup date [Sun Nov 19 13:53:09 CST 2017]; root of context hierarchy 2017-11-19 13:53:10.480 INFO 6976 --- [ main] s.w.r.r.m.a.RequestMappingHandlerMapping : Mapped "{[/persion/getPersion/{id}.json],methods=[POST]}" onto public net.xqlee.project.pojo.Person net.xqlee.project.controller.TestController.getPersion(java.lang.String) 2017-11-19 13:53:10.542 INFO 6976 --- [ main] o.s.w.r.handler.SimpleUrlHandlerMapping : Mapped URL path [/resources/**] onto handler of type [class org.springframework.web.reactive.resource.ResourceWebHandler] 2017-11-19 13:53:10.611 INFO 6976 --- [ main] o.s.w.r.r.m.a.ControllerMethodResolver : Looking for @ControllerAdvice: org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext@59402b8f: startup date [Sun Nov 19 13:53:09 CST 2017]; root of context hierarchy 2017-11-19 13:53:11.256 INFO 6976 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup 2017-11-19 13:53:11.523 INFO 6976 --- [ctor-http-nio-1] r.ipc.netty.tcp.BlockingNettyContext : Started HttpServer on /0:0:0:0:0:0:0:0:8080 2017-11-19 13:53:11.524 INFO 6976 --- [ main] o.s.b.web.embedded.netty.NettyWebServer : Netty started on port(s): 8080 2017-11-19 13:53:11.530 INFO 6976 --- [ main] n.x.p.DemoSpringbootWebflux2Application : Started DemoSpringbootWebflux2Application in 2.554 seconds (JVM running for 3.059) </code></pre> 通过启动日志我们可以看到。默认情况下webflux已经不是使用tomcat容器启动项目。而是替换为netty容器启动的项目。<br /> <br /> 运行我们上面创建的webclient:<br /> 重点截图1:<br /> <img alt="webclient" class="img-thumbnail" src="/assist/images/blog/b317c94a94254e9a9560f4d3374dc25c.png" />这里可以看到打印的请求日志http相关的头部信息<br /> <br /> 重点截图2:<br /> <img alt="webclient执行结果" class="img-thumbnail" src="/assist/images/blog/322c8a6cf0e941f7ab70b1829a62718e.png" />上面可以看到调用的返回已经自动载入Persion对象。<br /> <br /> 通过上面的使用不难发现使用weblcient在Java中进行http通讯是非常方便的。而且支持nio异步操作。在效率上也应该有所提升。在使用微服务的时候,是否可以考虑服务之间通讯使用weblcient?
  • Java Word模板导出包含表格单元格合并

    java通过freemarker导出word循环合并表格单元格本文主要讲解通过freemarker模板引擎来导出word,并且在word中包含表格的合并部分需要循环生成java通过freemarker导出word循环合并表格单元格本文主要讲解通过freemarker模板引擎来导出word,并且在word中包含表格的合并部分需要循环生成。一、Java需要通过模板导出的word​如上图所示。物品的信息是循环部分。但是前面的表格是合并固定的。接下来我们将通过freemarker模板的方式来导出上述格式二、创建freemarker模板2.1首先将word的源文件另存为xml格式文件,如下​用文本工具打开xml文件。notepad++ 或者sublimetext都可以​打开后如上图,看起来很乱。这时候需要进行xml格式化。欢迎使用本站xml格式化工具格式化以后如下:​格式化以后就好看多了。首先我们需要去找到我们需要循环的表格​物品信息就是我们要循环的开始部分。在这之前需要科普下word的xml是如何实现单元格合并的主要就是<w:vMerge w:val="restart"/> <w:vMerge/> 两个标签的组合。首先了解下word的表格标签<w:tr w:rsidR="00770B3E" w:rsidTr="00AB3846">               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1659" w:type="dxa"/>                   <w:vMerge w:val="restart"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRPr="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">                   <w:pPr>                     <w:jc w:val="center"/>                     <w:rPr>                       <w:b/>                     </w:rPr>                   </w:pPr>                   <w:r w:rsidRPr="00770B3E">                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                       <w:b/>                     </w:rPr>                     <w:t>物品信息</w:t>                   </w:r>                 </w:p>               </w:tc>               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1659" w:type="dxa"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>物品名称</w:t>                   </w:r>                 </w:p>               </w:tc>               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1659" w:type="dxa"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>刀</w:t>                   </w:r>                 </w:p>               </w:tc>               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1659" w:type="dxa"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>物品数量</w:t>                   </w:r>                 </w:p>               </w:tc>               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1660" w:type="dxa"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>2</w:t>                   </w:r>                 </w:p>               </w:tc>             </w:tr> 上面是合并单元格的首行,所以你可以找到<w:vMerge w:val="restart"/>标签标签说明:<w:tr></w:tr>  ---行标签<w:tc></w:tc>  ---单元格标签我们继续看下面的一行xml第二行表格xml:<w:tr w:rsidR="00770B3E" w:rsidTr="00CC5D94">               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1659" w:type="dxa"/>                   <w:vMerge/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333"/>               </w:tc>               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1659" w:type="dxa"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>物品说明</w:t>                   </w:r>                 </w:p>               </w:tc>               <w:tc>                 <w:tcPr>                   <w:tcW w:w="4978" w:type="dxa"/>                   <w:gridSpan w:val="3"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                   <w:proofErr w:type="gramStart"/>                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>刀非常</w:t>                   </w:r>                   <w:proofErr w:type="gramEnd"/>                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>锋利</w:t>                   </w:r>                 </w:p>               </w:tc>             </w:tr> 继续第三行:            <w:tr w:rsidR="00770B3E" w:rsidTr="00AB3846">               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1659" w:type="dxa"/>                   <w:vMerge/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333"/>               </w:tc>               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1659" w:type="dxa"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>上架时间</w:t>                   </w:r>                 </w:p>               </w:tc>               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1659" w:type="dxa"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>2</w:t>                   </w:r>                   <w:r>                     <w:t>019</w:t>                   </w:r>                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>-</w:t>                   </w:r>                   <w:r>                     <w:t>08</w:t>                   </w:r>                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>-</w:t>                   </w:r>                   <w:r>                     <w:t>09</w:t>                   </w:r>                 </w:p>               </w:tc>               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1659" w:type="dxa"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>上架人</w:t>                   </w:r>                 </w:p>               </w:tc>               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1660" w:type="dxa"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>小左</w:t>                   </w:r>                 </w:p>               </w:tc>             </w:tr> 从第二行,第三行可以找到<w:vMerge/>标签,标识这这列产生了合并              <w:tc>                 <w:tcPr>                   <w:tcW w:w="1659" w:type="dxa"/>                   <w:vMerge/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333"/>               </w:tc> 并且<w:vMerge/>就在第一个单元格内。那么模板就好改了。思路:首先循环判断是否第一条数据第一条数据那么就使用行1的格式。后面的都使用合并后的格式提取需要做模板的几行进行组建,通过上面我们可以知道,其实我们就是要循环以下三行表格:            <w:tr w:rsidR="00770B3E" w:rsidTr="00AB3846">               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1659" w:type="dxa"/>                   <w:vMerge w:val="restart"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRPr="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">                   <w:pPr>                     <w:jc w:val="center"/>                     <w:rPr>                       <w:b/>                     </w:rPr>                   </w:pPr>                   <w:r w:rsidRPr="00770B3E">                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                       <w:b/>                     </w:rPr>                     <w:t>物品信息</w:t>                   </w:r>                 </w:p>               </w:tc>               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1659" w:type="dxa"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>物品名称</w:t>                   </w:r>                 </w:p>               </w:tc>               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1659" w:type="dxa"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>刀</w:t>                   </w:r>                 </w:p>               </w:tc>               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1659" w:type="dxa"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>物品数量</w:t>                   </w:r>                 </w:p>               </w:tc>               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1660" w:type="dxa"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>2</w:t>                   </w:r>                 </w:p>               </w:tc>             </w:tr>             <w:tr w:rsidR="00770B3E" w:rsidTr="00CC5D94">               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1659" w:type="dxa"/>                   <w:vMerge/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333"/>               </w:tc>               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1659" w:type="dxa"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>物品说明</w:t>                   </w:r>                 </w:p>               </w:tc>               <w:tc>                 <w:tcPr>                   <w:tcW w:w="4978" w:type="dxa"/>                   <w:gridSpan w:val="3"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                   <w:proofErr w:type="gramStart"/>                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>刀非常</w:t>                   </w:r>                   <w:proofErr w:type="gramEnd"/>                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>锋利</w:t>                   </w:r>                 </w:p>               </w:tc>             </w:tr>             <w:tr w:rsidR="00770B3E" w:rsidTr="00AB3846">               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1659" w:type="dxa"/>                   <w:vMerge/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333"/>               </w:tc>               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1659" w:type="dxa"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>上架时间</w:t>                   </w:r>                 </w:p>               </w:tc>               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1659" w:type="dxa"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>2</w:t>                   </w:r>                   <w:r>                     <w:t>019</w:t>                   </w:r>                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>-</w:t>                   </w:r>                   <w:r>                     <w:t>08</w:t>                   </w:r>                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>-</w:t>                   </w:r>                   <w:r>                     <w:t>09</w:t>                   </w:r>                 </w:p>               </w:tc>               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1659" w:type="dxa"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>上架人</w:t>                   </w:r>                 </w:p>               </w:tc>               <w:tc>                 <w:tcPr>                   <w:tcW w:w="1660" w:type="dxa"/>                 </w:tcPr>                 <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                   <w:r>                     <w:rPr>                       <w:rFonts w:hint="eastAsia"/>                     </w:rPr>                     <w:t>小左</w:t>                   </w:r>                 </w:p>               </w:tc> 接下来就针对这部分进行模板标签的编写说明:Java代码后面给出,现在说明的是集合的key为 goodsList(物品集合)循环片段代码格式缩进后如图图6上图其实就是判断了是否第一条记录,第一条记录和后面记录的区别就是第一行的第一个单元格,第一条记录的第一个单元格是写的”物品信息“后面的记录第一个单元格都是合并单元格的cell代码。以下为循环片段代码:          <#list goodsList! as goods>             <#if goods_index == 0 >               <w:tr w:rsidR="00770B3E" w:rsidTr="00AB3846">                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1659" w:type="dxa"/>                     <w:vMerge w:val="restart"/>                     <w:vAlign w:val="center"/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRPr="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">                     <w:pPr>                       <w:jc w:val="center"/>                       <w:rPr>                         <w:b/>                       </w:rPr>                     </w:pPr>                     <w:r w:rsidRPr="00770B3E">                       <w:rPr>                         <w:rFonts w:hint="eastAsia"/>                         <w:b/>                       </w:rPr>                       <w:t>物品信息</w:t>                     </w:r>                   </w:p>                 </w:tc>                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1659" w:type="dxa"/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                     <w:r>                       <w:rPr>                         <w:rFonts w:hint="eastAsia"/>                       </w:rPr>                       <w:t>物品名称</w:t>                     </w:r>                   </w:p>                 </w:tc>                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1659" w:type="dxa"/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                     <w:r>                       <w:rPr>                         <w:rFonts w:hint="eastAsia"/>                       </w:rPr>                       <w:t>${goods.name}</w:t>                     </w:r>                   </w:p>                 </w:tc>                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1659" w:type="dxa"/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                     <w:r>                       <w:rPr>                         <w:rFonts w:hint="eastAsia"/>                       </w:rPr>                       <w:t>物品数量</w:t>                     </w:r>                   </w:p>                 </w:tc>                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1660" w:type="dxa"/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                     <w:r>                       <w:rPr>                         <w:rFonts w:hint="eastAsia"/>                       </w:rPr>                       <w:t>${goods.number}</w:t>                     </w:r>                   </w:p>                 </w:tc>               </w:tr>               <w:tr w:rsidR="00770B3E" w:rsidTr="00CC5D94">                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1659" w:type="dxa"/>                     <w:vMerge/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333"/>                 </w:tc>                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1659" w:type="dxa"/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                     <w:r>                       <w:rPr>                         <w:rFonts w:hint="eastAsia"/>                       </w:rPr>                       <w:t>物品说明</w:t>                     </w:r>                   </w:p>                 </w:tc>                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="4978" w:type="dxa"/>                     <w:gridSpan w:val="3"/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                     <w:r>                       <w:rPr>                         <w:rFonts w:hint="eastAsia"/>                       </w:rPr>                       <w:t>${goods.description}</w:t>                     </w:r>                   </w:p>                 </w:tc>               </w:tr>               <w:tr w:rsidR="00770B3E" w:rsidTr="00AB3846">                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1659" w:type="dxa"/>                     <w:vMerge/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333"/>                 </w:tc>                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1659" w:type="dxa"/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                     <w:r>                       <w:rPr>                         <w:rFonts w:hint="eastAsia"/>                       </w:rPr>                       <w:t>上架时间</w:t>                     </w:r>                   </w:p>                 </w:tc>                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1659" w:type="dxa"/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                     <w:r>                       <w:rPr>                         <w:rFonts w:hint="eastAsia"/>                       </w:rPr>                       <w:t>${goods.time}</w:t>                     </w:r>                   </w:p>                 </w:tc>                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1659" w:type="dxa"/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                     <w:r>                       <w:rPr>                         <w:rFonts w:hint="eastAsia"/>                       </w:rPr>                       <w:t>上架人</w:t>                     </w:r>                   </w:p>                 </w:tc>                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1660" w:type="dxa"/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="003A3333">                     <w:r>                       <w:rPr>                         <w:rFonts w:hint="eastAsia"/>                       </w:rPr>                       <w:t>${goods.user}</w:t>                     </w:r>                   </w:p>                 </w:tc>               </w:tr>             <#else>               <w:tr w:rsidR="00770B3E" w:rsidTr="00AB3846">                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1659" w:type="dxa"/>                     <w:vMerge/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E"/>                 </w:tc>                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1659" w:type="dxa"/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">                     <w:r>                       <w:rPr>                         <w:rFonts w:hint="eastAsia"/>                       </w:rPr>                       <w:t>物品名称</w:t>                     </w:r>                   </w:p>                 </w:tc>                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1659" w:type="dxa"/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">                     <w:r>                       <w:rPr>                         <w:rFonts w:hint="eastAsia"/>                       </w:rPr>                       <w:t>${goods.name}</w:t>                     </w:r>                   </w:p>                 </w:tc>                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1659" w:type="dxa"/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">                     <w:r>                       <w:rPr>                         <w:rFonts w:hint="eastAsia"/>                       </w:rPr>                       <w:t>物品数量</w:t>                     </w:r>                   </w:p>                 </w:tc>                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1660" w:type="dxa"/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">                     <w:r>                       <w:rPr>                         <w:rFonts w:hint="eastAsia"/>                       </w:rPr>                       <w:t>${goods.number}</w:t>                     </w:r>                   </w:p>                 </w:tc>               </w:tr>               <w:tr w:rsidR="00770B3E" w:rsidTr="00644BE9">                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1659" w:type="dxa"/>                     <w:vMerge/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E"/>                 </w:tc>                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1659" w:type="dxa"/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">                     <w:r>                       <w:rPr>                         <w:rFonts w:hint="eastAsia"/>                       </w:rPr>                       <w:t>物品说明</w:t>                     </w:r>                   </w:p>                 </w:tc>                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="4978" w:type="dxa"/>                     <w:gridSpan w:val="3"/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">                     <w:r>                       <w:rPr>                         <w:rFonts w:hint="eastAsia"/>                       </w:rPr>                       <w:t>${goods.description}</w:t>                     </w:r>                   </w:p>                 </w:tc>               </w:tr>               <w:tr w:rsidR="00770B3E" w:rsidTr="00AB3846">                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1659" w:type="dxa"/>                     <w:vMerge/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E"/>                 </w:tc>                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1659" w:type="dxa"/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">                     <w:r>                       <w:rPr>                         <w:rFonts w:hint="eastAsia"/>                       </w:rPr>                       <w:t>上架时间</w:t>                     </w:r>                   </w:p>                 </w:tc>                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1659" w:type="dxa"/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">                     <w:r>                       <w:rPr>                         <w:rFonts w:hint="eastAsia"/>                       </w:rPr>                       <w:t>${goods.time}</w:t>                     </w:r>                   </w:p>                 </w:tc>                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1659" w:type="dxa"/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">                     <w:r>                       <w:rPr>                         <w:rFonts w:hint="eastAsia"/>                       </w:rPr>                       <w:t>上架人</w:t>                     </w:r>                   </w:p>                 </w:tc>                 <w:tc>                   <w:tcPr>                     <w:tcW w:w="1660" w:type="dxa"/>                   </w:tcPr>                   <w:p w:rsidR="00770B3E" w:rsidRDefault="00770B3E" w:rsidP="00770B3E">                     <w:r>                       <w:rPr>                         <w:rFonts w:hint="eastAsia"/>                       </w:rPr>                       <w:t>${goods.user}</w:t>                     </w:r>                   </w:p>                 </w:tc>               </w:tr>             </#if>           </#list> 将上面代码放入demo.xml文件中替换掉原来的两个假数据行。替换后如下:(由于数据多,这里就截图展示)​将上诉的demo.xml保存并改为demo.ftl即完成freemarker的模板。提示:这里说下为啥要if else ,因为第一次生成的行需要展示合并的单元格,后面的整个数据都是一个合并标签。当然简单化也可以在第一行的第一个单元格做if else不需要像我这样整个循环体做if else三、编写freemarker模板导出复杂格式word代码 首先把上面制作的demo.ftl放入Java项目的classpath目录下Java数据模型Goods$title(Goods.java) package demo; public class Goods {     public Goods(String name, Integer number, String description, String time, String user) {         this.name = name;         this.number = number;         this.description = description;         this.time = time;         this.user = user;     }     String name;     Integer number;     String description;     String time;     String user;     public String getName() {         return name;     }     public void setName(String name) {         this.name = name;     }     public Integer getNumber() {         return number;     }     public void setNumber(Integer number) {         this.number = number;     }     public String getDescription() {         return description;     }     public void setDescription(String description) {         this.description = description;     }     public String getTime() {         return time;     }     public void setTime(String time) {         this.time = time;     }     public String getUser() {         return user;     }     public void setUser(String user) {         this.user = user;     } } 导出代码:$title(ComplexWordExport.java) package demo; import freemarker.template.Configuration; import freemarker.template.Template; import java.io.*; import java.text.SimpleDateFormat; import java.util.*; public class ComplexWordExport {     public static void main(String[] args) {         try {             // 创建模拟数据             List<Goods> goodsList = new ArrayList<>();             for (int i = 0; i < 4; i++) {                 goodsList.add(new Goods("刀" + i, i + 2, "到很好不错,数量多+" + i,                         new SimpleDateFormat("HH:mm:ss:SSS").format(new Date()), "用户" + i));             }             Map<String ,Object> dataMap=new HashMap<>();             dataMap.put("goodsList",goodsList);//注意这里的key与目标中的数据对应             File wordFile = new File("d:/demo.doc");// 注意这里只能输出doc,不能直接输出docx             Configuration configuration = new Configuration();             configuration.setDefaultEncoding("UTF-8");             configuration.setClassForTemplateLoading(WordTest.class, "/");             // 模板来源             // 1.创建一个word文件可以是doc或者docx的             // 2.在需要使用变量的地方用占位符占位             // 3.将word文档另存为xml文件             // 4.打开xml文件将里面的占位符替换为freemarker的表达式             // 5.重命名xml为ftl             // 6.完成             Template template = configuration.getTemplate("demo/demo.ftl", "UTF-8");//路径相对于项目的classpath             try (Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(wordFile),"UTF-8"))) {                 template.process(dataMap, out);                 out.flush();             }         } catch (Exception e) {             e.printStackTrace();         }     } }四、导出结果 ​注意:导出文件必须是.doc因为docx会验证xml里面的一些数据导致文件打不开。提示:项目源码下载demo-word-export-template-freemarker.zip
  • Spring boot 入门(一)环境搭建以及第一个应用

    spring boot又一个spring框架的经典项目,本文讲解spring boot入门的环境配置以及第一个项目,Spring Boot 入门教程<h2>一.Spring boot与spring MVC的关系</h2> 两者没有必然的联系,但是spring boot可以看作为spring MVC的升级版 <h2>二.SpringBoot的特点</h2> 1.化繁为简,简化配置(最大特点)<br /> 2.备受关注,是下一代spring框架<br /> 3.微服务的入门级微框架 <h2>三.环境准备</h2> 打开eclipse安装spring的工具插件STS<br /> 安装方法:<br /> 1.电脑连接网络<br /> 2.依次选择eclipse的 help >Eclipse Marketplace<br /> 3.搜索STS<br /> <img alt="eclipse STS插件" class="img-thumbnail" src="/assist/images/blog/a8bed2d8-ef19-4f83-9820-3b2483e38f7c.jpg" style="height:895px; width:616px" /><br /> 安装上图勾选的STS<br /> <strong><span style="color:#ff0000">注意:安装过程中电脑需要连接网络</span></strong> <h2>四.创建第一个spring boot项目</h2> 1.新建项目,选择Spring Starter Project<br /> <img alt="创建项目" class="img-thumbnail" src="/assist/images/blog/e06cf223-126c-4fc4-a7ce-91adf8daa894.jpg" style="height:500px; width:525px" /><br /> 2.填写项目相关信息<br /> <img alt="项目信息" class="img-thumbnail" src="/assist/images/blog/0a8493c1-3eae-47e2-9eaa-276bc67888ad.jpg" style="height:822px; width:910px" /><br /> 我默认的<br /> <br /> 3.选择Spring Boot版本以及依赖完成项目创建<br /> 版本选择的1.51,依赖选择了一个web,点击finish完成项目的创建<br /> <img alt="版本以及依赖" class="img-thumbnail" src="/assist/images/blog/735b4093-dd69-4c01-b462-8ec61eaa9636.jpg" style="height:822px; width:910px" /><br /> <br /> 4.项目结构<br /> <img alt="项目结构" class="img-thumbnail" src="/assist/images/blog/be08ce18-9a47-4b55-b249-8a6966ae3d1e.jpg" style="height:458px; width:337px" /><br /> 5.删除一些不需要的文件<br />  1>删除 mvnw <br />  2>删除 mvw.cmd<br /> 6.项目说明<br /> 1.默认有个DemoApplication类,里面是spring boot的载入函数<br /> 2.resource目录下有个application.properties文件,这个是Spring boot的配置文件<br /> 3.test目录下有个测试类DemoApplicationTests,这个是spring boot的单元测试<br /> 4.pom.xml文件 <pre> <code class="language-xml"><?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>demo</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> </code></pre> 注意观察<br /> 一个继承spring-boot-starter-parent,两个依赖,spring-boot-starter-web web项目依赖必须,spring-boot-starter-test spring boot项目单元测试依赖<br /> <br /> 7.启动项目<br /> 通过spring boot的启动类,这里是DemoApplication<br /> <img alt="启动" class="img-thumbnail" src="/assist/images/blog/1fc2ffe5-1a04-4366-8eb4-b413b2b2beab.jpg" style="height:282px; width:826px" /><br /> 选择Run As > Spring Boot App<br /> <img alt="启动完成" class="img-thumbnail" src="/assist/images/blog/d16c24c1-29b8-4358-9fc3-46f1d40ff638.jpg" style="height:608px; width:1039px" /><br /> 上面标示启动完成,<br /> tomcat启动在8080端口,http协议,启动花费了1.707秒<br /> 打开浏览器,输入地址:<br /> <img alt="错误" class="img-thumbnail" src="/assist/images/blog/fec5e96d-1df2-4dca-8d83-ceffa8ef9d14.jpg" style="height:338px; width:858px" /><br />  出现上图404错误是正常的,因为我们什么都没写<br /> <br /> 8.编写一个HelloController <pre> <code class="language-java">package com.example; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; /** * create leftso.com */ @RestController public class HelloController { @RequestMapping(value="/hello",method=RequestMethod.GET)//写法与springMVC有点相似 public String say(){ return "Hello Spring Boot!"; } } </code></pre> <br /> 重启应用<br /> <img alt="hello映射" class="img-thumbnail" src="/assist/images/blog/585368fb-27ee-43e8-942b-d453bb956548.jpg" style="height:341px; width:914px" /><br /> 重启发现刚才写的hello已经映射出来了<br /> 访问/hello<br /> <img alt="/hello" class="img-thumbnail" src="/assist/images/blog/85f84416-c48f-4c71-8c20-d9848300e4eb.jpg" style="height:242px; width:480px" /><br /> 这时候已经出来我们写的内容了<br /> <br /> <br /> Spring Boot 第一个项目hello就完成了。<br /> <br /> 推荐: <p><a rel="" target="_blank"href="http://www.leftso.com/blog/65.html" rel="" target="_blank">spring boot入门(二)属性配置</a><br /> <a rel="" target="_blank"href="http://www.leftso.com/blog/66.html" rel="" target="_blank">spring boot入门(三)controller的使用</a><br /> <a rel="" target="_blank"href="http://www.leftso.com/blog/67.html" rel="" target="_blank">spring boot入门(四)数据库操作</a></p> <p> </p>
  • java实现生成彩色背景图片验证码

    java实现生成彩色背景图片验证码,在登陆和注册可以使用,工具类将图片的IO流通过response输出到浏览器,在浏览器中可以使用 img标签的src属性路径写上该工具类的访问路径即可。1.页面展现 <pre> <code class="language-html"><img id="cerificationCode" src="/front/user/cardCoupon/getCerificationCode" style="margin -left: 62px" onclick="javascript:this.src='/front/user/cardCoupon/getCerificationCode?'+Math.random()"> <a style="color: #dbb04f; font-size: 0.8em; position: relative; bottom: 8px; margin-left: 5px;" onclick="javascript:$('#cerificationCode').click();">换一个</a></code></pre> <!--StartFragment -->注意:onclick="javascript:this.src='/front/user/cardCoupon/getCerificationCode?'+Math.random()"是为了刷新验证码一般都会给个随机数,必须保证每次请求的url不同 ,浏览器才会去服务端获取最新数据,相同的url浏览器优先找自己本地缓存的.<br /> <br /> 2.控制层 <pre> <code class="language-java"> @Controller @RequestMapping("/front/user/cardCoupon") public class CardCouponController extends BaseController { @RequestMapping("/getCerificationCode") public void getCerificationCode(HttpServletRequest request, HttpServletResponse response) { try { response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); response.setContentType("image/jpeg"); // 生成随机字串 String verifyCode = VerifyCodeUtils.generateVerifyCode(4); // 存入会话session HttpSession session = request.getSession(true); // 删除以前的 session.removeAttribute("cerificationCode"); session.setAttribute("cerificationCode", verifyCode.toLowerCase()); // 生成图片 int w = 100, h = 30; VerifyCodeUtils.outputImage(w, h, response.getOutputStream(), verifyCode); } catch (IOException e) { log.error("获取验证码失败", e); e.printStackTrace(); } }</code></pre> 3.生成图片验证码工具类 <pre> <code class="language-java">package com.xinfeng.util; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Arrays; import java.util.Random; import javax.imageio.ImageIO; public class VerifyCodeUtils { public static final String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ"; private static Random random = new Random(); /** * 使用系统默认字符源生成验证码 * * @param verifySize * 验证码长度 * @return */ public static String generateVerifyCode(int verifySize) { return generateVerifyCode(verifySize, VERIFY_CODES); } /** * 使用指定源生成验证码 * * @param verifySize * 验证码长度 * @param sources * 验证码字符源 * @return */ public static String generateVerifyCode(int verifySize, String sources) { if (sources == null || sources.length() == 0) { sources = VERIFY_CODES; } int codesLen = sources.length(); Random rand = new Random(System.currentTimeMillis()); StringBuilder verifyCode = new StringBuilder(verifySize); for (int i = 0; i < verifySize; i++) { verifyCode.append(sources.charAt(rand.nextInt(codesLen))); } return verifyCode.toString(); } /** * 生成随机验证码文件,并返回验证码值 * * @param w * @param h * @param outputFile * @param verifySize * @return * @throws IOException */ public static String outputVerifyImage(int w, int h, File outputFile, int verifySize) throws IOException { String verifyCode = generateVerifyCode(verifySize); outputImage(w, h, outputFile, verifyCode); return verifyCode; } /** * 输出随机验证码图片流,并返回验证码值 * * @param w * @param h * @param os * @param verifySize * @return * @throws IOException */ public static String outputVerifyImage(int w, int h, OutputStream os, int verifySize) throws IOException { String verifyCode = generateVerifyCode(verifySize); outputImage(w, h, os, verifyCode); return verifyCode; } /** * 生成指定验证码图像文件 * * @param w * @param h * @param outputFile * @param code * @throws IOException */ public static void outputImage(int w, int h, File outputFile, String code) throws IOException { if (outputFile == null) { return; } File dir = outputFile.getParentFile(); if (!dir.exists()) { dir.mkdirs(); } try { outputFile.createNewFile(); FileOutputStream fos = new FileOutputStream(outputFile); outputImage(w, h, fos, code); fos.close(); } catch (IOException e) { throw e; } } /** * 输出指定验证码图片流 * * @param w * @param h * @param os * @param code * @throws IOException */ public static void outputImage(int w, int h, OutputStream os, String code) throws IOException { int verifySize = code.length(); BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Random rand = new Random(); Graphics2D g2 = image.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); Color[] colors = new Color[5]; Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN, Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.YELLOW }; float[] fractions = new float[colors.length]; for (int i = 0; i < colors.length; i++) { colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)]; fractions[i] = rand.nextFloat(); } Arrays.sort(fractions); // Color c = getRandColor(200, 250); Color c = new Color(241, 238, 231); g2.setColor(c);// 设置背景色 g2.fillRect(0, 0, w, h); // 绘制干扰线 Random random = new Random(); g2.setColor(getRandColor(160, 200));// 设置线条的颜色 for (int i = 0; i < 20; i++) { int x = random.nextInt(w - 1); int y = random.nextInt(h - 1); int xl = random.nextInt(6) + 1; int yl = random.nextInt(12) + 1; g2.drawLine(x, y, x + xl + 40, y + yl + 20); } // 添加噪点 float yawpRate = 0.05f;// 噪声率 int area = (int) (yawpRate * w * h); for (int i = 0; i < area; i++) { int x = random.nextInt(w); int y = random.nextInt(h); int rgb = getRandomIntColor(); image.setRGB(x, y, rgb); } shear(g2, w, h, c);// 使图片扭曲 // g2.setColor(getRandColor(100, 160)); g2.setColor(new Color(208, 153, 153)); int fontSize = h - 4; Font font = new Font("Algerian", Font.ITALIC, fontSize); g2.setFont(font); char[] chars = code.toCharArray(); for (int i = 0; i < verifySize; i++) { AffineTransform affine = new AffineTransform(); affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize / 2, h / 2); g2.setTransform(affine); g2.translate(5, 5); g2.drawChars(chars, i, 1, ((w - 10) / verifySize) * i + 5, h / 2 + fontSize / 2 - 10); } g2.dispose(); ImageIO.write(image, "jpg", os); } private static Color getRandColor(int fc, int bc) { if (fc > 255) fc = 255; if (bc > 255) bc = 255; int r = fc + random.nextInt(bc - fc); int g = fc + random.nextInt(bc - fc); int b = fc + random.nextInt(bc - fc); return new Color(r, g, b); } private static int getRandomIntColor() { int[] rgb = getRandomRgb(); int color = 0; for (int c : rgb) { color = color << 8; color = color | c; } return color; } private static int[] getRandomRgb() { int[] rgb = new int[3]; for (int i = 0; i < 3; i++) { rgb[i] = random.nextInt(255); } return rgb; } private static void shear(Graphics g, int w1, int h1, Color color) { /* * shearX(g, w1, h1, color); shearY(g, w1, h1, color); */ } private static void shearX(Graphics g, int w1, int h1, Color color) { int period = random.nextInt(2); boolean borderGap = true; int frames = 1; int phase = random.nextInt(2); for (int i = 0; i < h1; i++) { double d = (double) (period >> 1) * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames); g.copyArea(0, i, w1, 1, (int) d, 0); if (borderGap) { g.setColor(color); g.drawLine((int) d, i, 0, i); g.drawLine((int) d + w1, i, w1, i); } } } private static void shearY(Graphics g, int w1, int h1, Color color) { int period = random.nextInt(40) + 10; // 50; boolean borderGap = true; int frames = 20; int phase = 7; for (int i = 0; i < w1; i++) { double d = (double) (period >> 1) * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames); g.copyArea(i, 0, 1, h1, 0, (int) d); if (borderGap) { g.setColor(color); g.drawLine(i, (int) d, i, 0); g.drawLine(i, (int) d + h1, i, h1); } } } } </code></pre> 4.展现结果<br /> <img src="file:///C:\Users\Administrator\AppData\Roaming\Tencent\Users\1023803178\QQ\WinTemp\RichOle\18955_V`_5P9O)YU]~}{U3R.png" /><img alt="" class="img-thumbnail" src="/assist/images/blog/7826a5549c5e47728c7e9dace3667280.png" /><br />