Spring MVC Frameworkの詳細解説:高パフォーマンスなWebアプリケーションの作成
まず、Spring MVC フレームワークを紹介します。
1 Spring MVC フレームワークの概念
Spring MVC は、Java の軽量の Model-View-Controller (MVC) アーキテクチャに基づく Web フレームワークであり、柔軟性が高く、疎結合です。優れた開発エクスペリエンスと迅速な開発効率を提供することに重点を置いています。
2 Spring MVC フレームワークの利点
Spring MVC フレームワークには次の利点があります。
- 使いやすさ: Spring MVC フレームワークは、アノテーションベースの構成方法を採用しており、開発者の作業負荷を簡素化します。
- 強力な柔軟性: Spring MVC フレームワークは、さまざまなシナリオのニーズを満たすために多数の拡張ポイントを提供します。
- 豊富なテンプレート エンジン: Spring MVC フレームワークは、JSP、FreeMarker、Thymeleaf などのさまざまなテンプレート エンジンをサポートしています。
- 優れたスケーラビリティ: Spring MVC フレームワークのすべてのコンポーネントは、アプリケーション全体の動作に影響を与えることなく置換または拡張できます。
3 Spring MVC フレームワークと他の MVC フレームワークの比較
他の MVC フレームワークと比較して、Spring MVC フレームワークには次の利点があります。
- 学習と使用が簡単: Spring MVC フレームワークの API インターフェイスはシンプルで理解しやすく、学習と使用が非常に簡単です。
- 強力なスケーラビリティ: Spring MVC フレームワークのすべてのコンポーネントはカスタマイズまたは置換できるため、非常に強力なスケーラビリティを備えています。
- 複数のテンプレート エンジンのサポート: Spring MVC フレームワークは、JSP、FreeMarker、Thymeleaf などの複数のテンプレート エンジンをサポートします。
- Spring フレームワークの統合: Spring MVC フレームワークは Spring フレームワークの一部として設計されているため、Spring フレームワークが提供する機能を最大限に活用できます。
2、Spring MVC フレームワークのワークフロー
1 インターセプターの概要
Spring MVC フレームワークのワークフローでリクエストを処理する最初のコンポーネントはインターセプターです。インターセプターは、ログの記録やユーザーのログイン ステータスの確認など、リクエストの前処理と後処理を行うことができます。
public interface HandlerInterceptor {
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception;
void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception;
}
2 内部プロセッサの紹介
リクエストがインターセプターによってインターセプトされない場合、リクエストは内部プロセッサによって処理されます。通常、内部プロセッサはコントローラ クラスであり、リクエストの解析、対応するサービス メソッドの呼び出し、処理結果の ModelAndView オブジェクトへのバインドを担当します。
public interface Controller {
ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;
}
3 HandlerAdapter の概要
HandlerAdapter は、さまざまな種類のプロセッサ (Controller、@RequestMapping など) を Spring MVC フレームワークの処理フローに適応させる役割を持つアダプターです。HandlerAdapter は、受信リクエストが対応するプロセッサーで処理できるかどうかを判断します。
public interface HandlerAdapter {
boolean supports(Object handler);
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
}
4 ビューリゾルバーの概要
Spring MVCフレームワークは、内部プロセッサで処理結果をModelAndViewオブジェクトにバインドした後、ModelAndViewオブジェクトをビューリゾルバに渡します。ビュー リゾルバーは、ModelAndView オブジェクト内のビュー名に従って特定のビュー オブジェクトを解決します。
public interface ViewResolver {
View resolveViewName(String viewName, Locale locale) throws Exception;
}
5 レンダービューの概要
ビュー リゾルバーは、ビュー名を特定のビュー オブジェクトに解決した後、それをレンダリングのためにレンダラーに渡します。レンダラーはモデル データをビューにバインドし、レンダリングされた結果をクライアントに出力します。
public interface View {
void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception;
}
3. Spring MVCフレームワークの基本構成
1 Spring MVC フレームワーク構成ファイル
Spring MVCフレームワークを使用する場合、Spring MVCフレームワークの基本的な構成情報を定義するXML構成ファイルを作成する必要があります。以下は、典型的な Spring MVC フレームワーク構成ファイルの例です。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
<!--启用注解配置-->
<context:annotation-config />
<!--启用MVC注解驱动-->
<mvc:annotation-driven />
<!--配置HandlerMapping-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!--配置HandlerAdapter-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
<!--配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp"></property>
</bean>
<!--配置静态资源文件映射-->
<mvc:resources location="/static/" mapping="/static/**"/>
</beans>
2 テクノロジーの選択と構成
Spring MVC フレームワークを使用するプロセスでは、構成のためにいくつかのテクノロジーを選択する必要があります。たとえば、どのビュー テンプレート エンジンを選択する必要があるか、フォーム検証を実装する方法、アップロードされたファイルを処理する方法などです。
一般的に使用されるテクノロジー選択構成の一部を次に示します。
- テンプレート エンジンの構成を表示します。
<!--配置Thymeleaf视图解析器-->
<bean id="templateResolver" class="org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver">
<property name="prefix" value="/WEB-INF/templates/" />
<property name="suffix" value=".html" />
<property name="templateMode" value="HTML5" />
<property name="cacheable" value="false" />
</bean>
<bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver" />
<property name="enableSpringELCompiler" value="true" />
</bean>
<bean id="viewResolver" class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
<property name="templateEngine" ref="templateEngine" />
<property name="characterEncoding" value="UTF-8" />
</bean>
- フォーム検証フレームワークの構成:
<!--配置验证框架-->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="validationMessageSource" ref="messageSource" />
</bean>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>ValidationMessages</value>
</list>
</property>
</bean>
- ファイルのアップロードとダウンロードの構成:
<!--配置文件上传下载相关的组件-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="52428800" />
</bean>
3 アノテーション構成スキル
Spring MVC フレームワークでの設定にアノテーションを付けることは、非常に便利な設定方法です。以下に、一般的なアノテーション構成の使用テクニックをいくつか示します。
- コントローラー クラスは @Controller アノテーションを使用して定義されます。@RequestMapping アノテーションは、リクエストのパスとリクエストのメソッドを指定するために使用されます。
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public String getUserById(@PathVariable("id") int id, ModelMap model) {
User user = userService.getUserById(id);
model.addAttribute("user", user);
return "user";
}
}
- @ResponseBody アノテーションを使用して、戻り値の型が JSON 形式であることを指定します。
@RequestMapping(value = "/user", method = RequestMethod.POST)
@ResponseBody
public User addUser(@RequestBody User user) {
int userId = userService.addUser(user);
User returnUser = userService.getUserById(userId);
return returnUser;
}
- @ModelAttribute アノテーションを使用して、Form オブジェクトのプロパティ スコープを制限します。
@RequestMapping(value = "/user/edit", method = RequestMethod.POST)
public String editUser(@ModelAttribute("userForm") User user) {
userService.editUser(user);
return "redirect:/user";
}
4 よくある問題と解決策
Spring MVC フレームワークを使用するときに発生する可能性のある一般的な問題がいくつかあります。よくある問題と解決策をいくつか示します。
- ページ文字化け問題
ページ文字化けの問題を回避するには、次のコードを JSP ファイルに追加します。
<%@ page contentType="text/html;charset=UTF-8" %>
次の構成を構成ファイルに追加します。
<!--配置字符编码过滤器-->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- 静的リソースにアクセスできない
Spring MVC フレームワークの使用時に静的リソースにアクセスできないという問題が発生した場合は、次の構成を構成ファイルに追加できます。
<!--配置静态资源文件映射-->
<mvc:resources location="/static/" mapping="/static/**"/>
4. Spring MVCフレームワークの高度な応用
1 RESTful Web サービス
RESTful Web サービスは、HTTP プロトコルに基づく Web サービスであり、単純な URL と HTTP メソッドを使用してリソースとその操作を定義します。以下は、典型的な RESTful Web サービスのコントローラー クラスの例です。
@RestController
@RequestMapping("/users")
public class UserController {
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@RequestMapping(value = "/", method = RequestMethod.GET)
public List<User> getUsers() {
return userService.getUsers();
}
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public User getUserById(@PathVariable("id") int id) {
User user = userService.getUserById(id);
if (user == null) {
throw new UserNotFoundException("User not found with id:" + id);
}
return user;
}
@RequestMapping(value = "/", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public User addUser(@RequestBody User user) {
return userService.addUser(user);
}
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
@ResponseStatus(HttpStatus.NO_CONTENT)
public void editUser(@PathVariable("id") int id, @RequestBody User user) {
userService.editUser(id, user);
}
@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteUser(@PathVariable("id") int id) {
userService.deleteUser(id);
}
}
2 WebSocket通信
WebSocketはHTML5規格で新たに追加されたプロトコルで、ブラウザとサーバー間の全二重通信を実現し、サーバーがクライアントにメッセージを積極的にプッシュすることでリアルタイム通信を実現します。以下は、一般的な WebSocket ハンドラーの例です。
@Component
@ServerEndpoint("/websocket/{name}")
public class WebSocketHandler {
private static ConcurrentHashMap<String, Session> sessions = new ConcurrentHashMap<>();
private UserService userService;
@Autowired
public WebSocketHandler(UserService userService) {
this.userService = userService;
}
@OnOpen
public void onOpen(Session session, @PathParam("name") String name) throws IOException {
if(!sessions.containsKey(name)){
session.setMaxIdleTimeout(1800000);
sessions.put(name, session);
}
}
@OnClose
public void onClose(Session session, @PathParam("name") String name) {
sessions.remove(name);
}
@OnMessage
public void onMessage(Session session, String message, @PathParam("name") String name) throws IOException {
session.getBasicRemote().sendText("Received:" + message);
}
@OnError
public void onError(Session session, Throwable throwable) {
throwable.printStackTrace();
}
}
3 ファイルのアップロードとダウンロード
Spring MVC フレームワークを使用する場合、ファイルのアップロードとダウンロードの機能要件を処理する必要がある場合があります。一般的なファイルのアップロードおよびダウンロード ハンドラーの例を次に示します。
@Controller
@RequestMapping("/file")
public class FileController {
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public String uploadFile(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws IOException {
String fileName = file.getOriginalFilename();
String filePath = request.getSession().getServletContext().getRealPath("/upload/") + fileName;
file.transferTo(new File(filePath));
return "redirect:/file";
}
@RequestMapping("/download")
public ResponseEntity<byte[]> downloadFile(HttpServletRequest request) throws IOException {
String fileName = "example.pdf";
String filePath = request.getSession().getServletContext().getRealPath("/upload/") + fileName;
byte[] content = FileUtils.readFileToByteArray(new File(filePath));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_PDF);
headers.setContentDispositionFormData("attachment", fileName);
return new ResponseEntity<byte[]>(content, headers, HttpStatus.OK);
}
}
インターセプターを使用するための 4 つのヒント
インターセプターは、Spring MVC フレームワークでコントローラーの前処理ロジックと後処理ロジックを実装するための非常に便利な方法です。以下は、典型的なインターセプター実装の例です。
@Component
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
if (session.getAttribute("user") != null) {
return true;
} else {
response.sendRedirect(request.getContextPath() + "/login");
return false;
}
}
}
設定ファイルでインターセプタとインターセプタ マッピングを定義します。
<!--定义拦截器-->
<bean id="authorizationInterceptor" class="com.example.interceptor.AuthorizationInterceptor" />
<!--定义拦截器映射-->
<interceptor-mapping path="/**" >
<interceptor>
<ref bean="authorizationInterceptor" />
</interceptor>
</interceptor-mapping>
例外ハンドラーを使用するための 5 つのヒント
例外ハンドラーは、Spring MVC フレームワークでグローバル例外処理を実装するための非常に便利な方法です。以下は、典型的な例外ハンドラー実装の例です。
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleException(Exception ex) {
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
errorResponse.setMessage(ex.getMessage());
return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<ErrorResponse> handleUserNotFoundException(UserNotFoundException ex) {
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setCode(HttpStatus.NOT_FOUND.value());
errorResponse.setMessage(ex.getMessage());
return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND);
}
}
カスタム注釈を使用するための 6 つのヒント
Spring MVC フレームワークでのアノテーションのカスタマイズは、ビジネス ロジックを実装するための非常に便利な方法です。以下は、典型的なカスタム アノテーション実装の例です。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthorizationRequired {
String[] value();
}
アノテーションを定義した後、それをコントローラー層で使用できます。
@RestController
@RequestMapping("/users")
public class UserController {
@AuthorizationRequired({
"admin"})
@RequestMapping(value = "/", method = RequestMethod.GET)
public List<User> getUsers() {
return userService.getUsers();
}
}
インターセプターでは、リフレクションを使用して、コントローラー メソッドで定義されたアノテーション情報を取得できます。
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
AuthorizationRequired annotation = handlerMethod.getMethodAnnotation(AuthorizationRequired.class);
if (annotation != null) {
String[] roles = annotation.value();
if (/*判断用户是否具备指定角色*/) {
return true;
} else {
response.setStatus(HttpStatus.FORBIDDEN.value());
return false;
}
}
}
return true;
}
5、Spring MVCフレームワークの最適化実践
Spring MVC フレームワークを使用して Web アプリケーションを開発する場合、最適化は重要な考慮事項となります。機能を実装するだけでは十分ではなく、アプリケーションをスケーラブルでパフォーマンスの高いものにする必要もあります。以下に、アプリケーションのパフォーマンスと保守性を向上させるための最適化手法をいくつか示します。
1 キャッシュを最大限に活用する
- 共通データをキャッシュする
キャッシュは、アプリケーションの応答時間とシステム負荷を大幅に削減できる一般的な最適化手法です。人気の商品リストやユーザー情報など、よく使われるデータをキャッシュに保存できます。
- キャッシュフレームワークを使用する
キャッシュ フレームワークを使用すると、キャッシュ機能をより便利に実装でき、有効期限、キャッシュ ヒット率、分散キャッシュなどの高度な機能が提供されます。Spring には、Ehcache、Redis、Guava など、一般的に使用されるキャッシュ フレームワークが多数あります。キャッシュフレームワークを使用する場合は、実際の状況に応じて適切なフレームワークを選択する必要があり、キャッシュされたデータの整合性や同時アクセスについても考慮する必要があります。
2 フロントエンドとバックエンドの最適化
- CDN を使用して静的リソースを高速化する
コンテンツ配信ネットワーク (CDN) は、Web サイトの静的リソース (画像、CSS、JS ファイルなど) をグローバル ノードに配布して、これらのリソースにアクセスする際のユーザーの応答時間を短縮し、ユーザー エクスペリエンスを向上させることができます。次のように、Spring MVC フレームワークによって提供されるリソース プロセッサを使用して CDN アドレスを構成できます。
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Value("${cdn.url}")
private String cdnUrl;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations(cdnUrl);
}
}
- フロントエンドコード圧縮
運用環境では、ファイル サイズと読み込み時間を削減するためにフロントエンド コードを圧縮する必要があります。フロントエンド コードは、YUI Compressor、Google Closure Compiler などの多くのツールを使用して圧縮できます。
- バックエンドコードの最適化
バックエンド コードを最適化することで、サーバー リソースをより有効に活用し、アプリケーションのパフォーマンスを向上させることができます。次の側面を最適化できます。
- スレッド プールを使用してリクエストを管理する
- キャッシュを賢く利用する
- データベースクエリの数を減らす
3 データベース最適化手法
- データベース接続の数を減らす
データベース接続の数は限られたリソースであり、接続が多すぎるとデータベースのパフォーマンスが低下します。接続プールを使用してデータベース接続を管理すると、必要なときにすぐに接続を取得し、使用が終了したら接続を解放できます。
- インデックスの公正な使用
インデックスを使用するとデータベース クエリ操作を高速化できますが、インデックスが多すぎたり、正しくない場合はクエリのパフォーマンスが低下する可能性があります。実際の状況に応じて適切なインデックスを選択し、重複したインデックスの作成を避ける必要があります。
- データベースサブデータベースサブテーブル
大規模なアプリケーションでは、単一のデータベースではニーズを満たせない場合があります。データベースをデータベースとテーブルに分割して、データベースの負荷容量とスケーラビリティを向上させることができます。ただし、これにはデータの一貫性や同時アクセスなどの問題も考慮する必要があります。
4 Springコンテナの最適化
- XML 設定の代わりにアノテーションを使用する
Spring 3.0 以降では、XML 設定ファイルの代わりにアノテーションを使用できます。アノテーションの構成は簡潔かつ明確であり、コードの読みやすさと保守性の向上にも役立ちます。
- シングルトンパターンを使用する
Spring では、Bean はデフォルトでシングルトンであるため、Bean を繰り返し作成すると、大量のメモリ オーバーヘッドが発生し、パフォーマンスが低下します。シングルトン パターンを合理的に使用して Bean を初期化し、アプリケーションのパフォーマンスを向上させることができます。