Jesse A. Green / notebook

Mall — User Guide

Generated May 2026 from macrozheng/mall at d9501e9

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

1. Quick Start

Mall is a full-featured e-commerce platform built on Spring Boot, providing both a back-office admin system and a customer-facing shopping portal as REST APIs. It covers product management, order processing, promotions, member management, and full-text product search.

Key features:

  • Complete product lifecycle management (categories, brands, attributes, SKUs)
  • Shopping cart with promotion calculation (ladders, full-reduction, coupons)
  • Order placement with automatic timeout cancellation via RabbitMQ
  • Alipay payment integration (desktop, mobile, async notification)
  • Elasticsearch-powered product search with aggregation
  • JWT-based stateless authentication with dynamic URL-level authorization
  • MinIO and Aliyun OSS file storage
  • Swagger UI auto-generated API documentation

Prerequisites:

  • JDK 8+
  • Maven 3.x
  • MySQL 5.7+, Redis 7+, MongoDB 4+, RabbitMQ 3.9+, Elasticsearch 7.17.x

Quickest path to running:

# Start infrastructure services
docker compose -f document/docker/docker-compose-env.yml up -d

# Import the database schema
mysql -u root -proot < document/sql/mall.sql

# Build all modules
mvn clean package -DskipTests

# Run the admin backend
java -jar mall-admin/target/mall-admin-1.0-SNAPSHOT.jar --spring.profiles.active=dev

The admin API is now accessible at http://localhost:8080. Swagger UI is at http://localhost:8080/swagger-ui/.

Tip

Use the included Postman collections (document/postman/) for quick API exploration. Import mall-admin.postman_collection.json and mall-portal.postman_collection.json into Postman.

What to try next:

  • Log in via POST /admin/login with {"username": "admin", "password": "123456"}
  • Browse products via GET /product/list
  • Start the portal module for the customer-facing API on port 8085

2. Installation

System Requirements

Component Minimum Version Purpose
JDK 8 Runtime
Maven 3.x Build
MySQL 5.7 Primary database
Redis 7 Caching, session
MongoDB 4 Member browsing history, collections
RabbitMQ 3.9 Order timeout cancellation
Elasticsearch 7.17.x Product search
MinIO Latest Object storage (product images)

Infrastructure Setup with Docker Compose

The recommended approach uses the provided Docker Compose file to run all infrastructure:

docker compose -f document/docker/docker-compose-env.yml up -d

This starts:

Service Port Purpose
MySQL 3306 Database (root password: root)
Redis 6379 Cache with AOF persistence
Nginx 80 Static assets / frontend proxy
RabbitMQ 5672 / 15672 Message queue / management UI
Elasticsearch 9200 / 9300 Search engine
Logstash 4560-4563 Log collection
Kibana 5601 Log visualization
MongoDB 27017 Document store
MinIO 9090 / 9001 Object storage (API / console)

Important

After starting MySQL, import the database schema before running any application module:

mysql -u root -proot < document/sql/mall.sql

The SQL file creates the mall database with all required tables (~70 tables).

Building the Project

mvn clean package -DskipTests

This produces executable JARs in each module's target/ directory.

Running Application Modules

Start modules in this order (admin is independent; portal requires RabbitMQ and MongoDB; search requires Elasticsearch):

# Admin back-office API (port 8080)
java -jar mall-admin/target/mall-admin-1.0-SNAPSHOT.jar --spring.profiles.active=dev

# Portal customer API (port 8085)
java -jar mall-portal/target/mall-portal-1.0-SNAPSHOT.jar --spring.profiles.active=dev

# Search service (port 8081)
java -jar mall-search/target/mall-search-1.0-SNAPSHOT.jar --spring.profiles.active=dev

Docker Deployment (Production)

Build Docker images via Maven:

mvn clean package -DskipTests -Pdocker

Or use the provided deployment scripts:

# Deploy mall-admin container
bash document/sh/mall-admin.sh

# Deploy mall-portal container
bash document/sh/mall-portal.sh

# Deploy mall-search container
bash document/sh/mall-search.sh

Warning

The deployment scripts use --link for container networking (legacy Docker feature). They also hard-delete dangling images. Ensure your container names match: mysql, redis, mongo, rabbitmq, elasticsearch.

Post-Installation Verification

# Check admin API health
curl http://localhost:8080/actuator/health
{"status":"UP"}

Access Swagger UI:

  • Admin: http://localhost:8080/swagger-ui/
  • Portal: http://localhost:8085/swagger-ui/
  • Search: http://localhost:8081/swagger-ui/

3. Configuration

Mall uses Spring Boot profiles for environment-specific configuration. Each module has:

  • application.yml — shared settings
  • application-dev.yml — development overrides
  • application-prod.yml — production overrides

Activate a profile at startup:

java -jar mall-admin.jar --spring.profiles.active=prod

Key Configuration Areas

Setting Location Purpose
Database spring.datasource.* MySQL connection (Druid pool)
Redis spring.redis.* Cache host/port
MongoDB spring.data.mongodb.* Member data store
RabbitMQ spring.rabbitmq.* Message broker
Elasticsearch spring.elasticsearch.* Search cluster
JWT jwt.secret, jwt.expiration, jwt.tokenHead Auth token config
Security whitelist secure.ignored.urls Paths that skip authentication
Aliyun OSS aliyun.oss.* Object storage credentials
MinIO minio.* MinIO endpoint and credentials
Alipay alipay.* Payment gateway config
Swagger spring.mvc.pathmatch.matching-strategy Must be ant_path_matcher

Tip

The secure.ignored.urls list controls which endpoints bypass JWT auth. In development, Swagger paths (/swagger-ui/**, /v2/api-docs, /swagger-resources/**) are whitelisted here.

For the full configuration reference (every key, every module), see the Admin Guide.


4. Core Usage

Mall exposes three REST API services. All responses use a standard envelope:

{
  "code": 200,
  "message": "操作成功",
  "data": { }
}
Code Meaning
200 Success
401 Not logged in / token expired
403 Insufficient permissions
404 Validation failed
500 Operation failed

Authentication

All protected endpoints require a JWT token in the Authorization header:

Authorization: Bearer <token>

Admin login:

curl -X POST http://localhost:8080/admin/login \
  -H "Content-Type: application/json" \
  -d '{"username": "admin", "password": "123456"}'
{
  "code": 200,
  "message": "操作成功",
  "data": {
    "token": "eyJhbGciOiJIUzUxMiJ9...",
    "tokenHead": "Bearer "
  }
}

Member login (portal):

curl -X POST http://localhost:8085/sso/login \
  -d "username=test&password=123"

Token refresh:

curl http://localhost:8080/admin/token/refresh \
  -H "Authorization: Bearer <current-token>"

Note

Tokens have a configurable expiration (default varies by environment). The refresh endpoint re-issues a token only if the current one was issued more than 30 minutes ago — calling it within that window returns the same token.

Paginated Responses

List endpoints return paginated data:

{
  "code": 200,
  "data": {
    "pageNum": 1,
    "pageSize": 5,
    "totalPage": 10,
    "total": 48,
    "list": [...]
  }
}

Use pageNum and pageSize query parameters to control pagination.


4.1 Product Management (Admin)

Endpoint Method Description
/product/list GET List products (paginated, filterable)
/product/create POST Create a new product
/product/update/{id} POST Update product details
/product/update/deleteStatus POST Batch soft-delete products
/brand/listAll GET List all brands
/brand/list GET Paginated brand list
/brand/create POST Create a brand
/productCategory/list/withChildren GET Category tree
/productCategory/list/{parentId} GET Subcategories
/productAttribute/list/{cid} GET Attributes for a category
/skuStock/update/{pid} POST Update SKU stock

4.2 Order Management (Admin)

Endpoint Method Description
/order/list GET List orders with filters
/order/{id} GET Order detail
/order/update/delivery POST Batch ship orders
/order/update/close POST Close orders
/order/update/moneyInfo POST Modify order amounts
/order/update/receiverInfo POST Update shipping address
/returnApply/list GET Return applications
/returnApply/update/status POST Process return
/orderSetting/update/{id} POST Update order settings

4.3 Promotions (Admin)

Endpoint Method Description
/coupon/add POST Create coupon
/coupon/update/{id} POST Update coupon
/coupon/delete/{id} POST Delete coupon
/coupon/list GET List coupons
/flash/create POST Create flash sale event
/flash/update/{id} POST Update flash sale
/flashSession/list GET List flash sale sessions
/flashProductRelation/create POST Add product to flash sale
/home/advertise/list GET Homepage ads
/home/brand/list GET Homepage brand recommendations
/home/newProduct/list GET Homepage new arrivals
/home/recommendProduct/list GET Homepage recommended products

4.4 User & Permission Management (Admin)

Endpoint Method Description
/admin/list GET List admin users
/admin/register POST Register new admin
/admin/update/{id} POST Update admin user
/admin/updatePassword POST Change password
/role/list GET List roles
/role/create POST Create role
/role/allocResource POST Assign resources to role
/role/allocMenu POST Assign menus to role
/resource/list GET List resources
/resource/create POST Create resource
/menu/treeList GET Menu tree

4.5 Shopping (Portal)

Endpoint Method Description
/cart/add POST Add item to cart
/cart/list GET Get cart items
/cart/list/promotion GET Cart with promotion calculations
/cart/update/quantity GET Update item quantity
/cart/update/attr POST Change item specifications
/cart/delete POST Remove items from cart
/cart/clear POST Empty cart
/cart/getProduct/{productId} GET Get product specs for re-selection

4.6 Orders (Portal)

Endpoint Method Description
/order/confirmOrder POST Generate order confirmation
/order/generateOrder POST Place order
/order/paySuccess POST Payment success callback
/order/cancelOrder POST Cancel a single order
/order/cancelTimeOutOrder POST Cancel all timed-out orders

Warning

Orders that are not paid within the configured timeout are automatically cancelled via RabbitMQ dead-letter queue. The timeout is set in the order settings (managed via admin API).

4.7 Member Features (Portal)

Endpoint Method Description
/sso/register POST Member registration
/sso/login POST Member login
/member/address/list GET Shipping addresses
/member/address/add POST Add address
/member/address/update/{id} POST Update address
/member/address/delete/{id} POST Delete address
/member/coupon/list GET Member's coupons
/member/coupon/add/{couponId} POST Claim a coupon
/member/coupon/list/cart/{type} GET Coupons applicable to cart
/member/attention/add POST Follow a brand
/member/attention/list GET Brand follows
/member/productCollection/add POST Collect a product
/member/productCollection/list GET Product collections
/member/readHistory/list GET Browse history

4.8 Homepage Content (Portal)

Endpoint Method Description
/home/content GET Homepage aggregated content
/home/recommendProductList GET Recommended products
/home/productCateList/{parentId} GET Product categories
/home/subjectList GET Subject/topic list
/home/hotProductList GET Hot products
/home/newProductList GET New products

4.9 Payment (Portal)

Endpoint Method Description
/alipay/pay GET Desktop Alipay payment page
/alipay/webPay GET Mobile Alipay payment page
/alipay/notify POST Alipay async notification callback
/alipay/query GET Query payment status
Endpoint Method Description
/esProduct/importAll POST Import all products to ES
/esProduct/search GET Search products (keyword, filters)
/esProduct/create/{id} POST Index a single product
/esProduct/delete/{id} GET Remove product from index
/esProduct/delete/batch POST Batch remove from index

Tip

After initial setup, run POST /esProduct/importAll to populate the Elasticsearch index with product data from MySQL.


5. Common Tasks

Register an Admin and Assign Permissions

  1. Log in as the default admin (admin/123456)
  2. POST /admin/register with name, username, password, email
  3. GET /role/list to find the target role ID
  4. POST /admin/role/update?adminId={id}&roleIds={roleId} to assign roles

Create a Product with SKU Variants

  1. Ensure product categories exist (GET /productCategory/list/withChildren)
  2. Ensure a brand exists (GET /brand/listAll)
  3. POST /product/create with full product JSON including skuStockList array (each entry has price, stock, sp1/sp2/sp3 for specification values, skuCode)

Process a Customer Order

  1. Customer adds items to cart (POST /cart/add)
  2. Customer confirms order (POST /order/confirmOrder) — returns available addresses, coupons, cart totals
  3. Customer places order (POST /order/generateOrder) with memberReceiveAddressId, couponId, payType
  4. Customer pays (Alipay redirects back; async /alipay/notify updates order status)
  5. Admin ships order (POST /order/update/delivery) with tracking info

Set Up a Flash Sale Promotion

  1. POST /flash/create — create flash promotion event (name, start/end dates)
  2. GET /flashSession/list — list time sessions
  3. POST /flashProductRelation/create — bind products to session with flash prices

Import Products to Elasticsearch

curl -X POST http://localhost:8081/esProduct/importAll \
  -H "Authorization: Bearer <token>"
{"code": 200, "message": "操作成功", "data": 48}

This syncs all products from MySQL to Elasticsearch for full-text search.

Handle a Return Application

  1. Customer submits return request via portal API
  2. Admin lists returns: GET /returnApply/list
  3. Admin reviews and updates status: POST /returnApply/update/status with approval/rejection details

6. Troubleshooting

Error: Swagger UI returns 404

Cause: Spring Boot 2.6+ defaults to PathPatternParser which conflicts with Springfox 3.0.

Solution: Ensure this is set in application.yml:

spring:
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher

Prevention: This is already configured in the project. If upgrading Spring Boot, verify this setting remains.

Error: 401 Unauthorized on all endpoints

Cause: JWT token missing, expired, or malformed.

Solution:

  1. Obtain a fresh token via /admin/login or /sso/login
  2. Include it in requests: Authorization: Bearer <token>
  3. If the token expired, use /admin/token/refresh (within token lifetime)

Prevention: Implement token refresh logic in your client before expiration.

Error: Cannot connect to MySQL on startup

Cause: MySQL container not running or connection credentials wrong.

Solution:

  1. Verify MySQL is running: docker ps | grep mysql
  2. Check application-dev.yml datasource URL, username, and password match your setup
  3. Ensure the mall database exists: mysql -u root -proot -e "SHOW DATABASES;"

Error: Orders not being auto-cancelled

Cause: RabbitMQ not running or queue configuration issue.

Solution:

  1. Confirm RabbitMQ is running: docker ps | grep rabbitmq
  2. Check the management UI at http://localhost:15672 (guest/guest) — verify mall.order.cancel and mall.order.cancel.ttl queues exist
  3. Verify the portal module started successfully (it registers the queues on boot)

Prevention: Always start RabbitMQ before mall-portal.

Note

The order timeout cancellation works via a dead-letter queue. Orders are sent to a TTL queue; when the message expires, RabbitMQ routes it to the cancel queue where CancelOrderReceiver processes the cancellation. (Community issue #499)

Error: Elasticsearch search returns empty results

Cause: Product index not populated.

Solution:

curl -X POST http://localhost:8081/esProduct/importAll

Prevention: Run the import after database changes or on first setup.

Error: MinIO upload fails with access denied

Cause: MinIO credentials or bucket policy not configured.

Solution:

  1. Access MinIO console at http://localhost:9001 (minioadmin/minioadmin)
  2. Create the required bucket
  3. Verify minio.* config in application-dev.yml matches your MinIO setup

Error: NumberFormatException on Swagger page load

Cause: Known Springfox 3.0 issue with certain model annotations.

Solution: The project includes swagger-models:1.6.0 and swagger-annotations:1.6.0 which fix this. If you see the error after dependency updates, re-pin these versions.

Warning

If running with JDK 11+, the javax.xml.bind:jaxb-api dependency is required (already included in the parent POM). Removing it causes ClassNotFoundException on JWT operations.

Error: Flash sale time returns incorrect values

Cause: Timezone mismatch between application and database. (Community issue #532)

Solution: Ensure both application (TZ=Asia/Shanghai) and MySQL (character-set-server=utf8mb4) are configured consistently. The Docker Compose files set this via environment variables.

Error: Coupon discount calculation appears wrong for edge cases

Cause: Floating-point precision issues in promotion amount apportionment across order items. (Community issue #356)

Solution: This is a known limitation of the current algorithm — fractional cent differences may occur when splitting coupon amounts across multiple items.


7. FAQ

Q: Is mall a monolithic application or microservices?

This repository is the monolithic version. Each module (mall-admin, mall-portal, mall-search) runs as a separate Spring Boot JAR but shares the same database. The author maintains a separate mall-swarm repository for the microservices (Spring Cloud) version.

Q: What is the default admin account?

Username admin, password 123456. This is seeded in the mall.sql database schema.

Q: Can I use this without Docker?

Yes. Install MySQL, Redis, MongoDB, RabbitMQ, and Elasticsearch natively, then configure connection details in the application-dev.yml files for each module.

Q: How do I add new API endpoints?

Create a controller in the appropriate module's controller package with @Controller, @Api, and @RequestMapping annotations. The endpoint will automatically appear in Swagger UI.

Q: Is there English language support?

The codebase and default data are in Chinese. Community issue #35 requests English translation but it has not been implemented. API responses use Chinese messages by default (e.g., "操作成功" for success).

Q: How do I customize the JWT secret and expiration?

Set jwt.secret and jwt.expiration (in seconds) in the module's application.yml. See the Admin Guide for security recommendations.

Caution

The default JWT secret in the codebase is a weak placeholder. In production, always override jwt.secret with a strong, unique value. (See security issue #948)

Q: How does the dynamic authorization system work?

Admin module registers all URL resources in the ums_resource table. Roles are assigned specific resources. At runtime, DynamicSecurityFilter intercepts requests and checks whether the current user's role(s) grant access to the requested URL pattern.

Q: Can I run just the admin module without portal/search?

Yes. mall-admin only requires MySQL and Redis. MongoDB, RabbitMQ, and Elasticsearch are only needed by mall-portal and mall-search.

Q: What is the mall-demo module for?

It's a demonstration/learning module showing Spring Security integration patterns (different from the main mall-security module approach). It's not needed for production.

Q: How do I integrate with a different payment gateway?

The Alipay integration lives entirely in mall-portal's AlipayController and AlipayService. Implement a new service following the same pattern and add a controller with your gateway's SDK.