我尝试用AngularJS+JavaEE搭建了一个类似于SIer的WEB应用程序(第一部分)

有一些人说要用AngularJS+JavaEE(JPA、JAX-RS)来替换在seasar2上实现的WEB应用程序!所以我创建了一个实际的示例来展示它会是什么样子。
作为一个只开发后端的人,结果只能以这种方式结束了。

这里是原始代码链接:
https://github.com/ko-aoki/angularJS_practice/tree/forQiita

我所参考的书籍如下。

    • Beginning Java EE 6 GlassFish 3で始めるエンタープライズJava (Programmer’s SELECTION)

 

    AngularJSアプリケーション開発ガイド

一旦开始实际制作后,只有书本上的信息远远不够,感觉很困难。
Oracle对JavaEE非常重视,但是从JavaEE6开始,特别是JPA的日本语信息明显不足。

功能概述

以大致的方式运行,实现以下功能。

    • ログイン

 

    • メニュー

 

    • 条件検索画面(検索結果明細を表示)

 

    • データ登録画面

 

    コード照会画面(ページ検索)

使用应用程序

    • NetBeans8

 

    • 業務だとeclipseを10年以上使用しているのですが、JavaEEならNetBeansかなと採用。

 

    • 自動生成機能が強力でした。

 

    • WebStorm8

 

    • AngularJSのコード補完があったり。NetBeansも対応していたかな?

 

    まだ使いこなせてないです。。

文件夹结构

+—src // Java源代码
| \—java
| +—基础
| | \—实体
| +—实体
| +—实体类
| +—表单
| +—仓库
| +—资源
| +—服务
| \—工具
+—test // 测试源代码。包括karma等。
\—web
+—样式
+—数据
+—图片
+—图片
+—脚本
| +—控制器 // AngularJS控制器
| +—指令 // AngularJS指令
| +—服务 // AngularJS服务
| \—第三方库 // AngularJS,jQuery等库文件
+—分部 // AngularJS模板
+—模板 // AngularJS模板(指令用)
\—WEB-INF

设定文件(的那种东西)

JavaScript – JavaScript

    main.js

使用RequireJS时,如果文件增加,请在此处添加。

require.config({
    paths: {
        'jquery': 'vendor/jquery/jquery',
        'jquery.treeview': 'vendor/jquery/jquery.treeview',
        'angular': 'vendor/angular/angular',
        'angularRoute': 'vendor/angular/angular-route',
        'angularResource': 'vendor/angular/angular-resource',
        'angularMocks': 'vendor/angular-mocks/angular-mocks',
        'domReady': 'vendor/requirejs/domReady'
    },
    shim: {
        'jquery' : {'exports' : 'jquery'},
        'jquery.treeview' :['jquery'],
        'angular' : {'exports' : 'angular'},
        'angularRoute': ['angular'],
        'angularResource': { deps:['angular'] },
        'angularMocks': {
            deps:['angular'],
            'exports':'angular.mock'
        }
    }
});

require([
        'angular',
        'app',
        'domReady',
        //ファイルを追加したらここに追記
        'services/dtoSrv',
        'controllers/loginCtrl',
        'controllers/menuCtrl',
        'controllers/mntMstUserCtrl',
        'controllers/mntMstUserRegCtrl',
        'controllers/mntMstUserRegConfirmCtrl',
        'controllers/codeDeptCtrl',
        'directives/csngPage',
        'directives/csngCodeDept'
    ],
    function (angular, app, domReady) {
        'use strict';
        app.config(['$routeProvider',
            function($routeProvider) {
//ルートの定義。画面を追加したらここで追記
                $routeProvider.when('/login', {templateUrl: 'partials/login.html', controller: 'LoginCtrl'});
                $routeProvider.when('/menu/:roleId', {templateUrl: 'partials/menu.html', controller: 'MenuCtrl'});
//中略
                $routeProvider.otherwise({redirectTo: '/login'});
            }
        ]);
        domReady(function() {
            angular.bootstrap(document, ['MyApp']);
            $('html').addClass('ng-app: MyApp');
        });
    }
);

Java企业版

    persistence.xml

参考了寺田先生的文章,然后在NetBeans中进行自动生成。

实施

登录

当输入用户ID和密码后,点击”登录”按钮,系统将访问服务器并参阅用户主数据库,根据查询结果进行下一步页面跳转或输出错误信息。

AngularJS: 请将以下内容用中文进行改写,只需要一种选项:

AngularJS

创建模板文件和相应的控制器文件。

    login.html
<h1>ログイン</h1>
<ul>
   <li ng-repeat="message in messages">
          <p>{{message}}</p>
   </li>
</ul>
<br>
<span>ユーザID :</span><input type="text" ng-model="loginUserId"/>
<br>
<span>パスワード:</span><input type="text" ng-model="password"/>
<br>
<button class="btn" ng-click="login()">ログイン</button>
    loginCtrl.js

在控制器文件中,通过JAX-RS进行访问,并根据结果输出错误或进行页面跳转。
通过$resource创建资源对象,并使用get方法访问服务器。
如果使用$location.path,则不会发生HTTP请求。

define(['controllers','angularResource'],
    function(controllers) {
        controllers.controller('LoginCtrl', ['$scope', '$http', '$location', '$resource',
            function ($scope, $http, $location, $resource) {
                $scope.login = function login() {
                    var login = $resource('webresources/login/:loginUserId,:password',
                                    {
                                        'loginUserId': '@loginUserId',
                                        'password': '@password'
                                    }
                                );
                    login.get(
                        {'loginUserId': $scope.loginUserId, 'password': $scope.password},
                        function (data) {
                            if (data.result === "error") {
                                $scope.messages = data.messages;
                            } else {
                                $location.path("menu/" + data.roleId);
                            }
                        }
                    );
                };
            }]);
    });

JavaEE是一种用于开发企业级应用程序的编程语言和平台。

    LoginResource.java

AngularJS的资源类,用于访问。
根据@Path指定的请求URL格式,确定相应的类和方法。
当以’login で”webresources/login/ユーザ,パスワード”的形式请求loginCtrl.js时,
将执行login方法。
通过@Inject进行DI。
通过@Produces(“application/json”),将返回的Java对象转换为JSON格式。


@Path("login")
public class LoginResource {

    @Inject
    private LoginService loginService;

    public LoginResource() {
    }

    @GET
    @Path("{userId},{password}")
    @Produces("application/json")
    public LoginForm login(@PathParam("userId") String userId, @PathParam("password") String password) {
       return loginService.login(userId, password);
    }

}
    LoginServiceImpl.java

被资源类调用的服务类。
从转移现有Java应用的角度来看,我们决定在返回值中指定form类。
利用Repository类获取Entity类,并将其转录到Form类中。

public class LoginServiceImpl implements LoginService{

    @Inject
    private MstUserRepository mstUserRep;

    public LoginForm login(String userId, String password) {

        List<MstUser> rec = mstUserRep.findByUserId(userId);
        LoginForm form = new LoginForm();
        if (rec.isEmpty()) {
            form.setMessages(Arrays.asList("ユーザが存在しません"));
            form.setResult("error");
        } else {
            if (password.equals(rec.get(0).getPassword())) {
                form.setRoleId(rec.get(0).getRoleId().getRoleId());
                form.setResult("ok");
            } else {
                form.setMessages(Arrays.asList("パスワードが一致しません"));
                form.setResult("error");
            }
        }
        return form;

    }

}
    MstUserRepositoryImpl.java

操作实体的存储库类。
老实说,我不太理解它与DAO的区别。

@PersistenceContext 指定了 persistence-unit。这里看起来可以进行共享化。
findByUserId 使用了 NamedQuery。


public class MstUserRepositoryImpl implements MstUserRepository{
    @PersistenceContext(name = "common-app-javaee7PU")
    private EntityManager em;

    /**
     * ユーザIDでユーザを検索します.
     * @param userId
     * @return 
     */
    @Override
    public List<MstUser> findByUserId(String userId) {
       Query query = em.createNamedQuery("MstUser.findByUserId", MstUser.class);
       query.setParameter("userId", userId);
       List<MstUser> rec = query.getResultList();
       return rec;
    }
//中略
    /**
     * ユーザ情報を更新します.
     * @param user 
     */
    @Override
    @Transactional(Transactional.TxType.REQUIRED)
    public void update(MstUser user) {
        em.merge(user);
    }

}

    MstUser.java

这个也可以在NetBeans中指定表格并自动生成。

总结

在旧有的Java框架中,JSP+动作类的实现部分可以用AngularJS来替代。
实际写起来感觉比以前更清晰地分离了前端和后端逻辑。JSP渲染页面需要花费一定的时间,所以去掉这个可以说是一个很大的进步。
JAX-RS可以只通过注解就能完成想做的事情。想起以前编写的代码,不禁流连忘返。
因为之前用的是MyBatis之类的基于原生SQL的框架,对JPA的理解相当困难。

继续下去

bannerAds