Nicholas S. Williams A wrox A Wiley Brand
CHAPTER 1; INTRODUCING JAVA PLATFORM, ENTERPRISE EDITION 3 A Timeline of Java Platforms 3 In the Beginning 4 The Birth of Enterprise Java 5 Java SE and Java EE Evolving Together 6 Understanding the Most Recent Platform Features 9 A Continuing Evolution 13 Understanding the Basic Web Application Structure 13 Servlets, Filters, Listeners, and JSPs 13 Directory Structure and WAR Files 14 The Deployment Descriptor 15 Class Loader Architecture 16 Enterprise Archives 17 Summary 18 CHAPTER 2: USING WEB CONTAINERS 19 Choosing a Web Container 19 Apache Tomcat 20 GlassFish 21 JBoss and WildFly 22 Other Containers and Application Servers 22 Why You'll Use Tomcat in This Book 23 Installing Tomcat on Your Machine 23 Installing as a Windows Service 24 Installing as a Command-Line Application 24 Configuring a Custom JSP Compiler 26 Deploying and Undeploying Applications in Tomcat 27 Performing a Manual Deploy and Undeploy 28 Using the Tomcat Manager 28
Debugging Tomcat from Your IDE 30 Using IntelliJ IDEA 30 Using Eclipse 35 Summary 39 CHAPTER 3: WRITING YOUR FIRST SERVLET 41 Creating a Servlet Class 42 What to Extend 42 Using the Initializer and Destroyer 45 Configuring a Servlet for Deployment 46 Adding the Servlet to the Descriptor 46 Mapping the Servlet to a URL 47 Running and Debugging Your Servlet 49 Understanding doget(), dopost(), and Other Methods 51 What Should Happen during the service Method Execution? 51 Using HttpServletRequest 52 Using HttpServletResponse 55 Using Parameters and Accepting Form Submissions 56 Configuring your Application Using Init Parameters 61 Using Context Init Parameters 61 Using Servlet Init Parameters 62 Files from a Form 64 Uploading Introducing the Customer Support Project 65 Configuring the Servlet for File Uploads 65 Accepting a File Upload 68 Making Your Application Safe for Multithreading 69 Understanding Requests, Threads, and Method Execution 69 Protecting Shared Resources 70 Summary 71 CHAPTER 4: USING JSPS TO DISPLAY CONTENT 73 <br /> Is Easier Than output.println("<br />") 74 Why JSPs Are Better 75 What Happens to a JSP at Run Time 76 Creating Your First JSP 78 Understanding the File Structure 78 Directives, Declarations, Scriptlets, and Expressions 79 Commenting Your Code 81 Adding Imports to Your JSP 82
Using Directives 83 Using the <jsp> Tag 86 Using Java within a JSP (and Why You Shouldn't!) 88 Using the Implicit Variables in a JSP 88 Why You Shouldn't Use Java in a JSP 93 Combining Servlets and JSPs 94 Configuring JSP Properties in the Deployment Descriptor 94 Forwarding a Request from a Servlet to a JSP 97 A Note about JSP Documents (JSPX) 102 Summary 104 CHAPTER 5: MAINTAINING STATE USING SESSIONS 105 Understanding Why Sessions Are Necessary 106 Maintaining State 106 Remembering Users 107 Enabling Application Workflow 107 Using Session Cookies and URL Rewriting 107 Understanding the Session Cookie 108 Session IDs in the URL 110 Session Vulnerabilities 112 Storing Data in a Session 116 Configuring Sessions in the Deployment Descriptor 116 Storing and Retrieving Data 119 Removing Data 123 Storing More Complex Data in Sessions 125 Applying Sessions Usefully 129 Adding Login to the Customer Support Application 129 Detecting Changes to Sessions Using Listeners 133 Maintaining a List of Active Sessions 135 Clustering an Application That Uses Sessions 139 Using Session IDs in a Cluster 139 Understand Session Replication and Failover 141 Summary 142 CHAPTER 6: USING THE EXPRESSION LANGUAGE IN JSPS 143 Understanding Expression Language 144 What It's For 144 Understanding the Base Syntax 145 Placing EL Expressions 146 Writing with the EL Syntax 147
Reserved Keywords 148 Operator Precedence 148 Object Properties and Methods 154 EL Functions 155 Static Field and Method Access 156 Enums 157 Lambda Expressions 157 Collections 158 Using Scoped Variables in EL Expressions 160 Using the Implicit EL Scope 161 Using the Implicit EL Variables 165 Accessing Collections with the Stream API 167 Understanding Intermediate Operations 168 Using Terminal Operations 170 Putting the Stream API to Use 171 Replacing Java Code with Expression Language 172 Summary 175 CHAPTER 7: USING THE JAVA STANDARD TAG LIBRARY 177 Introducing JSP Tags and the JSTL 178 Working with Tags 178 Using the Core Tag Library (C Namespace) 182 <c:out> 182 <c:url> 183 <c:if> 184 <c:choose>, <c:when>, and <c:otherwise> 185 <c:foreach> 186 <c:fortokens> 187 <c:redirect> 188 <c:import> 188 <c:set> and <c:remove> 189 Putting Core Library Tags to Use 190 Using the Internationalization and Formatting Tag Library (FMT Namespace) 193 Internationalization and Localization Components 193 <fmt:message> 194 <fmt:setlocale> 196 <fmt:bundle> and <fmt:setbundle> 196 <fmt:requestencoding> 197 <fmt:timezone> and <fmt:settimezone> 197 <fmt:formatdate> and <fmt:parsedate> 198 <fmt:formatnumber> and <fmt:parsenumber> 199
Putting i18n and Formatting Library Tags to Use 200 Using the Database Access Tag Library (SQL Namespace) 203 Using the XML Processing Tag Library (X Namespace) 205 Replacing Java Code with JSP Tags 205 Summary 208 CHAPTER 8: WRITING CUSTOM TAG AND FUNCTION LIBRARIES 209 Understanding TLDs, Tag Files, and Tag Handlers 210 Reading the Java Standard Tag Library TLD 211 Comparing JSP Directives and Tag File Directives 217 Creating Your First Tag File to Serve as an HTML Template 219 Creating a More Useful Date Formatting Tag Handler 221 Creating an EL Function to Abbreviate Strings 226 Replacing Java Code with Custom JSP Tags 227 Summary 232 CHAPTER 9: IMPROVING YOUR APPLICATION USING FILTERS 233 Understanding the Purpose of Filters 234 Logging Filters 234 Authentication Filters 234 Compression and Encryption Filters 234 Error Handling Filters 235 Creating, Declaring, and Mapping Filters 235 Understanding the Filter Chain 235 Mapping to URL Patterns and Servlet Names 236 Mapping to Different Request Dispatcher Types 236 Using the Deployment Descriptor 237 Using Annotations 238 Using Programmatic Configuration 238 Ordering Your Filters Properly 239 URL Pattern Mapping versus Servlet Name Mapping 239 Exploring Filter Order with a Simple Example 241 Using Filters with Asynchronous Request Handling 243 Investigating Practical Uses for Filters 247 Adding a Simple Logging Filter 248 Compressing Response Content Using a Filter 249 Simplifying Authentication with a Filter 254 Summary 255 xi
CHAPTER 10: MAKING YOUR APPLICATION INTERACTIVE WITH WEBSOCKETS 257 Evolution: From Ajax to WebSockets 258 Problem: Getting New Data from the Server to the Browser 259 Solution 1: Frequent Polling 259 Solution 2: Long Polling 260 Solution 3: Chunked Encoding 262 Solution 4: Applets and Adobe Flash 263 WebSockets: The Solution Nobody Knew Kind of Already Existed 264 Understanding the WebSocket APIs 268 HTML5 (JavaScript) Client API 268 Java WebSocket APIs 270 Creating Multiplayer Games with WebSockets 273 Implementing the Basic Tic-Tac-Toe Algorithm 274 Creating the Server Endpoint 274 Writing the JavaScript Game Console 278 Playing WebSocket Tic-Tac-Toe 283 Using WebSockets to Communicate in a Cluster 284 Simulating a Simple Cluster Using Two Servlet Instances 284 Transmitting and Receiving Binary Messages 286 Testing the Simulated Cluster Application 287 Adding "Chat with Support" to the Customer Support Application 288 Using Encoders and Decoders to Translate Messages 289 Creating the Chat Server Endpoint 291 Writing the JavaScript Chat Application 294 Summary 296 CHAPTER 11: USING LOGGING TO MONITOR YOUR APPLICATION 297 Understanding the Concepts of Logging 298 Why You Should Log 298 What Content You Might Want to See in Logs 299 How Logs Are Written 301 Using Logging Levels and Categories 303 Why Are There Different Logging Levels? 303 Logging Levels Defined 303 How Logging Categories Work 304 How Log Sifting Works 305 Choosing a Logging Framework 305 API versus Implementation 305
Performance 306 A Quick Look at Apache Commons Logging and SLF4J 307 Introducing Log4j 2 307 Integrating Logging into Your Application 312 Creating the Log4j 2 Configuration Files 313 Utilizing Fish Tagging with a Web Filter 316 Writing Logging Statements in Java Code 317 Using the Log Tag Library in JSPs 319 Logging in the Customer Support Application 319 Summary 320 CHAPTER 12: INTRODUCING SPRING FRAMEWORK 323 What Is Spring Framework? 324 Inversion of Control and Dependency Injection 325 Aspect-Oriented Programming 325 Data Access and Transaction Management 325 Application Messaging 326 Model-View-Controller Pattern for Web Applications 326 Why Spring Framework? 326 Logical Code Groupings 326 Multiple User Interfaces Utilizing One Code Base 327 Understanding Application Contexts 327 Bootstrapping Spring Framework 329 Using the Deployment Descriptor to Bootstrap Spring 330 Programmatically Bootstrapping Spring in an Initializer 332 Configuring Spring Framework 336 Creating an XML Configuration 338 Creating a Hybrid Configuration 340 Configuring Spring with Java Using Configuration 345 Utilizing Bean Definition Profiles 349 Understanding How Profiles Work 350 Considering Antipatterns and Security Concerns 352 Summary 353 CHAPTER 13: REPLACING YOUR SERVLETS WITH CONTROLLERS 355 Understanding RequestMapping 356 Using RequestMapping Attributes to Narrow Request Matching 356 Specifying Controller Method Parameters 360 Selecting Valid Return Types for Controller Methods 368
DNTENTS Using Spring Framework's Model and View Pattern 370 Using Explicit Views and View Names 371 Using Implicit Views with Model Attributes 373 Returning Response Entities 375 Making Your Life Easier with Form Objects 380 Adding the Form Object to Your Model 381 Using the Spring Framework <form> Tags 381 Obtaining Submitted Form Data 383 Updating the Customer Support Application 384 Enabling Multipart Support 384 Converting Servlets to Spring MVC Controllers 385 Creating a Custom Downloading View 386 Summary 387 CHAPTER 14: USING SERVICES AND REPOSITORIES TO SUPPORT YOUR CONTROLLERS 389 Understanding Model-View-Controller Plus Controller-Service- Repository 390 Recognizing Different Types of Program Logic 391 Repositories Provide Persistence Logic 392 Services Provide Business Logic 392 Controllers Provide User Interface Logic 393 Using the Root Application Context Instead of a Web Application Context 394 Reusing the Root Application Context for Multiple User Interfaces 394 Moving Your Business Logic from Controllers to Services 396 Using Repositories for Data Storage 399 Improving Services with Asynchronous and Scheduled Execution 404 Understanding Executors and Schedulers 404 Configuring a Scheduler and Asynchronous Support 405 Creating and Using Async Methods 407 Creating and Using Scheduled Methods 408 Applying Logic Layer Separation to WebSockets 409 Adding Container-Managed Objects to the Spring Application Context 409 Using the Spring WebSocket Configurator 411 Remember: A WebSocket Is Just Another Interface for Business Logic 412 Summary 416
CHAPTER 15: INTERNATIONALIZING YOUR APPLICATION WITH SPRING FRAMEWORK I18N 417 Why Do You Need Spring Framework i18n? 418 Making Internationalization Easier 418 Localizing Error Messages Directly 418 Using the Basic Internationalization ana Localization APIs 419 Understanding Resource Bundles and Message Formats 419 Message Sources to the Rescue 421 Using Message Sources to Internationalize JSPs 422 Configuring Internationalization in Spring Framework 424 Creating a Message Source 424 Understanding Locale Resolvers 425 Using a Handler Interceptor to Change Locales 427 Providing a User Profile Locale Setting 428 Including Time Zone Support 429 Understanding How Themes Can Improve Internationalization 429 Internationalizing Your Code 430 Using the <spring:message> Tag 431 Handling Application Errors Cleanly 433 Updating the Customer Support Application 436 Using the Message Source Directly 437 Summary 440 CHAPTER 16: USING JSR 349, SPRING FRAMEWORK, AND HIBERNATE VALIDATOR FOR BEAN VALIDATION 441 What Is Bean Validation? 442 Why Hibernate Validator? 444 Understanding the Annotation Metadata Model 444 Using Bean Validation with Spring Framework 445 Configuring Validation in the Spring Framework Container 445 Configuring the Spring Validator Bean 446 Setting Up Error Code Localization 448 Using a Method Validation Bean Post-Processor 449 Making Spring MVC Use the Same Validation Beans 450 Adding Constraint Validation Annotations to Your Beans 450
Understanding the Built-in Constraint Annotations 451 Understanding Common Constraint Attributes 452 Putting Constraints to Use 452 Using Valid for Recursive Validation 454 Using Validation Groups 455 Checking Constraint Legality at Compile-Time 457 Configuring Spring Beans for Method Validation 458 Annotating Interfaces, Not Implementations 458 Using Constraints and Recursive Validation on Method Parameters 459 Validating Method Return Values 459 Indicating That a Class Is Eligible for Method Validation 460 Using Parameter Validation in Spring MVC Controllers 462 Displaying Validation Errors to the User 463 Writing Your Own Validation Constraints 466 Inheriting Other Constraints in a Custom Constraint 466 Creating a Constraint Validator 467 Understanding the Constraint Validator Life Cycle 469 Integrating Validation in the Customer Support Application 470 Summary 472 CHAPTER 17: CREATING RESTFUL AND SOAP WEB SERVICES 473 Understanding Web Services 474 In the Beginning There Was SOAP 475 RESTful Web Services Provide a Simpler Approach 476 Configuring RESTful Web Services with Spring MVC 484 Segregating Controllers with Stereotype Annotations 484 Creating Separate Web and REST Application Contexts 485 Handling Error Conditions in RESTful Web Services 488 Mapping RESTful Requests to Controller Methods 491 Improving Discovery with an Index Endpoint 495 Testing Your Web Service Endpoints 496 Choosing a Testing Tool 497 Making Requests to Your Web Service 497 Using Spring Web Services for SOAP 500 Writing Your Contract-First XSD and WSDL 501 Adding the SOAP Dispatcher Servlet Configuration 503 Creating a SOAP Endpoint 504 Summary 508
CONTENT CHAPTER 18: USING MESSAGING AND CLUSTERING FOR FLEXIBILITY AND RELIABILITY 509 Recognizing When You Need Messaging and Clustering 510 What Is Application Messaging? 510 What Is Clustering? 513 How Do Messaging and Clustering Work Together? 517 Adding Messaging Support to your Application 520 Creating Application Events 520 Subscribing to Application Events 522 Publishing Application Events 523 Making your Messaging Distributable Across a Cluster 525 Updating Your Events to Support Distribution 526 Creating and Configuring a Custom Event Multicaster 527 Using WebSockets to Send and Receive Events 529 Discovering Nodes with Multicast Packets 531 Simulating a Cluster with Multiple Deployments 533 Distributing Events with AMQP 534 Configuring an AMQP Broker 536 Creating an AMQP Multicaster 537 Running the AMQP-Ehabled Application 539 Summary 540 CHAPTER 19: INTRODUCING JAVA PERSISTENCE API AND HIBERNATE ORM 543 What Is Data Persistence? 543 Flat-File Entity Storage 544 Structured File Storage 544 Relational Database Systems 545 Object-Oriented Databases 546 Schema-less Database Systems 546 What Is an Object-Relational Mapper? 547 Understanding the Problem of Persisting Entities 547 O/RMs Make Entity Persistence Easier 549 JPA Provides a Standard O/RM API 550 Why Hibernate ORM? 552 A Brief Look at Hibernate ORM 552 Using Hibernate Mapping Files 552
ONTENTS Understanding the Session API 554 Getting a Session from the Session Factory 556 Creating a SessionFactory with Spring Framework 557 Preparing a Relational Database 559 Installing MySQL and MySQL Workbench 559 Installing the MySQL JDBC Driver 562 Creating a Connection Resource in Tomcat 563 A Note About Maven Dependencies 564 Summary 564 CHAPTER 20: MAPPING ENTITIES TO TABLES WITH J PA ANNOTATIONS 565 Getting Started with Simple Entities 566 Marking an Entity and Mapping It to a Table 567 Indicating How JPA Uses Entity Fields 569 Mapping Surrogate Keys 570 Using Basic Data Types 576 Specifying Column Names and Other Details 579 Creating and Using a Persistence Unit 581 Designing the Database Tables 581 Understanding Persistence Unit Scope 583 Creating the Persistence Configuration 584 Using the Persistence API 586 Mapping Complex Data Types 590 Using Enums as Entity Properties 590 Understanding How JPA Handles Dates and Times 592 Mapping Large Properties to CLOBs and BLOBs 594 Summary 596 CHAPTER 21: USING JPA IN SPRING FRAMEWORK REPOSITORIES 597 Using Spring Repositories and Transactions 598 Understanding Transaction Scope 598 Using Threads for Transactions and Entity Managers 599 Taking Advantage of Exception Translation 601 Framework 602 Configuring Persistence in Spring Looking Up a Data Source 602 Creating a Persistence Unit in Code 603 Setting Up Transaction Management 607 Creating and Using JPA Repositories 610 Injecting the Persistence Unit 610 Implementing Standard CRUD Operations 611
Creating a Base Repository for All Your Entities 613 Demarking Transaction Boundaries in Your Services 618 Using the Transactional Service Methods 622 Converting Data with DTOs and Entities 624 Creating Entities for the Customer Support Application 624 Securing User Passwords with BCrypt 628 Transferring Data to Entities in Your Services 630 Summary 632 CHAPTER 22: ELIMINATING BOILERPLATE REPOSITORIES WITH SPRING DATA JPA 633 Understanding Spring Data's Unified Data Access 634 Avoiding Duplication of Code 634 Using the Stock Repository Interfaces 638 Creating Query Methods for Finding Entities 639 Providing Custom Method Implementations 642 Configuring and Creating Spring Data JPA Repositories 646 Enabling Repository Auto-Generation 646 Writing and Using Spring Data JPA Interfaces 654 Refactoring the Customer Support Application 656 Converting the Existing Repositories 656 Adding Comments to Support Tickets 657 Summary 661 CHAPTER 23: SEARCHING FOR DATA WITH JPA AND HIBERNATE SEARCH 663 An Introduction to Searching 664 Understanding the Importance of Indexes 664 Taking Three Different Approaches 666 Using Advanced Criteria to Locate Objects 666 Creating Complex Criteria Queries 667 Using OR in Your Queries 674 Creating Useful Indexes to Improve Performance 676, Taking Advantage of Full-Text Indexes with JPA 676 Creating Full-Text Indexes in MySQL Tables 677 Creating and Using a Searchable Repository 678 Making Full-Text Searching Portable 684 Indexing Any Data with Apache Lucene and Hibernate Search 684
Understanding Lucene Full-Text Indexing 685 Annotating Entities with Indexing Metadata 686 Using Hibernate Search with JPA 688 Summary 692 CHAPTER 24: CREATING ADVANCED MAPPINGS AND CUSTOM DATA TYPES 693 What's Left? 694 Converting Nonstandard Data Types 695 Understanding Attribute Converters 695 Understanding the Conversion Annotations 696 Creating and Using Attribute Converters 698 Embedding POJOs Within Entities 699 Indicating That a Type Is Embeddable 699 Marking a Property as Embedded 700 Overriding Embeddable Column Names 702 Defining Relationships Between Entities 703 Understanding One-to-One Relationships 703 Using One-to-Many and Many-to-One Relationships 705 Creating Many-to-Many Relationships 708 Addressing Other Common Situations 709 Versioning Entities with Revisions and Timestamps 709 Defining Abstract Entities with Common Properties 710 Mapping Basic and Embedded Collections 712 Persisting a Map of Key-Value Pairs 715 Storing an Entity in Multiple Tables 716 Creating Programmatic Triggers 717 Acting before and after CRUD Operations 717 Using Entity Listeners 719 Refining the Customer Support Application 720 Mapping a Collection of Attachments 721 Lazy Loading Simple Properties with Load Time Weaving 723 Summary 725 CHAPTER 25: INTRODUCING SPRING SECURITY 729 What Is Authentication? 729 Integrating Authentication 730 Understanding Authorization 740 Why Spring Security? 743
Understanding the Spring Security Foundation 744 Using Spring Security's Authorization Services 745 Configuring Spring Security 745 Summary 746 CHAPTER 26: AUTHENTICATING USERS WITH SPRING SECURITY 747 Choosing and Configuring an Authentication Provider 748 Configuring a User Details Provider 748 Working with LDAP and Active Directory Providers 759 Authenticating with OpenID 762 Remembering Users 765 Exploring Other Authentication Providers 766 Writing Your Own Authentication Provider 766 Bootstrapping in the Correct Order 767 Creating and Configuring a Provider 769 Mitigating Cross-Site Request Forgery Attacks 775 Summary 778 CHAPTER 27: USING AUTHORIZATION TAGS AND ANNOTATIONS 779 Authorizing by Declaration 780 Checking Permissions in Method Code 780 Employing URL Security 783 Using Annotations to Declare Permissions 786 Defining Method Pointcut Rules 794 Understanding Authorization Decisions 794 Using Access Decision Voters 795 Using Access Decision Managers 796 Creating Access Control Lists for Object Security 798 Understanding Spring Security ACLs 798 Configuring Access Control Lists 800 Populating ACLs for Your Entities 803 Adding Authorization to Customer Support 804 Switching to Custom User Details 804 Securing Your Service Methods 808 Using Spring Security's Tag Library 813 Summary 814 CHAPTER 28: SECURING RESTFUL WEB SERVICES WITH OAUTH 815 Understanding Web Service Security 816 Comparing Web GUI and Web Service Security 816
Choosing an Authentication Mechanism 817 Introducing OAuth 818 Understanding the Key Players 819 The Beginning: OAuth 1.0 819 The Standard: OAuth 1.0a 820 The Evolution: OAuth 2.0 826 Using Spring Security OAuth 833 Creating on OAuth 2.0 Provider 833 Creating an OAuth 2.0 Client 838 Finishing the Customer Support Application 840 Generating Request Nonces and Signatures 840 Implementing Client Services 842 Implementing Nonce Services 845 Implementing Token Services 847 Customizing the Resource Server Filter 850 Reconfiguring Spring Security 852 Creating an OAuth Client Application 856 Customizing the REST Template 857 Configuring the Spring Security OAuth Client 858 Using the REST Template 861 Testing the Provider and Client Together 861 Summary 862 INDEX 865 xxii