文件结构
- src: 这是源文件夹,其中包含主应用程序源文件和测试源文件。
- webpack: 这个文件夹包含用于开发、生产和测试的所有webpack客户端构建配置。
- gradle: 这个文件夹有gradle包装器和额外的gradle构建脚本,这些脚本将由主要的gradle构建文件使用(如果选择Maven, JHipster也提供了类似的包装器)。
- build.gradle: 这是gradle构建文件,它指定了应用程序的构建生命周期。它还指定了服务器端依赖项。构建使用gradle中定义的
gradle.properties
。还可以找到一个名为gradlew (gradlew.bat,用于Windows)的可执行文件,它允许您使用Gradle而无需安装它。 - .yo-rc.json: 这是JHipster的配置文件。这个文件存储了我们在创建应用程序时选择的选项,并用于应用程序的更新和升级。
- package.json: 这是NPM配置文件,它指定了所有客户端依赖项、客户端构建依赖项和任务。
- tsconfig.json: 这是Typescript的配置。还有tsconfig-aot.json,用于Angular AOT (Ahead-of-Time) compilation。
- tslint.json: 这是Typescript的lint配置。
src
src文件夹内结构
main
- docker: 保存应用程序的Dockerfile,并保存所选选项的docker配置。
- java: 保存应用程序的主要java源代码。
- resources: 保存Spring引导配置文件、Liquibase更改日志以及应用程序使用的静态资源,如服务器端i18n文件和电子邮件模板。
- webapp: 保存Angular应用程序源代码和客户端静态内容,如图像、样式表、i18n文件等。
test
- java:保存服务器端单元和集成测试源。
- javascript:为客户端应用程序保存Karma单元测试规范和量角器端到端规范。
- resources:保存应用程序用于测试的Spring配置文件和静态资源,如服务器端i18n文件和电子邮件模板。
服务端src/main/java
src/main/java文件夹内重要部分。
ShopApp.java
这是应用程序的主入口类。由于这是一个Spring引导应用程序,主类是可执行的,您可以通过在IDE中运行这个类来启动应用程序。
注解
Spring JavaConfig注解
@SpringBootApplication
@EnableConfigurationProperties({LiquibaseProperties.class, ApplicationProperties.class})
- @SpringBootApplication:是一个复合注解,包括@ComponentScan,和@SpringBootConfiguration,@EnableAutoConfiguration。
- @ComponentScan:扫描当前包及其子包下被@Component,@Controller,@Service,@Repository注解标记的类并纳入到spring容器中进行管理。
- @EnableAutoConfiguration:作用是启动自动的配置,意思就是Springboot根据你添加的jar包来配置你项目的默认配置。
- @SpringBootConfiguration:继承自@Configuration,二者功能也一致,标注当前类是配置类,并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到srping容器中,并且实例名就是方法名。
- @EnableConfigurationProperties:帮助通过属性文件注册应用程序的其他配置。
main方法
public static void main(String[] args) {
SpringApplication app = new SpringApplication(ShopApp.class);
DefaultProfileUtil.addDefaultProfile(app);
Environment env = app.run(args).getEnvironment();
logApplicationStartup(env);
}
config
这个包包含用于数据库、缓存、WebSocket等的Spring bean配置。我们将在这里为应用程序配置各种选项。其中一些重要的类是:
CacheConfiguration.java
该类为应用程序配置Hibernate二级缓存。由于我们选择Hazelcast作为缓存提供程序,所以该类的配置方式相同。
DatabaseConfiguration.java
该类为应用程序配置数据库,并为应用程序启用事务管理、JPA审计和JPA存储库。它还配置Liquibase来管理用于开发的DB迁移和H2数据库。
WebConfigurer.java
这是我们设置HTTP缓存头、MIME映射、静态资产位置和CORS(跨源资源共享)的地方。
SecurityConfiguration.java
配置了应用程序的安全性。
- 启用了WebSecurity和MethodSecurity,因此我们可以在单个方法上使用 @Secured and @Pre/PostAuthorize。
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
- 忽略Spring安全配置中的静态内容和某些api:
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")
.antMatchers("/app/**/*.{js,html}")
.antMatchers("/i18n/**")
.antMatchers("/content/**")
.antMatchers("/swagger-ui/index.html")
.antMatchers("/test/**");
}
- 下面的配置告诉Spring security哪些端点允许所有用户使用,哪些端点应该进行身份验证,以及哪些端点需要特定的角色(本例中是管理员)
@Override
public void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
.exceptionHandling()
.authenticationEntryPoint(problemSupport)
.accessDeniedHandler(problemSupport)
.and()
.headers()
.frameOptions()
.disable()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/register").permitAll()
.antMatchers("/api/activate").permitAll()
.antMatchers("/api/authenticate").permitAll()
.antMatchers("/api/account/reset-password/init").permitAll()
.antMatchers("/api/account/reset-password/finish").permitAll()
.antMatchers("/api/**").authenticated()
.antMatchers("/websocket/tracker").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/websocket/**").permitAll()
.antMatchers("/management/health").permitAll()
.antMatchers("/management/info").permitAll()
.antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
.and()
.apply(securityConfigurerAdapter());
}
domain
应用程序的域模型类在这个包中。这些简单的pojo具有JPA注解,将其映射到Hibernate实体。当选择Elasticsearch选项时,它们还充当文档对象。以User.java为例.
类的注解
@Entity
@Table(name = "jhi_user")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
字段的注解
- @Id :标记实体主键
- @Column:字段映射到数据表列
- @NotNull、@Pattern和@Size:用于验证的注释。
- @JsonIgnore:ackson在将对象转换为JSON时,是否使用它来忽略字段,这些对象将在REST API请求中返回
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
private Long id;
@NotNull
@Pattern(regexp = Constants.LOGIN_REGEX)
@Size(min = 1, max = 50)
@Column(length = 50, unique = true, nullable = false)
private String login;
@JsonIgnore
@NotNull
@Size(min = 60, max = 60)
@Column(name = "password_hash", length = 60, nullable = false)
private String password;
数据表之间的注释
@JsonIgnore
@ManyToMany
@JoinTable(
name = "jhi_user_authority",
joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "authority_name", referencedColumnName = "name")})
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@BatchSize(size = 20)
private Set<Authority> authorities = new HashSet<>();
repository
包含实体的Spring Data存储库。这些接口定义通常由Spring Data自动实现。这样就不需要为数据访问层编写任何样板实现。以UserRepository.java示例。
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
String USERS_BY_LOGIN_CACHE = "usersByLogin";
String USERS_BY_EMAIL_CACHE = "usersByEmail";
Optional<User> findOneByActivationKey(String activationKey);
List<User> findAllByActivatedIsFalseAndCreatedDateBefore(Instant dateTime);
···
}
- @Repository注释将其标记为Spring Data存储库组件。
- 该接口扩展了JpaRepository,它允许继承所有默认的CRUD操作,如findOne、findAll、save、count和delete。
- 自定义方法按照Spring数据命名约定编写为简单的方法定义,以便方法名称指定要生成的查询。例如,
findOneByEmailIgnoreCase
生成一个等价的查询SELECT * FROM user WHERE LOWER(email) = LOWER(:email)
。
security
包含Spring安全相关的组件和utils,由于我们选择JWT作为身份验证机制,它还包含与JWT相关的类,如TokenProvider、JWTFilter和JWTConfigurer。
service
包含由Spring服务bean、DTO、Mapstruct DTO映射器和服务实用程序组成的服务层。
web
包含web资源类、视图模型类和实用程序类。
rest
包含REST API的Spring资源类。它还包含视图模型对象和实用程序。以UserResource.java为例。
- 资源类由@RestController和@RequestMapping(“/api”)注解标记。
- 请求方法根据其用途使用注释进行注释,例如,下面的标记将createUser方法标记为“/users”的PostMapping,这意味着所有到
<applicationContext>/api/users
的POST请求都将由该方法提供服务。
@PostMapping("/users")
@PreAuthorize("hasRole(\"" + AuthoritiesConstants.ADMIN + "\")")
public ResponseEntity<User> createUser(@Valid @RequestBody UserDTO userDTO) throws URISyntaxException {
···
}
WebSocket
包含Websocket控制器和视图模型。
JHipster在服务器端使用DTO(数据传输对象)和VM(视图模型)。dto用于在服务层和资源层之间传输数据。它们中断Hibernate事务,并避免由资源层触发进一步的延迟加载。vm仅用于在web前端显示数据,不与服务层交互。
Resources
Resources下的config
它包含应用程序属性YAML文件和Liquibase更改日志。
i18n
它包含服务器端i18n资源文件。
mails
这保存了电子邮件的Thymeleaf模板。
templates
它为客户端保存Thymeleaf模板。
客户端src/main/webapp
app
包含Angular应用的Typescript源代码,每个组织都有一个文件夹
app.main.ts
这是Angular应用程序的主文件。注意,它使用了platformBrowserDynamic,这使得应用程序可以在浏览器中使用JIT(即时)编译。
platformBrowserDynamic()
.bootstrapModule(ShopAppModule, { preserveWhitespaces: true })
.then(success => console.log(`Application started`))
.catch(err => console.error(err));
app.module.ts
这是Angular应用程序的主模块。它声明了应用程序级的组件和提供者,并导入了应用程序的其他模块。它还引导主应用程序组件。
@NgModule({
imports: [
BrowserModule,
Ng2Webstorage.forRoot({ prefix: 'jhi', separator: '-' }),
NgJhipsterModule.forRoot({
// set below to true to make alerts look like toast
alertAsToast: false,
alertTimeout: 5000,
i18nEnabled: true,
defaultI18nLang: 'zh-cn'
}),
ShopSharedModule.forRoot(),
ShopCoreModule,
ShopHomeModule,
ShopAccountModule,
// jhipster-needle-angular-add-module JHipster will add new module here
ShopEntityModule,
ShopAppRoutingModule
],
declarations: [JhiMainComponent, NavbarComponent, ErrorComponent, PageRibbonComponent, ActiveMenuDirective, FooterComponent],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true
},
{
provide: HTTP_INTERCEPTORS,
useClass: AuthExpiredInterceptor,
multi: true
},
{
provide: HTTP_INTERCEPTORS,
useClass: ErrorHandlerInterceptor,
multi: true
},
{
provide: HTTP_INTERCEPTORS,
useClass: NotificationInterceptor,
multi: true
}
],
bootstrap: [JhiMainComponent]
})
export class ShopAppModule {
constructor(private dpConfig: NgbDatepickerConfig) {
this.dpConfig.minDate = { year: moment().year() - 100, month: 1, day: 1 };
}
}
account
此模块包含与帐户相关的功能,如激活、密码、密码重置、注册和设置。每个组件都由component.html, component.ts, route.ts, and service.ts文件组成。
admin
此模块包含与管理相关的特性,如审核、配置、文档、服务状态、日志、资源监控、跟踪器和用户管理。每个组件都由component.html, component.ts, route.ts, and service.ts文件组成。
blocks
该文件夹由HTTP拦截器和应用程序使用的其他配置组成。
entities
实体模块
home
首页模块
layouts
该文件夹包含导航栏、页脚、错误页面等布局组件。
shared
此模块包含应用程序所需的所有共享服务(auth、跟踪器、用户)、组件(登录、警报)、实体模型和实用程序。
content
此文件夹包含静态内容,如图像、CSS和SASS文件。
i18n 国际化
这是i18n JSON文件所在的位置。每种语言都有一个文件夹,其中包含许多由模块组织的JSON文件。
swagger-ui
该文件夹具有用于API文档开发的Swagger UI客户机。
index.html
这是web应用程序的索引文件。这包含了加载angular应用程序主组件的非常少的代码。它是一个单页Angular应用程序。您还将在这个文件中发现一些注释掉的实用程序代码,比如谷歌分析脚本和服务工作者脚本。如果需要,可以启用这些。
<!doctype html>
<html class="no-js" lang="en" dir="ltr">
<head>
...
</head>
<body>
...
<jhi-main></jhi-main>
<noscript>
<h1>You must enable javascript to view this page.</h1>
</noscript>
...
</body>
</html>
要使用服务工作者启用PWA模式,只需在src/main/webapp/index.html中取消相应代码的注释,以注册服务工作者。JHipster使用workbox,它创建相应的服务工作者并动态生成sw.js。