ConfigRegistCenter.java
package com.example.config;
import com.example.interceptor.JwtInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
@Configuration
@EnableWebMvc
public class ConfigRegistCenter implements WebMvcConfigurer {
public void addInterceptors(InterceptorRegistry registry){
registry.addInterceptor(new JwtInterceptor()).addPathPatterns("/**")
.excludePathPatterns("/static/**")
.excludePathPatterns("/customer/login")
.excludePathPatterns("/food/hot")
.excludePathPatterns("/error");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/","classpath:webapp/");
WebMvcConfigurer.super.addResourceHandlers(registry);
}
}
MybatisplusConfig.java
package com.example.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisplusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
paginationInnerInterceptor.setDbType(DbType.MYSQL);
paginationInnerInterceptor.setOverflow(true);
interceptor.addInnerInterceptor(paginationInnerInterceptor);
return interceptor;
}
}
RedisConfig.java
package com.example.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.*;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
private Duration timeToLive = Duration.ofDays(-1);
@Bean
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
JavaTimeModule timeModule = new JavaTimeModule();
timeModule.addDeserializer(LocalDate.class,
new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
timeModule.addDeserializer(LocalDateTime.class,
new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
timeModule.addSerializer(LocalDate.class,
new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
timeModule.addSerializer(LocalDateTime.class,
new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
om.registerModule(timeModule);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(timeToLive)
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer()))
.disableCachingNullValues();
RedisCacheManager redisCacheManager = RedisCacheManager.builder(connectionFactory)
.cacheDefaults(config)
.transactionAware()
.build();
return redisCacheManager;
}
@Bean
RedisMessageListenerContainer listenerContainer(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer listenerContainer = new RedisMessageListenerContainer();
listenerContainer.setConnectionFactory(connectionFactory);
return listenerContainer;
}
private RedisSerializer<String> keySerializer() {
return new StringRedisSerializer();
}
private RedisSerializer<Object> valueSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
}
FoodController.java
package com.example.controller;
import com.example.entity.Food;
import com.example.service.IFoodService;
import com.example.util.ServerResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@RestController
@RequestMapping("/food")
public class FoodController {
@Autowired
private IFoodService foodService;
@GetMapping("hot")
public ServerResult getHotProducts(HttpServletRequest request){
List<Food> list = foodService.getHotFood();
if(list != null && list.size()>0){
ServerResult result = ServerResult.getSuccess(list);
return result;
}
return ServerResult.getFail(null);
}
}
Food.java
package com.example.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
public class Food implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "food_id", type = IdType.AUTO)
private Integer foodId;
private String foodName;
private BigDecimal foodPrice;
private Float foodScore;
private String foodDetail;
private String foodType;
private String foodMainImg;
private Integer foodRecommendStatus;
private LocalDateTime foodCteateTime;
private LocalDateTime foodUpdateTime;
private String other1;
private String other2;
public Integer getFoodId() {
return foodId;
}
public void setFoodId(Integer foodId) {
this.foodId = foodId;
}
public String getFoodName() {
return foodName;
}
public void setFoodName(String foodName) {
this.foodName = foodName;
}
public BigDecimal getFoodPrice() {
return foodPrice;
}
public void setFoodPrice(BigDecimal foodPrice) {
this.foodPrice = foodPrice;
}
public Float getFoodScore() {
return foodScore;
}
public void setFoodScore(Float foodScore) {
this.foodScore = foodScore;
}
public String getFoodDetail() {
return foodDetail;
}
public void setFoodDetail(String foodDetail) {
this.foodDetail = foodDetail;
}
public String getFoodType() {
return foodType;
}
public void setFoodType(String foodType) {
this.foodType = foodType;
}
public String getFoodMainImg() {
return foodMainImg;
}
public void setFoodMainImg(String foodMainImg) {
this.foodMainImg = foodMainImg;
}
public Integer getFoodRecommendStatus() {
return foodRecommendStatus;
}
public void setFoodRecommendStatus(Integer foodRecommendStatus) {
this.foodRecommendStatus = foodRecommendStatus;
}
public LocalDateTime getFoodCteateTime() {
return foodCteateTime;
}
public void setFoodCteateTime(LocalDateTime foodCteateTime) {
this.foodCteateTime = foodCteateTime;
}
public LocalDateTime getFoodUpdateTime() {
return foodUpdateTime;
}
public void setFoodUpdateTime(LocalDateTime foodUpdateTime) {
this.foodUpdateTime = foodUpdateTime;
}
public String getOther1() {
return other1;
}
public void setOther1(String other1) {
this.other1 = other1;
}
public String getOther2() {
return other2;
}
public void setOther2(String other2) {
this.other2 = other2;
}
@Override
public String toString() {
return "Food{" +
"foodId=" + foodId +
", foodName=" + foodName +
", foodPrice=" + foodPrice +
", foodScore=" + foodScore +
", foodDetail=" + foodDetail +
", foodType=" + foodType +
", foodMainImg=" + foodMainImg +
", foodRecommendStatus=" + foodRecommendStatus +
", foodCteateTime=" + foodCteateTime +
", foodUpdateTime=" + foodUpdateTime +
", other1=" + other1 +
", other2=" + other2 +
"}";
}
}
JwtInterceptor.java
package com.example.interceptor;
import com.example.util.JwtUtil;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class JwtInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("登录检查拦截器正在拦截URL>>>"+request.getRequestURI());
String token = request.getHeader("token");
if(token == null || token.equals("")){
System.out.println("登录检查拦截器正在拦截,没有获得到token");
response.sendRedirect(request.getContextPath()+"/static/login.html");
return false;
}else {
System.out.println("登录检查拦截器正在拦截,获得到的token:"+token);
if (JwtUtil.checkToken(token)){
return true;
}else {
System.out.println("被拦截了,无效token");
return false;
}
}
}
}
FoodMapper.java
package com.example.mapper;
import com.example.entity.Food;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface FoodMapper extends BaseMapper<Food> {
}
IFoodService.java
package com.example.service;
import com.example.entity.Food;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
public interface IFoodService extends IService<Food> {
public List<Food> getHotFood();
}
FoodServiceImpl.java
package com.example.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.entity.Food;
import com.example.mapper.FoodMapper;
import com.example.service.IFoodService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Service
public class FoodServiceImpl extends ServiceImpl<FoodMapper, Food> implements IFoodService {
@Autowired
private FoodMapper foodMapper;
@Autowired
private RedisTemplate redisTemplate;
@Override
public List<Food> getHotFood(){
ListOperations<String,Food> operations = redisTemplate.opsForList();
String key = "hotFood";
if (redisTemplate.hasKey(key)){
List<Food> hotFoodList = operations.range(key,0,7);
return hotFoodList;
}else{
QueryWrapper<Food> queryWrapper = new QueryWrapper<>();
queryWrapper.orderByDesc("food_score");
Page<Food> page = new Page<>(1,8);
page = foodMapper.selectPage(page,queryWrapper);
List<Food> hotProductList = page.getRecords();
operations.leftPushAll(key,hotProductList);
redisTemplate.expire(key,30, TimeUnit.SECONDS);
return hotProductList;
}
}
}
JwtUtil.java
package com.example.util;
import com.example.entity.LoginCustomer;
import io.jsonwebtoken.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class JwtUtil {
private static final String jwtToken = "dahkgag7*$";
private static long expireTime = 1000*60*60*24;
public static String createToken(Integer customerId,String customerName){
Map<String,Object> claims = new HashMap<>();
claims.put("customerId",customerId);
claims.put("customerName",customerName);
System.out.println("创建token"+customerId);
System.out.println("创建token"+customerName);
JwtBuilder jwtBuilder = Jwts.builder().signWith(SignatureAlgorithm.HS256,jwtToken)
.setClaims(claims)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis()+expireTime));
String token = jwtBuilder.compact();
return token;
}
public static boolean checkToken(String token){
if(token != null && !token.equals("")){
try {
Jwt parse = Jwts.parser().setSigningKey(jwtToken).parseClaimsJws(token);
return true;
}catch (ExpiredJwtException e){
System.out.println("token已经过期了");
return false;
} catch (Exception e) {
System.out.println("无效的token");
return false;
}
}else
return false;
}
public static LoginCustomer parseToken(String token){
if(token != null && !token.equals("")) {
try {
Jwt parse = Jwts.parser().setSigningKey(jwtToken).parseClaimsJws(token);
Map<String,Object> map = (Map<String, Object>)parse.getBody();
if(map != null){
Integer custId = (Integer)map.get("customerId");
String custName = (String)map.get("customerName");
LoginCustomer loginCustomer = new LoginCustomer(custId,custName);
System.out.println("获得到的登录用户的信息是:" + loginCustomer);
return loginCustomer;
}else{
System.out.println("获得到的登录用户的信息失败");
return null;
}
} catch (Exception e){
e.printStackTrace();
return null;
}
}else
return null;
}
}
ServerResult.java
package com.example.util;
public class ServerResult {
private int code;
private String msg;
private Object data;
public static ServerResult getSuccess(Object data){
return new ServerResult(200,"查询成功",data);
}
public static ServerResult getFail(Object data){
return new ServerResult(201,"查询失败",data);
}
public static ServerResult updateSuccess(Object data){
return new ServerResult(200,"处理成功",data);
}
public static ServerResult updateFail(Object data){
return new ServerResult(201,"处理失败",data);
}
public static ServerResult loginSuccess(Object data){
return new ServerResult(200,"登录成功",data);
}
public static ServerResult loginFail(Object data){
return new ServerResult(201,"登录失败",data);
}
public ServerResult() {
}
public ServerResult(int code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
@Override
public String toString() {
return "ServerResult{" +
"code=" + code +
", msg='" + msg + '\'' +
", data=" + data +
'}';
}
}
ServletInitializer.java
package com.example;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(SpringbootLoginApplication.class);
}
}
SpringbootLoginApplication.java
package com.example;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@MapperScan("com.example.mapper")
@EnableCaching
public class SpringbootLoginApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootLoginApplication.class, args);
}
}
food.sql
DROP TABLE IF EXISTS `food`;
CREATE TABLE `food` (
`food_id` int(0) NOT NULL AUTO_INCREMENT COMMENT '美食id',
`food_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '美食名',
`food_price` decimal(10, 1) NULL DEFAULT NULL COMMENT '美食价格',
`food_score` float NULL DEFAULT NULL COMMENT '美食评分',
`food_detail` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '美食详情',
`food_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '美食类型',
`food_main_img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '美食图片',
`food_recommend_status` int(0) NULL DEFAULT 0 COMMENT '美食推荐状态',
`food_cteate_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间',
`food_update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
`other1` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`other2` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
PRIMARY KEY (`food_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 65 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
INSERT INTO `food` VALUES (1, '奥尔良翅中', 56.5, 8.31, '翅中5个', '烤肉', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (2, '薄切猪梅花', 54.9, 6.64, '一斤', '烤肉', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (3, '金针菇', 39.4, 8.08, '金针菇', '烤肉', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (4, '私房炸小排', 44.3, 4.66, '油炸', '烤肉', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (5, '荞麦冷面', 59.1, 4.3, '荞麦', '烤肉', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (6, '五花肉', 41.6, 7.99, '五花肉', '烤肉', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (7, '雪花牛里脊', 59.9, 8.34, '牛里脊', '烤肉', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (8, '雪花香翁牛排', 87.1, 3.91, '新鲜牛排', '烤肉', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (9, '粉丝金针菇', 50.3, 8.59, '粉丝金针菇', '烤肉', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (10, '黑椒牛肉粒', 68.0, 3.63, '黑椒牛肉粒', '烤肉', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (11, '香辣鸡腿肉', 77.2, 5.53, '香辣鸡腿肉', '烤肉', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (12, '原切烧汁牛五花', 76.1, 4.07, '原切烧汁牛五花', '烤肉', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (13, '牛肋条', 66.7, 6.82, '牛肋条', '烤肉', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (14, '牛肉五花', 61.8, 5.49, '牛肉', '烤肉', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (15, '猪肉五花', 77.4, 7.32, '猪肉', '烤肉', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (16, '鱼豆腐', 84.7, 8.6, '鱼豆腐', '烤肉', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (17, '德州BBQ烤翅', 30.7, 8.75, '三件套', '汉堡', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (18, '黑松露菌菇和牛堡', 55.5, 8.26, '四件套', '汉堡', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (19, '美式卡真烤去骨鸡腿全餐', 85.2, 9.22, '单个', '汉堡', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (20, '招牌芝士和牛汉堡', 52.8, 7.53, '咖啡', '汉堡', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (21, '茴香小油条', 74.6, 7.9, '茴香小油条', '火锅', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (22, '内蒙草原羔羊', 69.9, 3.3, '羊肉', '火锅', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (23, '现炸小酥肉', 67.9, 8, '现炸', '火锅', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (24, '雪花牛肉', 57.6, 8.68, '牛肉', '火锅', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (25, '炸豆皮', 77.5, 3.76, '放学小肉', '火锅', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (26, '干贝咸蛋黄虾滑', 42.0, 5.41, '蛋黄虾滑', '火锅', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (27, '老哥酥肉', 77.5, 9.08, '酥肉', '火锅', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (28, '雪花牛肉', 64.3, 5.42, '毛肚', '火锅', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (29, '风花雪月', 83.2, 3.22, '风花雪月', '烤肉', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (30, '黑牛牡蛎肉', 78.6, 7.09, '黑牛牡蛎肉', '烤肉', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (31, '青海烤饼', 63.7, 8.19, '饼1个', '烤肉', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (32, '黑牛肋条', 61.4, 9.63, '黑牛肋条', '烤肉', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (33, '大片毛肚', 40.2, 9.92, '大片毛肚', '火锅', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (34, '灯影鱼片', 62.6, 6.72, '鱼片', '火锅', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (35, '飞鱼籽虾滑', 66.7, 9.8, '虾滑', '火锅', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (36, '牛舌', 78.9, 3.46, '牛舌', '烤肉', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (37, '迷你汉堡', 53.8, 5.42, '会员专享', '汉堡', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (38, '蘑菇味狠浓牛肉汉堡', 71.8, 6.35, '单人餐', '汉堡', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (39, '四重芝士狠浓牛肉汉堡', 51.6, 3.37, '单人下午茶', '汉堡', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (40, 'M8澳洲和牛', 64.1, 8.5, '澳洲和牛', '火锅', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (41, 'M5牛肉', 81.0, 7.85, '牛肉', '火锅', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (42, '海鲜拼盘', 59.0, 8.94, '海鲜拼盘', '火锅', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (43, '鱼籽鲜虾滑', 40.5, 4.57, '虾滑', '火锅', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (44, '加州汉堡套餐', 43.1, 4.37, '兑换券', '汉堡', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (45, '双层美式汉堡', 88.9, 8.74, '兑换券', '汉堡', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (46, '招牌安格斯牛肉汉堡单人餐', 35.0, 6.97, '兑换券', '汉堡', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (47, '孜然鸡肉条', 82.6, 5.25, '兑换券', '汉堡', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (48, '上等黑虎虾', 56.7, 9.95, '虾', '烤肉', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (49, '上等牛五花', 85.7, 6.99, '牛五花', '烤肉', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (50, '土豆泥', 50.5, 5.52, '土豆泥', '烤肉', '', 1, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (52, '现切冰鲜牛排', 53.4, 4, '现切冰鲜牛排', '烤肉', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (53, '超传统超级棒约翰', 43.0, 5.33, '超传统超级棒约翰', '汉堡', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (54, '榴莲芝士条', 54.3, 7.11, '榴莲芝士条', '汉堡', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (55, '洋葱圈', 55.0, 8.2, '洋葱圈', '汉堡', '', 0, NULL, NULL, NULL, NULL);
INSERT INTO `food` VALUES (56, '意式红烩牛肉焗饭', 40.0, 5.44, '意式红烩牛肉焗饭', '汉堡', '', 0, NULL, NULL, NULL, NULL);
FoodMapper.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">
<mapper namespace="com.example.mapper.FoodMapper">
</mapper>
application.yaml
server:
servlet:
context-path: /app
port: 80
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/dicts?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: 123456
redis:
host: localhost
port: 6379
database: 0
connect-timeout: 1800000
mvc:
view:
prefix: /
suffix: .jsp
hiddenmethod:
filter:
enabled: true
logging:
file:
path: d://logger
level:
com.example: debug
css_04_首页.css
*{
margin: 0;
padding: 0;
}
.header{
width: 85%;
height: 58px;
min-width: 1000px;
margin: 0 auto;
}
.header .logo{
width: 15%;
height: 33px;
float: left;
margin-top: 12px;
}
.header .logo a{
display: inline-block;
width: 100%;
height: 33px;
background: url(../images/header-small-sprites3.png) no-repeat 0 -25px;
background-size: 125px;
}
.header .nav{
width: 35%;
height: 100%;
float: left;
min-width: 450px;
}
.nav .head-nav{
width: 100%;
height: 100%;
list-style: none;
}
.head-nav li{
float: left;
height: 100%;
width: 80px;
}
.head-nav li a{
display: inline-block;
width: 100%;
height: 100%;
color: rgb(78, 78, 78);
text-decoration: none;
font-size: 13px;
text-align: center;
line-height: 58px;
}
.head-nav li a:hover{
background-color: rgba(230, 69, 102, 0.1);
color: rgb(78, 78, 78);
border-bottom: 3px solid rgba(230, 69, 102, 0.1)
}
.head-nav .first-item{
background-color: rgba(230, 69, 102, 0.1);
color: rgb(78, 78, 78);
}
.head-nav .first-item:hover{
background-color: rgba(230, 69, 102, 0.1);
color: rgb(78, 78, 78);
border-bottom:none;
}
.search{
width: 25%;
height: 100%;
float: left;
min-width: 260px;
}
.search form{
width: 100%;
height: 30px;
margin-top: 12px;
}
.search form .search-kw{
width: 180px;
height: 100%;
border: 1px solid rgba(230, 69, 102, 0.1);
border-radius: 4px;
outline: none;
padding-left: 10px;
color: rgb(108, 108, 108);
}
.search .search-btn{
width: 60px;
height: 30px;
background-color: rgba(230, 69, 102, 0.1);
font-size: 12px;
color: rgb(78, 78, 78);
border: none;
cursor: pointer ;
border-radius: 4px;
}
.header .login{
width: 13%;
height: 100%;
float: right;
}
.login a{
display: inline-block;
width: 60px;
height: 30px;
background-color: rgba(230, 69, 102, 0.1);
margin-top: 14px;
border-radius: 4px;
text-decoration: none;
color: rgb(78, 78, 78);
font-size: 12px;
text-align: center;
line-height: 30px;
}
.login a:hover{
font-weight: bold;
}
.banner{
width: 100%;
height: 400px;
}
.banner img{
width: 100%;
height: 100%;
}
.pro-title{
width: 100%;
height: 80px;
text-align: center;
line-height: 80px;
font-size: 28px;
}
.pro-list{
width: 85%;
height: 660px;
margin: 0 auto;
}
.pro-list ul{
width: 100%;
height: 100%;
list-style: none;
}
.pro-list ul li{
width: 230px;
height: 320px;
float: left;
margin-right: 30px;
margin-bottom: 10px;
}
.pro-list ul li img{
width: 160px;
height: 160px;
}
.pro-list ul .pro-name{
width: 190px;
height: 48px;
margin-left: 20px;
font-size: 13px;
color: darkgrey;
text-align: center;
}
.pro-name-a{
text-decoration: none;
}
.pro-list ul .pro-price{
width: 190px;
height: 18px;
margin-left: 20px;
margin-top: 10px;
text-align: center;
color: rgba(230, 69, 101, 0.591);
}
.pro-price i{
vertical-align: middle;
font-size: 12px;
font-weight: 700;
font-family: MicrosoftYahei-regular,Arial,Helvetica,sans-serif;
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>首页</title>
<link href="css/css_04_首页.css" rel="stylesheet"/>
<link rel="shortcut icon" href="images/favicon.ico" />
<script src="js/jquery-3.7.0.min.js"></script>
</head>
<body>
<div class="header">
<div class="logo">
<a href=""> </a>
</div>
<div class="nav">
<ul class="head-nav">
<li><a href="" class="first-item">首页</a></li>
<li><a href="">菜品</a></li>
<li><a href="">店铺</a></li>
<li><a href="">热卖</a></li>
<li><a href="">优惠券</a></li>
</ul>
</div>
<div class="search">
<form>
<input type="text" class="search-kw" >
<input type="submit" class="search-btn" value="搜索"/>
</form>
</div>
<div class="login">
<a href="login.html">登录</a>
<a href="">注册</a>
</div>
</div>
<div class="banner">
<img src="images/bg1.jpg" />
</div>
<h3 class="pro-title"> 热门商品</h3>
<div class="pro-list">
<ul>
<li>
<a href="css_06_商品详情.html">
<img class="pro-img" src="images/pro2.webp" />
</a>
<a href="" class="pro-name-a">
<p class="pro-name">HUAWEI Mate X5 典藏版 16GB+1TB 青山黛</p>
</a>
<div class="pro-price">
<i>¥</i>
<span>6999.00</span>
</div>
</li>
<li>
<a href="css_06_商品详情.html">
<img class="pro-img" src="images/pro3.webp" />
</a>
<a href="" class="pro-name-a">
<p class="pro-name">HUAWEI Mate X5 典藏版 16GB+1TB 青山黛</p>
</a>
<div class="pro-price">
<i>¥</i>
<span>6999.00</span>
</div>
</li>
<li>
<a href="css_06_商品详情.html">
<img class="pro-img" src="images/pro2.webp" />
</a>
<a href="" class="pro-name-a">
<p class="pro-name">HUAWEI Mate X5 典藏版 16GB+1TB 青山黛</p>
</a>
<div class="pro-price">
<i>¥</i>
<span>6999.00</span>
</div>
</li>
<li>
<a href="css_06_商品详情.html">
<img class="pro-img" src="images/pro3.webp" />
</a>
<a href="" class="pro-name-a">
<p class="pro-name">HUAWEI Mate X5 典藏版 16GB+1TB 青山黛</p>
</a>
<div class="pro-price">
<i>¥</i>
<span>6999.00</span>
</div>
</li>
<li>
<a href="css_06_商品详情.html">
<img class="pro-img" src="images/pro2.webp" />
</a>
<a href="" class="pro-name-a">
<p class="pro-name">HUAWEI Mate X5 典藏版 16GB+1TB 青山黛</p>
</a>
<div class="pro-price">
<i>¥</i>
<span>6999.00</span>
</div>
</li>
<li>
<a href="css_06_商品详情.html">
<img class="pro-img" src="images/pro3.webp" />
</a>
<a href="" class="pro-name-a">
<p class="pro-name">HUAWEI Mate X5 典藏版 16GB+1TB 青山黛</p>
</a>
<div class="pro-price">
<i>¥</i>
<span>6999.00</span>
</div>
</li>
<li>
<a href="css_06_商品详情.html">
<img class="pro-img" src="images/pro2.webp" />
</a>
<a href="" class="pro-name-a">
<p class="pro-name">HUAWEI Mate X5 典藏版 16GB+1TB 青山黛</p>
</a>
<div class="pro-price">
<i>¥</i>
<span>6999.00</span>
</div>
</li>
<li>
<a href="css_06_商品详情.html">
<img class="pro-img" src="images/pro3.webp" />
</a>
<a href="" class="pro-name-a">
<p class="pro-name">HUAWEI Mate X5 典藏版 16GB+1TB 青山黛</p>
</a>
<div class="pro-price">
<i>¥</i>
<span>6999.00</span>
</div>
</li>
</ul>
</div>
<script>
function loadIndexInfo() {
let token = localStorage.getItem("token");
console.log(token);
let url = "http://localhost:80/app/food/hot";
document.addEventListener('DOMContentLoaded', function() {
$.ajax({
type: "get",
url: url,
success: function(result) {
console.log(result);
if (result.code == 200) {
var imgElements = document.querySelectorAll('.pro-img');
console.log(imgElements.length);
var minLength = Math.min(result.data.length, imgElements.length);
for (var i = 0; i < minLength && i < 8; i++) {
imgElements[i].src = result.data[i].foodMainImg;
console.log('Updated image element #' + (i + 1) + ' with URL: ' + result.data[i].foodMainImg);
}
if (minLength < 8 || result.data.length < 8) {
console.warn('Not enough data or image elements to assign to 8 images.');
}
} else {
console.error('Request failed with code:', result.code);
}
}
});
});
}
loadIndexInfo();
</script>
</body>
</html>
pom.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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.6</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>springboot_login</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>springboot_login</name>
<description>springboot_login</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>