目次
zmall-cart ショッピング カート モジュールの作成と構成
1. Nginx の動的および静的分離
ステップ 1: SwitchHosts: images.zmall.com を介して第 2 レベルのドメイン名を追加します。
ステップ 2: このプロジェクトの Yibuy.com のすべての静的リソース js/css/images を nginx の html ディレクトリにコピーします。
ステップ 3: nginx コア構成ファイル nginx.conf にセカンドレベル ドメイン名 images.zmall.com アクセス マッピングを追加して、nginx の動的および静的分離を実現します。
注: 変更が成功したら、nginx サービスを再起動して構成を有効にします。! !
server{
listen 80;
server_name images.zmall.com;
location / {
root html;
index index.html;
}
}
プロジェクトのスタイルをnginxのhtmlフォルダーにコピーします
ブラウザーでの静的リソース サーバー構成の表示の成功を検出する
http://images.zmall.com/css/style.css
ステップ 4: zmall-product コモディティ サービスおよび zmall-gateway ゲートウェイ サービスの下にある静的静的リソースを削除し、代わりに nginx で構成された静的リソースを使用します。
ステップ 5: zmall-product 商品サービスを変更する
テンプレート/共通/head.html
<#assign ctx>
<#--域名,动态请求时需加入该前缀-->
http://product.zmall.com
</#assign>
<#--采用H5方式的base标签,在整个页面的url地址前加入,用于访问nginx中的静态资源-->
<base href="http://images.zmall.com/"/>
ステップ 6: zmall-product、zmall-gateway、nginx をそれぞれ再起動し、リクエスト アドレス zmall.com/product-serv/index.html を入力して、以下に示すように製品サービス ホームページにアクセスします。
第二に、サービスコール
zmall-cart ショッピング カート モジュールの作成と構成
ステップ 1: Spring initializr に基づいて zmall-cart ショッピング カート モジュールを作成する
ステップ 2: zmall-order order モジュールをメイン モジュールに構成する
<modules>
...
<module>zmall-cart</module>
...
</modules>
ステップ 3: pom.xml を変更する
<parent>
<groupId>com.zking.zmall</groupId>
<artifactId>zmall</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>zmall-cart</artifactId>
<dependencies>
<dependency>
<groupId>com.zking.zmall</groupId>
<artifactId>zmall-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
ステップ 4: application.yml を構成する (ポート: 8030)
server:
port: 8030
spring:
application:
name: zmall-cart
datasource:
#type连接池类型 DBCP,C3P0,Hikari,Druid,默认为Hikari
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/zmall?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username: root
password: 1234
freemarker:
suffix: .html
template-loader-path: classpath:/templates/
cloud:
nacos:
config:
server-addr: localhost:8848
#mybatis-plus配置
mybatis-plus:
#所对应的 XML 文件位置
mapper-locations: classpath*:/mapper/*Mapper.xml
#别名包扫描路径
type-aliases-package: com.zking.zmall.model
configuration:
#驼峰命名规则
map-underscore-to-camel-case: true
#日志配置
logging:
level:
com.zking.zmall.mapper: debug
ステップ 5: スタートアップ クラスに参加する@EnableDiscoveryClient
ステップ 6: ショッピング カート ページと common/head.html をテンプレート ディレクトリにインポートし、head.html の ctx ローカル変数を変更します。
<#assign ctx>
<#--一级域名,动态请求时需加入该前缀-->
http://cart.zmall.com
</#assign>
<#--采用H5方式的base标签,在整个页面的url地址前加入,用于访问nginx中的静态资源-->
<base href="http://images.zmall.com/"/>
ステップ 7: zmall-gateway ゲートウェイ サービスでショッピング カートのルーティングおよび転送ルールを構成する (ゲートウェイ ゲートウェイ サービスを再起動する)
spring:
application:
name: zmall-gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
routes:
...
- id: cart_route
uri: lb://zmall-cart # lb指的是从nacos中按照名称获取微服务,并遵循负载均衡策略
predicates:
- Path=/cart-serv/**
filters:
- StripPrefix=1
#此过滤器设置路由过滤器检查的请求属性,以确定是否应发送原始主机头,而不是由 HTTP 客户端确定的主机头
- PreserveHostHeader
注: ここでは、リダイレクトを処理するときに元のホスト ヘッダーで要求を送信するために使用されるフィルター PreserveHostHeader を構成する必要があります。
ステップ 8: CartController を作成し、リクエスト メソッドを定義する
@Controller
public class CartController {
@RequestMapping("/cart.html")
public String toCart(){
return "buyCar";
}
@RequestMapping("/addCart")
public String addCart(Integer pid,Integer num){
return "redirect:/cart.html";
}
}
注: ここではリダイレクト リダイレクト メソッドを使用してページにジャンプします.Spring Cloud ゲートウェイのルーティングおよび転送プロセス中に、ドメイン名のジャンプは http 要求メソッドに変更されるため、ゲートウェイ ゲートウェイ サービスで関連する構成を実行する必要があります。 . 詳細については、ステップ 8 のゲートウェイ ゲートウェイ ルーティング構成を参照してください。
ステップ 9: zmall-product モジュールでショッピング カートに追加するリクエスト メソッドを変更し、ショッピング カートに直接移動する
<td><a href="http://cart.zmall.com/addCart?pid=${(product.id)!}&num=3" class="b_sure">去购物车结算</a><a href="#" class="b_buy">继续购物</a></td>
zmall-order order モジュールの作成と構成
ステップ 1: Spring initializr に基づいて zmall-order order モジュールを作成する
ステップ 2: zmall-order order モジュールをメイン モジュールに構成する
<modules>
...
<module>zmall-order</module>
...
</modules>
ステップ 3: pom.xml を変更する
<parent>
<groupId>com.zking.zmall</groupId>
<artifactId>zmall</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>zmall-order</artifactId>
<dependencies>
<dependency>
<groupId>com.zking.zmall</groupId>
<artifactId>zmall-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
ステップ 4: application.yml を構成する (ポート: 8040)
server:
port: 8040
spring:
application:
name: zmall-order
datasource:
#type连接池类型 DBCP,C3P0,Hikari,Druid,默认为Hikari
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/zmall?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username: root
密码: 1234
freemarker:
suffix: .html
template-loader-path: classpath:/templates/
cloud:
nacos:
config:
server-addr: localhost:8848
#mybatis-plus配置
mybatis-plus:
#所对应的 XML 文件位置
mapper-locations: classpath*:/mapper/*Mapper.xml
#别名包扫描路径
type-aliases-package: com.zking.zmall.model
configuration:
#驼峰命名规则
map-underscore-to-camel-case: true
#日志配置
logging:
level:
com.zking.zmall.mapper: debug
ステップ 5: スタートアップ クラスに参加し@EnableDiscoveryClient
、@MapperScan({"com.zking.zmall.mapper"})
ステップ 6: パブリック モジュール zmall-common から直接コピーできる注文インターフェイスを定義します。
ステップ 7: OrderController を作成し、リクエスト インターフェイスを定義する
@Controller
public class OrderController {
@Autowired
private IOrderService orderService;
@RequestMapping("/orderUserList")
@ResponseBody
public List<Order> orderUserList(){
return orderService.list(new QueryWrapper<Order>()
.eq("userId",18));
}
}
ステップ 8: zmall-gateway ゲートウェイ サービスでショッピング カートのルーティングおよび転送ルールを構成する (ゲートウェイ ゲートウェイ サービスを再起動する)
spring:
application:
name: zmall-gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
routes:
...
- id: order_route
uri: lb://zmall-order # lb指的是从nacos中按照名称获取微服务,并遵循负载均衡策略
predicates:
- Path=/order-serv/**
filters:
- StripPrefix=1
- PreserveHostHeader
サービスコール
zmall-user で openfeign を介して注文サービス インターフェイスにアクセスします。
openfeign インターフェイスを定義する
@FeignClient("zmall-order")
public interface IOrderFeignService {
@RequestMapping("/orderUserList")
List<Order> orderUserList();
}
-
クラス設定を開始し
@EnableDiscoveryClient
、@EnableFeignClients
-
インターフェイスを呼び出してインターフェイスをテストする
@Controller
public class UserController {
@Autowired
private IOrderFeignService orderFeignService;
@RequestMapping("/login.html")
public String toLogin(){
return "login";
}
@RequestMapping("/order.html")
@ResponseBody
public List<Order> orderUserList(){
return orderFeignService.orderUserList();
}
}
リンクのテスト
http://product.zmall.com/index.html
http://product.zmall.com/product.html?pid=733
http://cart.zmall.com/cart.html
インターフェースは、商品マイクロサービスからショッピング カート マイクロサービスに直接ジャンプできます。
ユーザー マイクロサービス インターフェースを呼び出して、注文マイクロサービスのデータにアクセスします。
四、春のセッション実戦
スプリングセッションとは
SpringBoot の Spring-Session 統合の自動構成は、すぐに使用できる、非常に簡潔で便利なものと言えます。この記事では、SpringBoot の Spring-Session の統合について紹介します. ここでは、RedisSession に基づく実際の戦闘のみを紹介します.
Spring Session は Spring ファミリーのサブプロジェクトで、ユーザー セッション情報を管理するための API と実装を提供します。これは、サーブレット コンテナーによって実装された httpSession を spring-session に置き換え、セッション管理の問題の解決に焦点を当てています. デフォルトのセッション情報は Redis に保存され、簡単、迅速かつシームレスにアプリケーションに統合できます。
スプリングセッション公式サイトアドレス:スプリングセッション
春学期の特徴:
-
ユーザー セッション管理の API と実装を提供する
-
Tomcat のセッションなど、Web コンテナーのセッションをニュートラルな方法で置き換える HttpSession を提供します。
-
クラスター下でのセッション共有の問題を解決するために、特定の Web コンテナーにバインドすることなく、クラスター セッション処理をサポートします。
Spring Session を使用する理由
SpringCloud マイクロサービスは、完全なモノリシック アプリケーションを独立したサブサービスに分解し、各独立したマイクロサービス サブモジュールは異なるサーバーにデプロイされ、サービスは互いに独立して分離されます.この時点で、サービス間のセッション セッション共有を実装するために分散セッションの管理と共有の問題を解決するには、spring-session フレームワークを使用する必要があります。
春のセッションを構成する
パブリック モジュール zmall-common に spring-session の pom 構成を導入します. spring-boot には spring-session のスターター モジュールが含まれているため、pom は以下に依存します: 注: パブリック モジュールは、すべてのマイクロサービス サブモジュールの依存関係としてサポートされます.モジュールでredis サポートを構成すると、他のマイクロサービスを開始するときにエラーが発生します。
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--spring session-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<!--commons-pool2-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
製品サービス zmall-product とユーザー サービス zmall-user でそれぞれ application.yml を構成します。
spring:
session:
redis:
flush-mode: on_save
namespace: session.zmall
cleanup-cron: 0 * * * * *
store-type: redis
timeout: 1800
redis:
host: localhost
port: 6379
password: 123456
jedis:
pool:
max-active: 100
max-wait: 10
max-idle: 10
min-idle: 10
database: 0
zmall-user および zmall-product サービスを再起動し、最初にhttp://zmall.com/user-serv/login.htmlにアクセスしてから、http://zmall.com/product-serv/index.htmlにアクセスしてください。 zmall-product モジュール コンソールに移動して、セッションの取得を確認します。
注: ゲートウェイ マイクロサービスを使用して内部的にアクセスできますが、異なる第 2 レベル ドメイン名間でアクセスすることはできません。
五、セカンドレベルドメイン名問題
テストでは、ユーザー情報をユーザー モジュールに保存し、それを製品モジュールで読み取りますが、第 2 レベル ドメイン名を使用したアクセスと読み取りは失敗します。
第 2 レベル ドメイン名の無効なアクセス セッションの問題を解決するには、このクラスをユーザー サービスと商品サービスでそれぞれ構成してください。
@Configuration
public class SessionConfig {
@Bean
public CookieSerializer cookieSerializer(){
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
cookieSerializer.setDomainName("zmall.com");
cookieSerializer.setCookieName("ZMALLSESSION");
return cookieSerializer;
}
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer(){
return new GenericJackson2JsonRedisSerializer();
}
}
リンクのテスト
#1. 最初に
http://user.zmall.com/login.htmlにアクセスします
#2. 次に
http://product.zmall.com/index.htmlにアクセスします
ユーザーログイン
ステップ 1: zmall-common パブリック モジュールでグローバルな例外処理クラスと応答カプセル化クラスを作成する
ステップ 2: zmall-user モジュールで IUserService と UserServiceImpl を定義する
IUserService
public interface IUserService extends IService<User> {
JsonResponseBody<?> userLogin(UserVo user, HttpServletRequest req, HttpServletResponse resp);
}
UserServiceImpl
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
@Override
public JsonResponseBody<?> userLogin(UserVo user,
HttpServletRequest req,
HttpServletResponse resp) {
//1.判断用户账号和密码是否为空
if(StringUtils.isEmpty(user.getLoginName())||
StringUtils.isEmpty(user.getPassword()))
return new JsonResponseBody<>(JsonResponseStatus.USERNAME_OR_PWD_EMPTY);
//2.根据用户名查询数据对应的用户信息
User us = this.getOne(new QueryWrapper<User>()
.eq("loginName", user.getLoginName()));
//3.判断us用户对象是否为空
if(null==us)
return new JsonResponseBody<>(JsonResponseStatus.USERNAME_ERROR);
try {
//MD5加密转换处理
String pwd=MD5Utils.md5Hex(user.getPassword().getBytes());
//4.判断输入密码与数据库表存储密码是否一致
if(!us.getPassword().equals(pwd)){
return new JsonResponseBody<>(JsonResponseStatus.PASSWORD_ERROR);
}
} catch (Exception e) {
e.printStackTrace();
return new JsonResponseBody<>(JsonResponseStatus.ERROR);
}
//5.通过UUID生成token令牌并保存到cookie中
String token= UUID.randomUUID().toString().replace("-","");
//将随机生成的Token令牌保存到Cookie中,并设置1800秒超时时间
CookieUtils.setCookie(req,resp,"token",token,7200);
//6.将token令牌与spring session进行绑定并存入redis中
HttpSession session = req.getSession();
session.setAttribute(token,us);
return new JsonResponseBody<>(token);
}
}
ステップ 3: UserVo クラスを作成する
@Data
public class UserVo {
private String loginName;
private String password;
}
ステップ 4: UserController でユーザーのログイン方法を定義する
/**
* 用户登陆功能实现
* @return
*/
@RequestMapping("/userLogin")
@ResponseBody
public JsonResponseBody<?> userLogin(UserVo user,
HttpServletRequest req,
HttpServletResponse resp){
return userService.userLogin(user,req,resp);
}
ステップ 5: フロントエンドの login.html ページで login js メソッドを定義する
<script>
$(function(){
$('.log_btn').click(function(){
let loginName=$('.l_user').val();
let password=$('.l_pwd').val();
if(''===loginName){
alert('请输入用户名!');
return false;
}
if(''===password){
alert('请输入密码!');
return false;
}
console.log({
loginName:loginName,
password:password
});
$.post('http://zmall.com/user-serv/userLogin',{
loginName:loginName,
password:password
},function(rs){
console.log(rs);
if(rs.code===200){
location.href='http://zmall.com/product-serv/index.html';
}else{
alert(rs.msg);
}
},'json');
});
});
</script>
ログインに成功したら、製品のホームページにジャンプします
http://zmall.com/user-serv/login.html
第 2 レベルのドメイン名をテストに使用する場合は、クロスドメインの問題を解決する必要があります。
url: jdbc:mysql://localhost:3306/zmall?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC