项目结构图
Eureka 注册中心
CloudNewEurekaApplication
@SpringBootApplication
@EnableEurekaServer
public class CloudNewEurekaApplication {
public static void main ( String [ ] args) {
SpringApplication . run ( CloudNewEurekaApplication . class , args) ;
}
}
application.yml
spring:
application:
name: cloud- news- eureka
server:
port: 8899
eureka:
instance:
hostname: eurekaDemo
client:
service- url:
defaultZone: http: / / 127.0 .0 .1 : ${ server. port} / eureka
register- with - eureka: false
fetch- registry: false
网关
CloudNewsZuulApplication
@SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy
public class CloudNewsZuulApplication {
public static void main ( String [ ] args) {
SpringApplication . run ( CloudNewsZuulApplication . class , args) ;
}
}
application.yml
spring:
application:
name: cloud- news- zuul
server:
port: 8877
eureka:
client:
registry- fatch- interval- seconds: 5 # 获取服务列表的周期
service- url:
defaultZone: http: / / 127.0 .0 .1 : 8899 / eureka
zuul:
routes:
springCloudDemoService: #路由名称 通常是微服务的名称
path: / cloud- news- query
utlis工具模块
CodeEnum
public enum CodeEnum {
SUCCESS ( 200 , "success" ) ,
FAil ( 400 , "active error" ) ,
UNFOUNDED ( 404 , "not found" ) ,
ERROR ( 500 , "error" ) ;
public Integer code;
public String message;
CodeEnum ( Integer code, String message) {
this . code = code;
this . message = message;
}
}
ResultDTO
public class ResultDTO < T > {
private Integer code;
private String message;
private T data;
public ResultDTO ( Integer code, String message, T data) {
this . code = code;
this . message = message;
this . data = data;
}
public ResultDTO ( ) {
}
public Integer getCode ( ) {
return code;
}
public void setCode ( Integer code) {
this . code = code;
}
public String getMessage ( ) {
return message;
}
public void setMessage ( String message) {
this . message = message;
}
public T getData ( ) {
return data;
}
public void setData ( T data) {
this . data = data;
}
@Override
public String toString ( ) {
return "ResultDTO{" +
"code=" + code +
", message='" + message + '\'' +
", data=" + data. toString ( ) +
'}' ;
}
}
ResultUtil
public class ResultUtil {
public static < T > ResultDTO < T > success ( T data) {
return new ResultDTO < T > ( CodeEnum . SUCCESS. code, CodeEnum . SUCCESS. message, data) ;
}
public static < T > ResultDTO < T > success ( ) {
return new ResultDTO < T > ( CodeEnum . SUCCESS. code, CodeEnum . SUCCESS. message, null ) ;
}
public static < T > ResultDTO < T > success ( String message, T data) {
return new ResultDTO < T > ( CodeEnum . SUCCESS. code, message, data) ;
}
public static < T > ResultDTO < T > error ( Integer code, String message) {
return new ResultDTO < T > ( code, message, null ) ;
}
public static < T > ResultDTO < T > error ( Integer code, String message, T data) {
return new ResultDTO < T > ( code, message, data) ;
}
}
pojo模块
Category
public class Category {
private int id;
private String cname;
public Category ( ) {
}
public Category ( int id, String cname) {
this . id = id;
this . cname = cname;
}
@Override
public String toString ( ) {
return "Category{" +
"id=" + id +
", cname='" + cname + '\'' +
'}' ;
}
public int getId ( ) {
return id;
}
public void setId ( int id) {
this . id = id;
}
public String getCname ( ) {
return cname;
}
public void setCname ( String cname) {
this . cname = cname;
}
}
News
public class News {
private int id;
private int categoryid;
private String title;
private String summary;
private String author;
private Date createDate;
public News ( ) {
}
public News ( int id, int categoryid, String title, String summary, String author, Date createDate) {
this . id = id;
this . categoryid = categoryid;
this . title = title;
this . summary = summary;
this . author = author;
this . createDate = createDate;
}
@Override
public String toString ( ) {
return "News{" +
"id=" + id +
", categoryid=" + categoryid +
", title='" + title + '\'' +
", summary='" + summary + '\'' +
", author='" + author + '\'' +
", createDate=" + createDate +
'}' ;
}
public int getId ( ) {
return id;
}
public void setId ( int id) {
this . id = id;
}
public int getCategoryid ( ) {
return categoryid;
}
public void setCategoryid ( int categoryid) {
this . categoryid = categoryid;
}
public String getTitle ( ) {
return title;
}
public void setTitle ( String title) {
this . title = title;
}
public String getSummary ( ) {
return summary;
}
public void setSummary ( String summary) {
this . summary = summary;
}
public String getAuthor ( ) {
return author;
}
public void setAuthor ( String author) {
this . author = author;
}
public Date getCreateDate ( ) {
return createDate;
}
public void setCreateDate ( Date createDate) {
this . createDate = createDate;
}
}
mapper模块
CategoryMapper
@Mapper
@Repository
public interface CategoryMapper {
@Select ( "select * from category" )
List < Category > findCategoryAll ( ) ;
}
CategoryMapper.xml
< ? xml version= "1.0" encoding= "UTF-8" ? >
< ! DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
< ! -- namespace;命名空间 -- >
< mapper namespace= "pre.cg.cloudnewsmapper.mapper.CategoryMapper" >
< / mapper>
NewsMapper
@Mapper
@Repository
public interface NewsMapper {
@Select ( "select * from news" )
List < News > findNewsAll ( ) ;
@Select ( "select * from news where id = #{id}" )
News findNewsById ( @Param ( "id" ) Integer id) ;
@Update ( "update news set title=#{title},summary=#{summary},author=#{author} where id=#{id}" )
int updateNewsById ( News news) ;
@Select ( "select * from news where categoryid = #{categoryid} and title like concat('%',#{title},'%') " )
List < News > findByCategoryIdTitle ( News news) ;
@Select ( "select * from news where title like concat('%',#{title},'%') " )
List < News > findByCategoryTitle ( News news) ;
}
NewsMapper.xml
< ? xml version= "1.0" encoding= "UTF-8" ? >
< ! DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
< ! -- namespace;命名空间 -- >
< mapper namespace= "pre.cg.cloudnewsmapper.mapper.NewsMapper" >
< / mapper>
查询query模块
application.yml
spring:
application:
name: cloud- news- query
datasource:
driver- class - name: com. mysql. jdbc. Driver
name: defaultDataSource
url: jdbc: mysql: / / localhost: 3306 / cgmybatis? serverTimezone= GMT% 2 B8& useUnicode= true & characterEncoding= utf8& useSSL= false
username: root
password: root
server:
port: 8081
eureka:
client:
service- url:
defaultZone: http: / / 127.0 .0 .1 : 8899 / eureka
CloudNewsQueryApplication
@SpringBootApplication
@EnableEurekaClient
@MapperScan ( "pre.cg.cloudnewsmapper.mapper" )
public class CloudNewsQueryApplication {
public static void main ( String [ ] args) {
SpringApplication . run ( CloudNewsQueryApplication . class , args) ;
}
}
CategoryController
@RestController
public class CategoryController {
@Autowired
CategoryService categoryService;
@GetMapping ( "/queryCategory" )
public ResultDTO < List < Category > > queryCategory ( ) {
List < Category > categoryAll = categoryService. findCategoryAll ( ) ;
ResultDTO < List < Category > > success = ResultUtil . success ( categoryAll) ;
return success;
}
}
NewsQueryController
@RestController
public class NewsQueryController {
@Autowired
NewsService newsService;
@GetMapping ( "/queryNews" )
public ResultDTO < List < News > > queryNews ( ) {
List < News > newsAll = newsService. findNewsAll ( ) ;
ResultDTO < List < News > > success = ResultUtil . success ( newsAll) ;
return success;
}
@GetMapping ( "/queryNewById" )
public ResultDTO < News > queryNewById ( @RequestParam ( name = "id" ) Integer id) {
News newsById = newsService. findNewsById ( id) ;
return ResultUtil . success ( newsById) ;
}
@PostMapping ( "/findByCategoryIdTitle" )
public ResultDTO < List < News > > findByCategoryIdTitle ( @RequestBody News news) {
List < News > newsList = null ;
if ( news. getCategoryid ( ) == 0 ) {
newsList = newsService. findByCategoryTitle ( news) ;
} else {
newsList = newsService. findByCategoryIdTitle ( news) ;
}
return ResultUtil . success ( newsList) ;
} `public interface NewsService {
List < News > findNewsAll ( ) ;
News findNewsById ( Integer id) ;
List < News > findByCategoryIdTitle ( News news) ;
List < News > findByCategoryTitle ( News news) ;
} `
}
CategoryService
public interface CategoryService {
List < Category > findCategoryAll ( ) ;
}
CategoryServiceImpl
@Service
public class CategoryServiceImpl implements CategoryService {
@Autowired
CategoryMapper categoryMapper;
@Override
public List < Category > findCategoryAll ( ) {
return categoryMapper. findCategoryAll ( ) ;
}
}
NewsServiceImpl
@Service
public class NewsServiceImpl implements NewsService {
@Autowired
NewsMapper newsMapper;
@Override
public List < News > findNewsAll ( ) {
return newsMapper. findNewsAll ( ) ;
}
@Override
public News findNewsById ( Integer id) {
return newsMapper. findNewsById ( id) ;
}
@Override
public List < News > findByCategoryIdTitle ( News news) {
return newsMapper. findByCategoryIdTitle ( news) ;
}
@Override
public List < News > findByCategoryTitle ( News news) {
return newsMapper. findByCategoryTitle ( news) ;
}
}
Edit模块
application.yml
spring:
application:
name: cloud- news- edit
datasource:
driver- class - name: com. mysql. jdbc. Driver
name: defaultDataSource
url: jdbc: mysql: / / localhost: 3306 / cgmybatis? serverTimezone= GMT% 2 B8& useUnicode= true & characterEncoding= utf8& useSSL= false
username: root
password: root
server:
port: 8082
eureka:
client:
service- url:
defaultZone: http: / / 127.0 .0 .1 : 8899 / eureka
CloudNewsEditApplication
@SpringBootApplication
@EnableEurekaClient
@MapperScan ( "pre.cg.cloudnewsmapper.mapper" )
public class CloudNewsEditApplication {
public static void main ( String [ ] args) {
SpringApplication . run ( CloudNewsEditApplication . class , args) ;
}
}
NewsEditController
@RestController
public class NewsEditController {
@Autowired
NewsEditService newsEditService;
@PostMapping ( "/updateNewsById" )
public ResultDTO < Integer > updateNewsById ( @RequestBody News news) {
int i = newsEditService. updateNewsById ( news) ;
return ResultUtil . success ( i) ;
}
}
NewsEditService
public interface NewsEditService {
int updateNewsById ( News news) ;
}
NewsEditServiceImpl
@Service
public class NewsEditServiceImpl implements NewsEditService {
@Autowired
NewsMapper newsMapper;
@Override
public int updateNewsById ( News news) {
return newsMapper. updateNewsById ( news) ;
}
}
web模块
application.yml
spring:
application:
name: cloud- news- web
thymeleaf:
cache: false
encoding: UTF- 8
suffix: . html
mode: HTML
server:
port: 9090
eureka:
client:
service- url:
defaultZone: http: / / 127.0 .0 .1 : 8899 / eureka
#cloud- news- query:
# ribbon:
# NFLoadBalancerRuleClassName : com. netflix. loadbalancer. RandomRule
hystrix:
command:
default :
execution:
isolation:
thread:
timeoutInMilliseconds: 6000
#feign 开启熔断器
feign:
hystrix:
enabled: true
CloudNewsWebApplication
@SpringBootApplication
@EnableFeignClients
@EnableCircuitBreaker
@EnableEurekaServer
public class CloudNewsWebApplication {
public static void main ( String [ ] args) {
SpringApplication . run ( CloudNewsWebApplication . class , args) ;
}
}
NewsFeignClient
@FeignClient ( value = "cloud-news-query" , qualifier = "cloud-news-query" , fallback = NewsClientFallback . class )
public interface NewsFeignClient {
@LoadBalanced
@GetMapping ( "/queryNews" )
ResultDTO < List < News > > queryNews ( ) ;
@LoadBalanced
@GetMapping ( "/queryCategory" )
ResultDTO < List < Category > > queryCategory ( ) ;
@LoadBalanced
@GetMapping ( "/queryNewById" )
ResultDTO < News > queryNewById ( @RequestParam ( name = "id" ) Integer id) ;
@LoadBalanced
@PostMapping ( "/findByCategoryIdTitle" )
ResultDTO < List < News > > findByCategoryIdTitle ( @RequestBody News news) ;
}
NewsEditFeignClient
@FeignClient ( value = "cloud-news-edit" , qualifier = "cloud-news-edit" , fallback = NewsClientFallback . class )
public interface NewsEditFeignClient {
@LoadBalanced
@PostMapping ( "/updateNewsById" )
ResultDTO < Integer > updateNewsById ( @RequestBody News news) ;
}
NewsEditFeignClient
@Component
public class NewsClientFallback implements NewsFeignClient , NewsEditFeignClient {
@Override
public ResultDTO < List < News > > queryNews ( ) {
return ResultUtil . error ( CodeEnum. FAil . code, "请求超时" ) ;
}
@Override
public ResultDTO < List < Category > > queryCategory ( ) {
return ResultUtil . error ( CodeEnum. FAil . code, "请求超时" ) ;
}
@Override
public ResultDTO < News > queryNewById ( Integer id) {
return ResultUtil . error ( CodeEnum. FAil . code, "请求超时" ) ;
}
@Override
public ResultDTO < List < News > > findByCategoryIdTitle ( News news) {
return ResultUtil . error ( CodeEnum. FAil . code, "请求超时" ) ;
}
@Override
public ResultDTO < Integer > updateNewsById ( News news) {
return ResultUtil . error ( CodeEnum. FAil . code, "请求超时" ) ;
}
}
NewsController
@Controller
public class NewsController {
@Qualifier ( "cloud-news-query" )
@Autowired
NewsFeignClient newsFeignClient;
@Qualifier ( "cloud-news-edit" )
@Autowired
NewsEditFeignClient newsEditFeignClient;
@GetMapping ( "/queryNews" )
public ModelAndView queryNews ( @ModelAttribute ( "newsCondition" ) News news) {
ModelAndView modelAndView = new ModelAndView ( ) ;
ResultDTO < List < News > > newsResultDTO = newsFeignClient. queryNews ( ) ;
ResultDTO < List < Category > > categoryResultDTO = newsFeignClient. queryCategory ( ) ;
modelAndView. addObject ( "newsList" , newsResultDTO. getData ( ) ) ;
modelAndView. addObject ( "cateList" , categoryResultDTO. getData ( ) ) ;
modelAndView. setViewName ( "index" ) ;
return modelAndView;
}
@GetMapping ( "/toUpdate/{id}" )
public ModelAndView toupdate ( @PathVariable int id) {
ModelAndView modelAndView = new ModelAndView ( ) ;
ResultDTO < News > newsResultDTO = newsFeignClient. queryNewById ( id) ;
ResultDTO < List < Category > > categoryResultDTO = newsFeignClient. queryCategory ( ) ;
modelAndView. addObject ( "newsDetail" , newsResultDTO. getData ( ) ) ;
modelAndView. addObject ( "categoryList" , categoryResultDTO. getData ( ) ) ;
modelAndView. setViewName ( "updateNews" ) ;
return modelAndView;
}
@PostMapping ( "/doUpdateSubmit" )
public String doUpdateSubmit ( News news) {
ResultDTO < Integer > integerResultDTO = newsEditFeignClient. updateNewsById ( news) ;
return "redirect:/queryNews" ;
}
@PostMapping ( "/queryByCondition" )
public ModelAndView queryByCondition ( @ModelAttribute ( "newsCondition" ) News news) {
ModelAndView modelAndView = new ModelAndView ( ) ;
ResultDTO < List < News > > newsResultDTO = newsFeignClient. findByCategoryIdTitle ( news) ;
ResultDTO < List < Category > > categoryResultDTO = newsFeignClient. queryCategory ( ) ;
modelAndView. addObject ( "newsList" , newsResultDTO. getData ( ) ) ;
modelAndView. addObject ( "cateList" , categoryResultDTO. getData ( ) ) ;
modelAndView. setViewName ( "index" ) ;
return modelAndView;
}
}
index.html
<! DOCTYPE html >
< html xmlns: th= " http://www.thymeleaf.org" >
< head>
< meta charset = " UTF-8" >
< title> 新闻列表</ title>
</ head>
< body>
< form action = " /queryByCondition" method = " post" >
新闻分类
< select name = " categoryid" >
< option value = " 0" > 全部</ option>
< option th: each= " category:${cateList}"
th: value= " ${category.id}"
th: text= " ${category.cname}"
th: selected= " ${newsCondition.categoryid==category.id}" > </ option>
</ select>
标题
< input type = " text" name = " title" th: value= " ${newsCondition.title}" />
< input type = " submit" value = " 查 询" />
</ form>
< table border = " 1px" width = " 90%" >
< tr th: each= " news:${newsList}" >
< td th: text= " ${news.id}" > </ td>
< td th: text= " ${news.title}" > </ td>
< td th: text= " ${news.summary}" > </ td>
< td th: text= " ${news.author}" > </ td>
< td>
< a th: href= " ' /toUpdate/' +${news.id}" > 编辑</ a>
</ td>
</ tr>
</ table>
</ body>
</ html>
<! DOCTYPE html >
< html xmlns: th= " http://www.thymeleaf.org" >
< head>
< meta charset = " UTF-8" >
< title> 新闻编辑</ title>
</ head>
< body>
< form action = " /doUpdateSubmit" method = " post" >
< table width = " 40%" border = " 1px" >
< input type = " hidden" name = " id" th: value= " ${newsDetail.id}" />
< tr>
< td> 标题</ td>
< td> < input type = " text" name = " title" th: value= " ${newsDetail.title}" >
</ td>
</ tr>
< tr>
< td> 类别</ td>
< td>
< select name = " categoryid" >
< option value = " 0" > 全部</ option>
< option th: each= " category:${categoryList}"
th: value= " ${category.id}"
th: text= " ${category.cname}"
th: selected= " ${category.id==newsDetail.categoryid}" > </ option>
</ select>
</ td>
</ tr>
< tr>
< td> 作者</ td>
< td> < input type = " text" name = " author" th: value= " ${newsDetail.author}" > </ td>
</ tr>
< tr>
< td> 摘要</ td>
< td> < textarea cols = " 33" rows = " 8" name = " summary" th: text= " ${newsDetail.summary}" > </ textarea> </ td>
</ tr>
< tr>
< td colspan = " 2" >
< input type = " submit" value = " 提 交" >
</ td>
</ tr>
</ table>
</ form>
</ body>
</ html>