├── .github ├── actions │ └── send-notification │ │ └── action.yml ├── dco.yml └── workflows │ ├── build-pull-request.yml │ └── build.yml ├── .gitignore ├── .mvn └── wrapper │ └── maven-wrapper.properties ├── README.adoc ├── airline ├── README.adoc ├── client │ ├── airline.wsdl │ ├── axis │ │ ├── .mvn │ │ │ └── wrapper │ │ │ │ ├── maven-wrapper.jar │ │ │ │ └── maven-wrapper.properties │ │ ├── mvnw │ │ ├── mvnw.cmd │ │ ├── pom.xml │ │ ├── readme.txt │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── springframework │ │ │ │ └── ws │ │ │ │ └── samples │ │ │ │ └── airline │ │ │ │ └── client │ │ │ │ └── axis │ │ │ │ └── AxisMain.java │ │ │ └── resources │ │ │ └── log4j.properties │ ├── jax-ws │ │ ├── .mvn │ │ │ └── wrapper │ │ │ │ ├── maven-wrapper.jar │ │ │ │ └── maven-wrapper.properties │ │ ├── mvnw │ │ ├── mvnw.cmd │ │ ├── pom.xml │ │ ├── readme.txt │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── org │ │ │ └── springframework │ │ │ └── ws │ │ │ └── samples │ │ │ └── airline │ │ │ └── client │ │ │ └── jaxws │ │ │ └── JaxWsMain.java │ ├── jms │ │ ├── pom.xml │ │ ├── readme.txt │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── springframework │ │ │ │ └── ws │ │ │ │ └── samples │ │ │ │ └── airline │ │ │ │ └── client │ │ │ │ └── jms │ │ │ │ ├── JmsClient.java │ │ │ │ ├── JmsConfiguration.java │ │ │ │ └── JmsMain.java │ │ │ └── resources │ │ │ └── application.properties │ ├── saaj │ │ ├── pom.xml │ │ ├── readme.txt │ │ └── src │ │ │ └── main │ │ │ ├── java │ │ │ └── org │ │ │ │ └── springframework │ │ │ │ └── ws │ │ │ │ └── samples │ │ │ │ └── airline │ │ │ │ └── client │ │ │ │ └── saaj │ │ │ │ ├── GetFlights.java │ │ │ │ └── SaajMain.java │ │ │ └── resources │ │ │ └── application.properties │ └── spring-ws │ │ ├── pom.xml │ │ └── src │ │ ├── main │ │ ├── java │ │ │ └── org │ │ │ │ └── springframework │ │ │ │ └── ws │ │ │ │ └── samples │ │ │ │ └── airline │ │ │ │ └── client │ │ │ │ └── sws │ │ │ │ ├── GetFlights.java │ │ │ │ ├── GetFrequentFlyerMileage.java │ │ │ │ ├── SpringWsMain.java │ │ │ │ └── WsConfiguration.java │ │ └── resources │ │ │ └── log4j.properties │ │ └── test │ │ └── java │ │ └── org │ │ └── springframework │ │ └── ws │ │ └── samples │ │ └── airline │ │ └── client │ │ └── sws │ │ └── GetFlightsTest.java └── server │ ├── pom.xml │ └── src │ └── main │ ├── java │ └── org │ │ └── springframework │ │ └── ws │ │ └── samples │ │ └── airline │ │ ├── AirlineServerApplication.java │ │ ├── dao │ │ ├── AirportDao.java │ │ ├── Databaseinit.java │ │ ├── FlightDao.java │ │ ├── FrequentFlyerDao.java │ │ └── TicketDao.java │ │ ├── domain │ │ ├── Airport.java │ │ ├── Flight.java │ │ ├── FrequentFlyer.java │ │ ├── Passenger.java │ │ ├── ServiceClass.java │ │ └── Ticket.java │ │ ├── jms │ │ └── JmsConfiguration.java │ │ ├── schema │ │ └── support │ │ │ └── SchemaConversionUtils.java │ │ ├── security │ │ ├── FrequentFlyerDetails.java │ │ ├── FrequentFlyerSecurityService.java │ │ ├── SecurityConfiguration.java │ │ ├── SpringSecurityFrequentFlyerService.java │ │ └── StubFrequentFlyerSecurityService.java │ │ ├── service │ │ ├── AirlineService.java │ │ ├── NoSeatAvailableException.java │ │ ├── NoSuchFlightException.java │ │ ├── NoSuchFrequentFlyerException.java │ │ └── impl │ │ │ └── AirlineServiceImpl.java │ │ ├── web │ │ └── FlightsController.java │ │ └── ws │ │ ├── AirlineEndpoint.java │ │ ├── AirlineWebServiceConstants.java │ │ └── WebServicesConfiguration.java │ └── resources │ ├── application.properties │ ├── messages.xsd │ ├── templates │ ├── flight.html │ ├── flights.html │ └── noSuchFlight.html │ └── types.xsd ├── echo ├── README.adoc ├── client │ ├── saaj │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── org │ │ │ └── springframework │ │ │ └── ws │ │ │ └── samples │ │ │ └── echo │ │ │ └── client │ │ │ └── saaj │ │ │ ├── EchoClient.java │ │ │ └── SaajEchoClient.java │ └── spring-ws │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ ├── java │ │ └── org │ │ │ └── springframework │ │ │ └── ws │ │ │ └── samples │ │ │ └── echo │ │ │ └── client │ │ │ └── sws │ │ │ ├── EchoClient.java │ │ │ └── SpringWsEchoClient.java │ │ └── resources │ │ ├── application.yml │ │ └── echoRequest.xml └── server │ ├── pom.xml │ └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── springframework │ │ │ └── ws │ │ │ └── samples │ │ │ └── echo │ │ │ ├── EchoApplication.java │ │ │ ├── config │ │ │ └── EchoConfig.java │ │ │ ├── service │ │ │ ├── EchoService.java │ │ │ └── impl │ │ │ │ └── EchoServiceImpl.java │ │ │ └── ws │ │ │ └── EchoEndpoint.java │ ├── resources │ │ ├── application.yml │ │ └── echo.xsd │ └── webapp │ │ └── EMTPY │ └── test │ ├── java │ └── org │ │ └── springframework │ │ └── ws │ │ └── samples │ │ └── echo │ │ └── ws │ │ └── EchoEndpointTest.java │ └── resources │ └── log4j.properties ├── mtom ├── README.adoc ├── client │ └── spring-ws │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ ├── java │ │ └── org │ │ │ └── springframework │ │ │ └── ws │ │ │ └── samples │ │ │ └── mtom │ │ │ └── client │ │ │ └── sws │ │ │ ├── MtomClientConfig.java │ │ │ └── SaajMtomClient.java │ │ └── resources │ │ ├── application.yml │ │ └── spring-ws-logo.png └── server │ ├── pom.xml │ └── src │ └── main │ ├── java │ └── org │ │ └── springframework │ │ └── ws │ │ └── samples │ │ └── mtom │ │ ├── MtomServer.java │ │ ├── config │ │ └── MtomServerConfiguration.java │ │ ├── service │ │ ├── ContentRepository.java │ │ └── ContentRepositoryImpl.java │ │ └── ws │ │ └── ContentRepositoryEndpoint.java │ └── resources │ ├── application.yml │ └── contentStore.wsdl ├── mvnw ├── mvnw.cmd ├── pom.xml └── tutorial ├── README.adoc ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── mycompany │ │ └── hr │ │ ├── HrApplication.java │ │ ├── config │ │ └── HRConfiguration.java │ │ ├── service │ │ ├── HumanResourceService.java │ │ └── StubHumanResourceService.java │ │ └── ws │ │ └── HolidayEndpoint.java ├── resources │ ├── application.properties │ ├── hr.xsd │ └── log4j.properties └── webapp │ └── EMPTY └── test ├── java └── com │ └── mycompany │ └── hr │ └── ws │ └── HolidayEndpointTest.java └── resources └── com └── mycompany └── hr └── ws └── holidayRequest.xml /.github/actions/send-notification/action.yml: -------------------------------------------------------------------------------- 1 | name: Send notification 2 | description: Sends a Google Chat message as a notification of the job's outcome 3 | inputs: 4 | webhook-url: 5 | description: 'Google Chat Webhook URL' 6 | required: true 7 | status: 8 | description: 'Status of the job' 9 | required: true 10 | run-name: 11 | description: 'Name of the run to include in the notification' 12 | default: ${{ format('{0} {1}', github.ref_name, github.job) }} 13 | runs: 14 | using: composite 15 | steps: 16 | - shell: bash 17 | run: | 18 | echo "RUN_URL=${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> "$GITHUB_ENV" 19 | - shell: bash 20 | if: ${{ inputs.status == 'success' }} 21 | run: | 22 | curl -X POST '${{ inputs.webhook-url }}' -H 'Content-Type: application/json' -d '{ text: "<${{ env.RUN_URL }}|${{ inputs.run-name }}> was successful"}' || true 23 | - shell: bash 24 | if: ${{ inputs.status == 'failure' }} 25 | run: | 26 | curl -X POST '${{ inputs.webhook-url }}' -H 'Content-Type: application/json' -d '{ text: " *<${{ env.RUN_URL }}|${{ inputs.run-name }}> failed* "}' || true 27 | - shell: bash 28 | if: ${{ inputs.status == 'cancelled' }} 29 | run: | 30 | curl -X POST '${{ inputs.webhook-url }}' -H 'Content-Type: application/json' -d '{ text: "<${{ env.RUN_URL }}|${{ inputs.run-name }}> was cancelled"}' || true 31 | -------------------------------------------------------------------------------- /.github/dco.yml: -------------------------------------------------------------------------------- 1 | require: 2 | members: false 3 | -------------------------------------------------------------------------------- /.github/workflows/build-pull-request.yml: -------------------------------------------------------------------------------- 1 | name: Build Pull Request 2 | on: pull_request 3 | 4 | permissions: 5 | contents: read 6 | 7 | jobs: 8 | build: 9 | name: Build pull request 10 | runs-on: ubuntu-latest 11 | if: ${{ github.repository == 'spring-projects/spring-ws-samples' }} 12 | steps: 13 | - name: Check out 14 | uses: actions/checkout@v4 15 | - name: Set up JDK 17 16 | uses: actions/setup-java@v4 17 | with: 18 | java-version: '17' 19 | distribution: 'liberica' 20 | cache: 'maven' 21 | - name: Build with Maven 22 | run: ./mvnw --batch-mode --update-snapshots verify 23 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build Samples 2 | on: 3 | push: 4 | branches: 5 | - main 6 | concurrency: 7 | group: ${{ github.workflow }}-${{ github.ref }} 8 | jobs: 9 | build-samples: 10 | name: Build Samples 11 | if: ${{ github.repository == 'spring-projects/spring-ws-samples' }} 12 | runs-on: ubuntu-latest 13 | timeout-minutes: 60 14 | steps: 15 | - name: Check out 16 | uses: actions/checkout@v4 17 | - name: Set up JDK 17 18 | uses: actions/setup-java@v4 19 | with: 20 | java-version: '17' 21 | distribution: 'liberica' 22 | cache: 'maven' 23 | - name: Build 24 | run: ./mvnw --no-transfer-progress --batch-mode --update-snapshots verify 25 | - name: Send notification 26 | uses: ./.github/actions/send-notification 27 | if: always() 28 | with: 29 | webhook-url: ${{ secrets.GOOGLE_CHAT_WEBHOOK }} 30 | status: ${{ job.status }} 31 | run-name: ${{ format('Spring WS Samples | {0} | {1}', github.ref_name, matrix.runner.name) }} 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.ipr 2 | *.iws 3 | *.iml 4 | .clover 5 | activemq-data 6 | *.hsp 7 | atlassian-ide-plugin*.xml 8 | 9 | .idea 10 | 11 | /build 12 | /*/build 13 | /*/*/build 14 | /*/*/*/build 15 | .gradle 16 | 17 | target -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | wrapperVersion=3.3.2 2 | distributionType=only-script 3 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip 4 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | = Spring Web Services Samples 2 | 3 | https://spring.io/projects/spring-ws[Spring Web Services] is a product of the Spring community focused on creating 4 | document-driven, contract-first Web services. This repository contains sample 5 | projects illustrating usage of Spring Web Services. 6 | 7 | == Spring Boot 3.5.x + Spring WS 4.1.x 8 | 9 | This version of the samples focuses on Spring WS 4.1.x, the generation provided by Spring Boot 3.5 10 | For samples on Spring WS 4.0.x, check the `2.0.x` branch. 11 | 12 | == Sample Applications 13 | 14 | The following sample applications demonstrate the capabilities of https://spring.io/projects/spring-ws[Spring Web 15 | Services]. See the README within each sample project for more information and 16 | additional instructions. 17 | 18 | * link:./airline[airline] - a complete airline sample that shows both Web Service and 19 | O/X Mapping functionality in a complete application 20 | * link:./echo[echo] - a simple sample that shows a bare-bones Echo service 21 | * link:./mtom[mtom] - shows how to use MTOM and JAXB2 marshalling 22 | * link:./tutorial[tutorial] - contains the code from the Spring-WS tutorial 23 | 24 | == Running the Server 25 | 26 | Most of the sample apps can be built and run using the following commands from 27 | within the `server` folder. 28 | 29 | ---- 30 | $ ./mvnw spring-boot:run 31 | ---- 32 | 33 | Or alternatively, run the following to create runnable JAR file that will run anywhere there's a JDK: 34 | 35 | ---- 36 | $ ./mvnw package 37 | ---- 38 | 39 | == Running the Client(s) 40 | 41 | Most of the sample apps have a separate `client` directory containing clients 42 | that connect to the server. You can run these clients by using the following 43 | command from within each of client subdirectories: 44 | 45 | ---- 46 | $ ./mvnw spring-boot:run 47 | ---- 48 | 49 | == License 50 | 51 | https://projects.spring.io/spring-ws[Spring Web Services] is released under version 2.0 of the http://www.apache.org/licenses/LICENSE-2.0[Apache License]. 52 | -------------------------------------------------------------------------------- /airline/README.adoc: -------------------------------------------------------------------------------- 1 | = Airline Sample 2 | 3 | Features a web service on top of an airline reservation system, backed by a 4 | database. The web service works by using XML Marshalling techniques (JAXB2), 5 | and XPath in combination with XPath queries to pull information from a message. 6 | Additionally, the Airline service has JMS support. All messages follow the 7 | messages.xsd schema. 8 | 9 | == Build and deploy 10 | 11 | See the main link:../README.adoc[README] for build instructions. 12 | 13 | == License 14 | 15 | https://projects.spring.io/spring-ws[Spring Web Services] is released under version 2.0 of the http://www.apache.org/licenses/LICENSE-2.0[Apache License]. -------------------------------------------------------------------------------- /airline/client/axis/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects/spring-ws-samples/e22a7833d6408730b35dff808f56b51443c9c0fe/airline/client/axis/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /airline/client/axis/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip 2 | -------------------------------------------------------------------------------- /airline/client/axis/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.ws 8 | spring-ws-samples 9 | 2.1.0-SNAPSHOT 10 | ../../../pom.xml 11 | 12 | airline-client-axis 13 | Spring Web Services Samples - Airline - Client - Axis 14 | 15 | 16 | ${project.basedir}/target/generated-sources/axis 17 | ${project.basedir}/../airline.wsdl 18 | 19 | 20 | 21 | 22 | org.apache.axis2 23 | axis2-adb 24 | 25 | 26 | org.apache.axis2 27 | axis2-transport-local 28 | 29 | 30 | org.apache.axis2 31 | axis2-transport-http 32 | 33 | 34 | 35 | 36 | 37 | 38 | org.apache.axis2 39 | axis2-wsdl2code-maven-plugin 40 | 41 | 42 | wsdl2code 43 | 44 | wsdl2code 45 | 46 | 47 | 48 | 49 | true 50 | 51 | 52 | http://www.springframework.org/spring-ws/samples/airline/definitions 53 | org.springframework.ws.samples.airline.client.axis 54 | 55 | 56 | http://www.springframework.org/spring-ws/samples/airline/schemas/messages 57 | org.springframework.ws.samples.airline.client.axis 58 | 59 | 60 | http://www.springframework.org/spring-ws/samples/airline/schemas/types 61 | org.springframework.ws.samples.airline.client.axis 62 | 63 | 64 | ${generated-sources} 65 | ${wsdl} 66 | 67 | 68 | 69 | org.codehaus.mojo 70 | build-helper-maven-plugin 71 | 72 | 73 | add-source 74 | process-sources 75 | 76 | add-source 77 | 78 | 79 | 80 | ${generated-sources}/src 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /airline/client/axis/readme.txt: -------------------------------------------------------------------------------- 1 | SPRING WEB SERVICES 2 | 3 | This directory contains a Java client for the Airline Web Service that uses JAX-RPC. 4 | The client can be run from the provided ant file, by calling "ant run". 5 | 6 | SAJA Client Sample table of contents 7 | --------------------------------------------------- 8 | * src - The source files for the client 9 | * build.xml - Ant build file with a 'build' and a 'run' target 10 | 11 | -------------------------------------------------------------------------------- /airline/client/axis/src/main/java/org/springframework/ws/samples/airline/client/axis/AxisMain.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.client.axis; 18 | 19 | import java.rmi.RemoteException; 20 | import java.text.SimpleDateFormat; 21 | import java.util.Calendar; 22 | import java.util.Date; 23 | 24 | import org.springframework.ws.samples.airline.client.axis.AirlineServiceStub.AirportCode; 25 | import org.springframework.ws.samples.airline.client.axis.AirlineServiceStub.BookFlightRequest; 26 | import org.springframework.ws.samples.airline.client.axis.AirlineServiceStub.BookFlightResponse; 27 | import org.springframework.ws.samples.airline.client.axis.AirlineServiceStub.Flight; 28 | import org.springframework.ws.samples.airline.client.axis.AirlineServiceStub.FrequentFlyerUsername; 29 | import org.springframework.ws.samples.airline.client.axis.AirlineServiceStub.GetFlightsRequest; 30 | import org.springframework.ws.samples.airline.client.axis.AirlineServiceStub.GetFlightsResponse; 31 | import org.springframework.ws.samples.airline.client.axis.AirlineServiceStub.Name; 32 | import org.springframework.ws.samples.airline.client.axis.AirlineServiceStub.PassengersChoice; 33 | import org.springframework.ws.samples.airline.client.axis.AirlineServiceStub.Passengers_type0; 34 | import org.springframework.ws.samples.airline.client.axis.AirlineServiceStub.Ticket; 35 | 36 | /** 37 | * Simple client that calls the GetFlights and BookFlight 38 | * operations using Axis 2 and HTTP. 39 | * 40 | * @author Arjen Poutsma 41 | * @author Stephane Nicoll 42 | */ 43 | public class AxisMain { 44 | 45 | public static void main(String[] args) throws RemoteException { 46 | AirlineServiceStub airline = (args.length > 0) ? new AirlineServiceStub(args[0]) : new AirlineServiceStub(); 47 | GetFlightsRequest request = new GetFlightsRequest(); 48 | request.setFrom(createAirportCode("AMS")); 49 | request.setTo(createAirportCode("VCE")); 50 | Calendar departureCalendar = Calendar.getInstance(); 51 | departureCalendar.set(Calendar.YEAR, 2006); 52 | departureCalendar.set(Calendar.MONTH, Calendar.JANUARY); 53 | departureCalendar.set(Calendar.DATE, 31); 54 | Date departureDate = departureCalendar.getTime(); 55 | request.setDepartureDate(departureDate); 56 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 57 | System.out.println("Requesting flights on " + dateFormat.format(departureDate)); 58 | 59 | GetFlightsResponse flightsResponse = airline.getFlights(request); 60 | Flight[] flights = flightsResponse.getFlight(); 61 | 62 | System.out.println("Got " + flights.length + " results"); 63 | 64 | if (flights.length > 0) { 65 | // Book the first flight using John Doe as a frequent flyer 66 | BookFlightRequest bookFlightRequest = new BookFlightRequest(); 67 | bookFlightRequest.setFlightNumber(flights[0].getNumber()); 68 | bookFlightRequest.setDepartureTime(flights[0].getDepartureTime()); 69 | Passengers_type0 passengers = new Passengers_type0(); 70 | passengers.addPassengersChoice(createPassenger("john")); 71 | bookFlightRequest.setPassengers(passengers); 72 | BookFlightResponse bookFlightResponse = airline.bookFlight(bookFlightRequest); 73 | Ticket ticket = bookFlightResponse.getBookFlightResponse(); 74 | 75 | writeTicket(ticket); 76 | } 77 | } 78 | 79 | private static void writeTicket(Ticket ticket) { 80 | System.out.println("Ticket " + ticket.getId()); 81 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 82 | System.out.println("Ticket issue date:\t" + dateFormat.format(ticket.getIssueDate())); 83 | 84 | Name[] passengers = ticket.getPassengers().getPassenger(); 85 | for (Name passenger : passengers) { 86 | writeName(passenger); 87 | } 88 | writeFlight(ticket.getFlight()); 89 | } 90 | 91 | private static void writeName(Name name) { 92 | 93 | System.out.println("Passenger Name:"); 94 | System.out.println(name.getFirst() + " " + name.getLast()); 95 | System.out.println("------------"); 96 | } 97 | 98 | private static void writeFlight(Flight flight) { 99 | 100 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); 101 | System.out.println(dateFormat.format(flight.getDepartureTime().getTime())); 102 | System.out.println(flight.getNumber() + "\t" + flight.getServiceClass()); 103 | System.out.println("------------"); 104 | System.out.println("Depart:\t" + flight.getFrom().getCode() + "-" + flight.getFrom().getName() + "\t" 105 | + dateFormat.format(flight.getDepartureTime().getTime())); 106 | System.out.println("\t" + flight.getFrom().getCity()); 107 | System.out.println("Arrive:\t" + flight.getTo().getCode() + "-" + flight.getTo().getName() + "\t" 108 | + dateFormat.format(flight.getArrivalTime().getTime())); 109 | System.out.println("\t" + flight.getTo().getCity()); 110 | } 111 | 112 | private static AirportCode createAirportCode(String code) { 113 | AirportCode airportCode = new AirportCode(); 114 | airportCode.setAirportCode(code); 115 | return airportCode; 116 | } 117 | 118 | private static PassengersChoice createPassenger(String username) { 119 | PassengersChoice passenger = new PassengersChoice(); 120 | FrequentFlyerUsername frequentFlyerUsername = new FrequentFlyerUsername(); 121 | frequentFlyerUsername.setFrequentFlyerUsername(username); 122 | passenger.setUsername(frequentFlyerUsername); 123 | return passenger; 124 | } 125 | 126 | } 127 | -------------------------------------------------------------------------------- /airline/client/axis/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=WARN, stdout 2 | log4j.logger.org.springframework.ws=DEBUG 3 | 4 | 5 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 6 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n -------------------------------------------------------------------------------- /airline/client/jax-ws/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects/spring-ws-samples/e22a7833d6408730b35dff808f56b51443c9c0fe/airline/client/jax-ws/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /airline/client/jax-ws/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip 2 | -------------------------------------------------------------------------------- /airline/client/jax-ws/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.ws 8 | spring-ws-samples 9 | 2.1.0-SNAPSHOT 10 | ../../../pom.xml 11 | 12 | airline-client-jax-ws 13 | Spring Web Services Samples - Airline - Client - JAX-WS 14 | 15 | 16 | ${project.basedir}/target/generated-sources/jaxws 17 | ${project.basedir}/target/classes 18 | ${project.basedir}/../airline.wsdl 19 | 20 | 21 | 22 | 23 | org.springframework.ws 24 | spring-ws-core 25 | 26 | 27 | com.sun.xml.ws 28 | jaxws-tools 29 | 30 | 31 | jakarta.jws 32 | jakarta.jws-api 33 | 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-test 38 | test 39 | 40 | 41 | 42 | 43 | 44 | 45 | com.sun.xml.ws 46 | jaxws-maven-plugin 47 | 48 | 49 | 50 | wsimport 51 | 52 | 53 | 54 | 55 | 56 | ${project.basedir}/../airline.wsdl 57 | org.springframework.ws.samples.airline.client.jaxws 58 | ${sourcesDir} 59 | ${classesDir} 60 | true 61 | 62 | 63 | 64 | org.codehaus.mojo 65 | build-helper-maven-plugin 66 | 67 | 68 | add-source 69 | process-sources 70 | 71 | add-source 72 | 73 | 74 | 75 | ${sourcesDir} 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /airline/client/jax-ws/readme.txt: -------------------------------------------------------------------------------- 1 | SPRING WEB SERVICES 2 | 3 | This directory contains a Java client for the Airline Web Service that uses JAX-WS. 4 | The client can be run from the provided ant file, by calling "ant run". 5 | Note that the airline sample has to be running before invoking this target. 6 | 7 | Client Sample table of contents 8 | --------------------------------------------------- 9 | * src - The source files for the client 10 | * build.xml - Ant build file with a 'build' and a 'run' target 11 | 12 | -------------------------------------------------------------------------------- /airline/client/jax-ws/src/main/java/org/springframework/ws/samples/airline/client/jaxws/JaxWsMain.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.client.jaxws; 18 | 19 | import jakarta.xml.ws.soap.SOAPFaultException; 20 | 21 | import java.net.MalformedURLException; 22 | import java.net.URL; 23 | 24 | import javax.xml.datatype.DatatypeConfigurationException; 25 | import javax.xml.datatype.DatatypeConstants; 26 | import javax.xml.datatype.DatatypeFactory; 27 | import javax.xml.datatype.XMLGregorianCalendar; 28 | import javax.xml.namespace.QName; 29 | 30 | /** 31 | * Simple client that calls the GetFlights and BookFlight 32 | * operations using JAX-WS. 33 | * 34 | * @author Arjen Poutsma 35 | */ 36 | public class JaxWsMain { 37 | 38 | public static void main(String[] args) throws MalformedURLException, DatatypeConfigurationException { 39 | 40 | try { 41 | AirlineService service; 42 | 43 | if (args.length == 0) { 44 | service = new AirlineService(); 45 | } 46 | else { 47 | QName serviceName = new QName("http://www.springframework.org/spring-ws/samples/airline/definitions", 48 | "AirlineService"); 49 | service = new AirlineService(new URL(args[0]), serviceName); 50 | } 51 | 52 | Airline airline = service.getAirlineSoap11(); 53 | 54 | GetFlightsRequest request = new GetFlightsRequest(); 55 | request.setFrom("AMS"); 56 | request.setTo("VCE"); 57 | XMLGregorianCalendar departureDate = DatatypeFactory.newInstance() 58 | .newXMLGregorianCalendarDate(2006, 1, 31, DatatypeConstants.FIELD_UNDEFINED); 59 | request.setDepartureDate(departureDate); 60 | 61 | System.out.format("Requesting flights on %1tD%n", departureDate.toGregorianCalendar()); 62 | 63 | GetFlightsResponse response = airline.getFlights(request); 64 | 65 | System.out.format("Got %1d results%n", response.getFlight().size()); 66 | 67 | if (!response.getFlight().isEmpty()) { 68 | // Book the first flight using John Doe as a frequent flyer 69 | Flight flight = response.getFlight().get(0); 70 | BookFlightRequest bookFlightRequest = new BookFlightRequest(); 71 | bookFlightRequest.setFlightNumber(flight.getNumber()); 72 | bookFlightRequest.setDepartureTime(flight.getDepartureTime()); 73 | BookFlightRequest.Passengers passengers = new BookFlightRequest.Passengers(); 74 | passengers.getPassengerOrUsername().add("john"); 75 | bookFlightRequest.setPassengers(passengers); 76 | Ticket ticket = airline.bookFlight(bookFlightRequest); 77 | writeTicket(ticket); 78 | } 79 | 80 | } 81 | catch (SOAPFaultException ex) { 82 | System.out.format("SOAP Fault Code %1s%n", ex.getFault().getFaultCodeAsQName()); 83 | System.out.format("SOAP Fault String: %1s%n", ex.getFault().getFaultString()); 84 | } 85 | } 86 | 87 | private static void writeTicket(Ticket ticket) { 88 | 89 | System.out.format("Ticket %1d%n", ticket.getId()); 90 | System.out.format("Ticket issue date:\t%1tD%n", ticket.getIssueDate().toGregorianCalendar()); 91 | 92 | for (Name passenger : ticket.getPassengers().getPassenger()) { 93 | writeName(passenger); 94 | } 95 | 96 | writeFlight(ticket.flight); 97 | } 98 | 99 | private static void writeName(Name name) { 100 | 101 | System.out.format("Passenger Name:%n"); 102 | System.out.format("%1s %2s%n", name.getFirst(), name.getLast()); 103 | System.out.format("------------%n"); 104 | } 105 | 106 | private static void writeFlight(Flight flight) { 107 | 108 | System.out.format("%1tD%n", flight.getDepartureTime().toGregorianCalendar()); 109 | System.out.format("%1s\t%2s%n", flight.getNumber(), flight.getServiceClass()); 110 | System.out.format("------------%n"); 111 | System.out.format("Depart:\t%1s-%2s\t%tR%n", flight.getFrom().getCode(), flight.getFrom().getName(), 112 | flight.getDepartureTime().toGregorianCalendar()); 113 | System.out.format("\t%1s%n", flight.getFrom().getCity()); 114 | System.out.format("Arrive:\t%1s-%2s\t%tR%n", flight.getTo().getCode(), flight.getTo().getName(), 115 | flight.getArrivalTime().toGregorianCalendar()); 116 | System.out.format("\t%1s%n", flight.getTo().getCity()); 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /airline/client/jms/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.ws 8 | spring-ws-samples 9 | 2.1.0-SNAPSHOT 10 | ../../../pom.xml 11 | 12 | airline-client-jms 13 | Spring Web Services Samples - Airline - Client - JMS 14 | 15 | 16 | ${project.basedir}/target/generated-sources/jaxws 17 | ${project.basedir}/target/classes 18 | ${project.basedir}/../airline.wsdl 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-artemis 25 | 26 | 27 | 28 | org.springframework.ws 29 | spring-ws-core 30 | 31 | 32 | org.springframework.ws 33 | spring-ws-support 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /airline/client/jms/readme.txt: -------------------------------------------------------------------------------- 1 | SPRING WEB SERVICES 2 | 3 | This directory contains a client for the Airline Web Service that uses JMS: Java Message Service. The client can be run 4 | from the provided ant file, by calling "ant run". 5 | 6 | JMS Client Sample table of contents 7 | --------------------------------------------------- 8 | * src - The source files for the client 9 | * build.xml - Ant build file with a 'build' and a 'run' target 10 | 11 | -------------------------------------------------------------------------------- /airline/client/jms/src/main/java/org/springframework/ws/samples/airline/client/jms/JmsClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.client.jms; 18 | 19 | import javax.xml.transform.stream.StreamResult; 20 | 21 | import org.springframework.ws.client.core.support.WebServiceGatewaySupport; 22 | import org.springframework.xml.transform.StringSource; 23 | 24 | /** 25 | * @author Arjen Poutsma 26 | */ 27 | public class JmsClient extends WebServiceGatewaySupport { 28 | 29 | private static final String PAYLOAD = "" 30 | + "AMS" + "VCE" 31 | + "2006-01-31" + ""; 32 | 33 | public void getFlights() { 34 | getWebServiceTemplate().sendSourceAndReceiveToResult(new StringSource(PAYLOAD), new StreamResult(System.out)); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /airline/client/jms/src/main/java/org/springframework/ws/samples/airline/client/jms/JmsConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.client.jms; 18 | 19 | import jakarta.jms.ConnectionFactory; 20 | 21 | import org.springframework.context.annotation.Bean; 22 | import org.springframework.context.annotation.Configuration; 23 | import org.springframework.ws.transport.jms.JmsMessageSender; 24 | 25 | /** 26 | * Java configuration for setting up a JMS-based client. 27 | * 28 | * @author Greg Turnquist 29 | */ 30 | @Configuration(proxyBeanMethods = false) 31 | public class JmsConfiguration { 32 | 33 | @Bean 34 | JmsMessageSender jmsMessageSender(ConnectionFactory connectionFactory) { 35 | return new JmsMessageSender(connectionFactory); 36 | } 37 | 38 | @Bean 39 | JmsClient jmsClient(JmsMessageSender messageSender) { 40 | 41 | JmsClient jmsClient = new JmsClient(); 42 | jmsClient.setDefaultUri("jms:RequestQueue"); 43 | jmsClient.setMessageSender(messageSender); 44 | return jmsClient; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /airline/client/jms/src/main/java/org/springframework/ws/samples/airline/client/jms/JmsMain.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.client.jms; 18 | 19 | import org.springframework.boot.CommandLineRunner; 20 | import org.springframework.boot.SpringApplication; 21 | import org.springframework.boot.autoconfigure.SpringBootApplication; 22 | import org.springframework.context.annotation.Bean; 23 | 24 | /** 25 | * "Main" that creates a {@link JmsClient} and uses it to talk to the SOAP-based server. 26 | * 27 | * @author Greg Turnquist 28 | */ 29 | @SpringBootApplication 30 | public class JmsMain { 31 | 32 | public static void main(String[] args) { 33 | SpringApplication.run(JmsMain.class); 34 | } 35 | 36 | @Bean 37 | CommandLineRunner getFlights(JmsClient client) { 38 | return args -> { 39 | client.getFlights(); 40 | }; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /airline/client/jms/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.org.springframework.jms=DEBUG 2 | logging.level.org.springframework.ws=DEBUG 3 | #logging.level.org.apache.activemq=DEBUG 4 | -------------------------------------------------------------------------------- /airline/client/saaj/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.ws 8 | spring-ws-samples 9 | 2.1.0-SNAPSHOT 10 | ../../../pom.xml 11 | 12 | airline-client-saaj 13 | 0.0.1-SNAPSHOT 14 | Spring Web Services Samples - Airline - Client - SAAJ 15 | 16 | 17 | 18 | org.springframework.boot 19 | spring-boot-starter 20 | 21 | 22 | com.sun.xml.messaging.saaj 23 | saaj-impl 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /airline/client/saaj/readme.txt: -------------------------------------------------------------------------------- 1 | SPRING WEB SERVICES 2 | 3 | This directory contains two Java clients for the Airline Web Service that use SAAJ: SOAP with Attachments API for Java. 4 | There is a client for the GetFlights operation and a client for the secure GetFrequentFlyerMileage operation. Both 5 | clients can be run from the provided ant file, by calling "ant run". 6 | 7 | SAJA Client Sample table of contents 8 | --------------------------------------------------- 9 | * src - The source files for the client 10 | * build.xml - Ant build file with a 'build' and a 'run' target 11 | 12 | -------------------------------------------------------------------------------- /airline/client/saaj/src/main/java/org/springframework/ws/samples/airline/client/saaj/GetFlights.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.client.saaj; 18 | 19 | import jakarta.xml.soap.*; 20 | 21 | import java.io.IOException; 22 | import java.net.MalformedURLException; 23 | import java.net.URL; 24 | import java.util.Iterator; 25 | 26 | import javax.xml.transform.OutputKeys; 27 | import javax.xml.transform.Transformer; 28 | import javax.xml.transform.TransformerException; 29 | import javax.xml.transform.TransformerFactory; 30 | import javax.xml.transform.dom.DOMSource; 31 | import javax.xml.transform.stream.StreamResult; 32 | 33 | /** 34 | * Simple client that calls the GetFlights operation using SAAJ. 35 | * 36 | * @author Arjen Poutsma 37 | */ 38 | public class GetFlights { 39 | 40 | public static final String NAMESPACE_URI = "http://www.springframework.org/spring-ws/samples/airline/schemas/messages"; 41 | 42 | public static final String PREFIX = "airline"; 43 | 44 | private SOAPConnectionFactory connectionFactory; 45 | 46 | private MessageFactory messageFactory; 47 | 48 | private URL url; 49 | 50 | private TransformerFactory transfomerFactory; 51 | 52 | public GetFlights(String url) throws SOAPException, MalformedURLException { 53 | connectionFactory = SOAPConnectionFactory.newInstance(); 54 | messageFactory = MessageFactory.newInstance(); 55 | transfomerFactory = TransformerFactory.newInstance(); 56 | this.url = new URL(url); 57 | } 58 | 59 | private SOAPMessage createGetFlightsRequest() throws SOAPException { 60 | SOAPMessage message = messageFactory.createMessage(); 61 | SOAPEnvelope envelope = message.getSOAPPart().getEnvelope(); 62 | Name getFlightsRequestName = envelope.createName("GetFlightsRequest", PREFIX, NAMESPACE_URI); 63 | SOAPBodyElement getFlightsRequestElement = message.getSOAPBody().addBodyElement(getFlightsRequestName); 64 | Name fromName = envelope.createName("from", PREFIX, NAMESPACE_URI); 65 | SOAPElement fromElement = getFlightsRequestElement.addChildElement(fromName); 66 | fromElement.setValue("AMS"); 67 | Name toName = envelope.createName("to", PREFIX, NAMESPACE_URI); 68 | SOAPElement toElement = getFlightsRequestElement.addChildElement(toName); 69 | toElement.setValue("VCE"); 70 | Name departureDateName = envelope.createName("departureDate", PREFIX, NAMESPACE_URI); 71 | SOAPElement departureDateElement = getFlightsRequestElement.addChildElement(departureDateName); 72 | departureDateElement.setValue("2006-01-31"); 73 | return message; 74 | } 75 | 76 | public void getFlights() throws SOAPException, IOException, TransformerException { 77 | SOAPMessage request = createGetFlightsRequest(); 78 | SOAPConnection connection = connectionFactory.createConnection(); 79 | SOAPMessage response = connection.call(request, url); 80 | if (!response.getSOAPBody().hasFault()) { 81 | writeGetFlightsResponse(response); 82 | } 83 | else { 84 | SOAPFault fault = response.getSOAPBody().getFault(); 85 | System.err.println("Received SOAP Fault"); 86 | System.err.println("SOAP Fault Code: " + fault.getFaultCode()); 87 | System.err.println("SOAP Fault String: " + fault.getFaultString()); 88 | } 89 | } 90 | 91 | private void writeGetFlightsResponse(SOAPMessage message) throws SOAPException, TransformerException { 92 | SOAPEnvelope envelope = message.getSOAPPart().getEnvelope(); 93 | Name getFlightsResponseName = envelope.createName("GetFlightsResponse", PREFIX, NAMESPACE_URI); 94 | SOAPBodyElement getFlightsResponseElement = (SOAPBodyElement) message.getSOAPBody() 95 | .getChildElements(getFlightsResponseName) 96 | .next(); 97 | Name flightName = envelope.createName("flight", PREFIX, NAMESPACE_URI); 98 | Iterator iterator = getFlightsResponseElement.getChildElements(flightName); 99 | Transformer transformer = transfomerFactory.newTransformer(); 100 | transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 101 | transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 102 | int count = 1; 103 | while (iterator.hasNext()) { 104 | System.out.println("Flight " + count); 105 | System.out.println("--------"); 106 | SOAPElement flightElement = (SOAPElement) iterator.next(); 107 | DOMSource source = new DOMSource(flightElement); 108 | transformer.transform(source, new StreamResult(System.out)); 109 | } 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /airline/client/saaj/src/main/java/org/springframework/ws/samples/airline/client/saaj/SaajMain.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.client.saaj; 18 | 19 | import org.slf4j.Logger; 20 | import org.slf4j.LoggerFactory; 21 | 22 | /** 23 | * @author Arjen Poutsma 24 | */ 25 | public class SaajMain { 26 | 27 | private static final Logger logger = LoggerFactory.getLogger(SaajMain.class); 28 | 29 | public static void main(String[] args) throws Exception { 30 | 31 | String url = "http://localhost:8080/airline-server/services"; 32 | if (args.length > 0) { 33 | url = args[0]; 34 | } 35 | 36 | logger.info("Connecting to " + url + " for flight details..."); 37 | 38 | GetFlights getFlights = new GetFlights(url); 39 | getFlights.getFlights(); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /airline/client/saaj/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.org.springframework.ws=TRACE 2 | logging.level.javax.xml.soap=TRACE 3 | logging.level.com.sun.xml=TRACE 4 | logging.level.javax.security.auth=TRACE 5 | -------------------------------------------------------------------------------- /airline/client/spring-ws/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.ws 8 | spring-ws-samples 9 | 2.1.0-SNAPSHOT 10 | ../../../pom.xml 11 | 12 | airline-client-spring-ws 13 | Spring Web Services Samples - Airline - Client - Spring WS 14 | 15 | 16 | ${project.basedir}/target/generated-sources/xjc 17 | ${project.basedir}/target/classes 18 | ${project.basedir}/../../server/src/main/resources 19 | file://${project.basedir}/../airline.wsdl 20 | 21 | 22 | 23 | 24 | org.springframework.ws 25 | spring-ws-core 26 | 27 | 28 | org.springframework.ws 29 | spring-ws-security 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-test 35 | test 36 | 37 | 38 | org.springframework.ws 39 | spring-ws-test 40 | test 41 | 42 | 43 | 44 | 45 | 46 | 47 | com.evolvedbinary.maven.jvnet 48 | jaxb30-maven-plugin 49 | 50 | 51 | 52 | generate 53 | 54 | 55 | 56 | 57 | WSDL 58 | org.springframework.springWs.samples.airline.schemas 59 | 60 | 61 | ${wsdl} 62 | 63 | 64 | true 65 | 66 | 67 | 68 | org.codehaus.mojo 69 | build-helper-maven-plugin 70 | 71 | 72 | add-source 73 | process-sources 74 | 75 | add-source 76 | 77 | 78 | 79 | ${sourcesDir} 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /airline/client/spring-ws/src/main/java/org/springframework/ws/samples/airline/client/sws/GetFlights.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.client.sws; 18 | 19 | import jakarta.xml.bind.JAXBElement; 20 | 21 | import javax.xml.datatype.DatatypeConfigurationException; 22 | import javax.xml.datatype.DatatypeConstants; 23 | import javax.xml.datatype.DatatypeFactory; 24 | import javax.xml.datatype.XMLGregorianCalendar; 25 | 26 | import org.springframework.springWs.samples.airline.schemas.*; 27 | import org.springframework.ws.WebServiceMessageFactory; 28 | import org.springframework.ws.client.core.support.WebServiceGatewaySupport; 29 | 30 | public class GetFlights extends WebServiceGatewaySupport { 31 | 32 | public GetFlights(WebServiceMessageFactory messageFactory) { 33 | super(messageFactory); 34 | } 35 | 36 | public void getFlights() { 37 | 38 | GetFlightsRequest getFlightsRequest = new GetFlightsRequest(); 39 | getFlightsRequest.setFrom("AMS"); 40 | getFlightsRequest.setTo("VCE"); 41 | XMLGregorianCalendar departureDate = null; 42 | try { 43 | departureDate = DatatypeFactory.newInstance() 44 | .newXMLGregorianCalendarDate(2006, 1, 31, DatatypeConstants.FIELD_UNDEFINED); 45 | } 46 | catch (DatatypeConfigurationException e) { 47 | throw new RuntimeException(e); 48 | } 49 | 50 | getFlightsRequest.setDepartureDate(departureDate); 51 | 52 | System.out.println("Requesting flights on " + departureDate); 53 | GetFlightsResponse response = null; 54 | try { 55 | response = (GetFlightsResponse) getWebServiceTemplate().marshalSendAndReceive(getFlightsRequest); 56 | } 57 | catch (Exception e) { 58 | throw new RuntimeException(e); 59 | } 60 | System.out.println("Got " + response.getFlight().size() + " results"); 61 | if (response.getFlight().size() > 0) { 62 | // Book the first flight using John Doe as a frequent flyer 63 | BookFlightRequest bookFlightRequest = new BookFlightRequest(); 64 | bookFlightRequest.setFlightNumber(response.getFlight().get(0).getNumber()); 65 | bookFlightRequest.setDepartureTime(response.getFlight().get(0).getDepartureTime()); 66 | BookFlightRequest.Passengers passengers = new BookFlightRequest.Passengers(); 67 | passengers.getPassengerOrUsername().add("john"); 68 | bookFlightRequest.setPassengers(passengers); 69 | 70 | JAXBElement ticket = (JAXBElement) getWebServiceTemplate() 71 | .marshalSendAndReceive(bookFlightRequest); 72 | 73 | writeTicket(ticket.getValue()); 74 | } 75 | } 76 | 77 | private void writeTicket(Ticket ticket) { 78 | 79 | System.out.println("Ticket " + ticket.getId()); 80 | System.out.println("Ticket issue date:\t" + ticket.getIssueDate()); 81 | ticket.getPassengers().getPassenger().forEach(this::writeName); 82 | writeFlight(ticket.getFlight()); 83 | } 84 | 85 | private void writeName(Name name) { 86 | 87 | System.out.println("Passenger Name:"); 88 | System.out.println(name.getFirst() + " " + name.getLast()); 89 | System.out.println("------------"); 90 | } 91 | 92 | private void writeFlight(Flight flight) { 93 | 94 | System.out.println(flight.getDepartureTime()); 95 | System.out.println(flight.getNumber() + "\t" + flight.getServiceClass()); 96 | System.out.println("------------"); 97 | System.out.println("Depart:\t" + flight.getFrom().getCode() + "-" + flight.getFrom().getName() + "\t" 98 | + flight.getDepartureTime()); 99 | System.out.println("\t" + flight.getFrom().getCity()); 100 | System.out.println("Arrive:\t" + flight.getTo().getCode() + "-" + flight.getTo().getName() + "\t" 101 | + flight.getArrivalTime()); 102 | System.out.println("\t" + flight.getTo().getCity()); 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /airline/client/spring-ws/src/main/java/org/springframework/ws/samples/airline/client/sws/GetFrequentFlyerMileage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.client.sws; 18 | 19 | import javax.xml.transform.Source; 20 | import javax.xml.transform.stream.StreamResult; 21 | 22 | import org.springframework.ws.WebServiceMessageFactory; 23 | import org.springframework.ws.client.core.support.WebServiceGatewaySupport; 24 | import org.springframework.xml.transform.StringSource; 25 | 26 | public class GetFrequentFlyerMileage extends WebServiceGatewaySupport { 27 | 28 | public GetFrequentFlyerMileage(WebServiceMessageFactory messageFactory) { 29 | super(messageFactory); 30 | } 31 | 32 | public void getFrequentFlyerMileage() { 33 | 34 | Source source = new StringSource( 35 | ""); 36 | 37 | getWebServiceTemplate().sendSourceAndReceiveToResult(source, new StreamResult(System.out)); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /airline/client/spring-ws/src/main/java/org/springframework/ws/samples/airline/client/sws/SpringWsMain.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.client.sws; 18 | 19 | import org.springframework.context.annotation.AnnotationConfigApplicationContext; 20 | 21 | /** 22 | * @author Arjen Poutsma 23 | */ 24 | public class SpringWsMain { 25 | 26 | public static void main(String[] args) { 27 | 28 | AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(WsConfiguration.class); 29 | 30 | GetFlights getFlights = ctx.getBean(GetFlights.class); 31 | getFlights.getFlights(); 32 | 33 | GetFrequentFlyerMileage getFrequentFlyerMileage = ctx.getBean(GetFrequentFlyerMileage.class); 34 | getFrequentFlyerMileage.getFrequentFlyerMileage(); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /airline/client/spring-ws/src/main/java/org/springframework/ws/samples/airline/client/sws/WsConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.client.sws; 18 | 19 | import org.springframework.context.annotation.Bean; 20 | import org.springframework.context.annotation.Configuration; 21 | import org.springframework.oxm.jaxb.Jaxb2Marshaller; 22 | import org.springframework.ws.client.support.interceptor.ClientInterceptor; 23 | import org.springframework.ws.soap.SoapMessageFactory; 24 | import org.springframework.ws.soap.saaj.SaajSoapMessageFactory; 25 | import org.springframework.ws.soap.security.wss4j2.Wss4jSecurityInterceptor; 26 | 27 | @Configuration(proxyBeanMethods = false) 28 | public class WsConfiguration { 29 | 30 | @Bean 31 | SoapMessageFactory messageFactory() { 32 | return new SaajSoapMessageFactory(); 33 | } 34 | 35 | @Bean 36 | Jaxb2Marshaller marshaller() { 37 | 38 | Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); 39 | marshaller.setPackagesToScan("org.springframework.springWs.samples.airline.schemas"); 40 | return marshaller; 41 | } 42 | 43 | @Bean 44 | GetFlights getFlights(SoapMessageFactory messageFactory, Jaxb2Marshaller marshaller, 45 | Wss4jSecurityInterceptor securityInterceptor) { 46 | 47 | GetFlights getFlights = new GetFlights(messageFactory); 48 | getFlights.setDefaultUri("http://localhost:8080/airline-server/services"); 49 | getFlights.setMarshaller(marshaller); 50 | getFlights.setUnmarshaller(marshaller); 51 | return getFlights; 52 | } 53 | 54 | @Bean 55 | GetFrequentFlyerMileage getFrequentFlyerMileage(SoapMessageFactory messageFactory, Jaxb2Marshaller marshaller, 56 | Wss4jSecurityInterceptor securityInterceptor) { 57 | 58 | GetFrequentFlyerMileage getFrequentFlyerMileage = new GetFrequentFlyerMileage(messageFactory); 59 | getFrequentFlyerMileage.setDefaultUri("http://localhost:8080/airline-server/services"); 60 | getFrequentFlyerMileage.setMarshaller(marshaller); 61 | getFrequentFlyerMileage.setUnmarshaller(marshaller); 62 | getFrequentFlyerMileage.setInterceptors(new ClientInterceptor[] { securityInterceptor }); 63 | return getFrequentFlyerMileage; 64 | } 65 | 66 | @Bean 67 | Wss4jSecurityInterceptor securityInterceptor() { 68 | 69 | Wss4jSecurityInterceptor securityInterceptor = new Wss4jSecurityInterceptor(); 70 | securityInterceptor.setSecurementActions("UsernameToken"); 71 | securityInterceptor.setSecurementUsername("john"); 72 | securityInterceptor.setSecurementPassword("changeme"); 73 | return securityInterceptor; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /airline/client/spring-ws/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=WARN, stdout 2 | log4j.logger.org.springframework.ws=DEBUG 3 | log4j.logger.org.springframework.xml=DEBUG 4 | 5 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 6 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 7 | log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n -------------------------------------------------------------------------------- /airline/client/spring-ws/src/test/java/org/springframework/ws/samples/airline/client/sws/GetFlightsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.client.sws; 18 | 19 | import static org.springframework.ws.test.client.RequestMatchers.*; 20 | import static org.springframework.ws.test.client.ResponseCreators.*; 21 | 22 | import java.util.Collections; 23 | import java.util.Map; 24 | 25 | import javax.xml.transform.Source; 26 | 27 | import org.junit.jupiter.api.BeforeEach; 28 | import org.junit.jupiter.api.Test; 29 | import org.junit.jupiter.api.extension.ExtendWith; 30 | import org.springframework.beans.factory.annotation.Autowired; 31 | import org.springframework.context.annotation.Import; 32 | import org.springframework.test.context.junit.jupiter.SpringExtension; 33 | import org.springframework.ws.test.client.MockWebServiceServer; 34 | import org.springframework.xml.transform.StringSource; 35 | 36 | /** 37 | * This test illustrates the use of the client-side testing API, introduced in Spring-WS 38 | * 2.0. 39 | * 40 | * @author Arjen Poutsma 41 | */ 42 | @ExtendWith(SpringExtension.class) 43 | @Import(WsConfiguration.class) 44 | public class GetFlightsTest { 45 | 46 | @Autowired 47 | GetFlights getFlights; 48 | 49 | private MockWebServiceServer mockServer; 50 | 51 | private static final String MESSAGES_NS = "http://www.springframework.org/spring-ws/samples/airline/schemas/messages"; 52 | 53 | private static final String TYPES_NS = "http://www.springframework.org/spring-ws/samples/airline/schemas/types"; 54 | 55 | @BeforeEach 56 | public void setUpMocks() { 57 | mockServer = MockWebServiceServer.createServer(getFlights); 58 | } 59 | 60 | @Test 61 | public void getFlights() { 62 | 63 | Source getFlightsRequest = new StringSource( 64 | "" + "AMS" + "VCE" 65 | + "2006-01-31" + ""); 66 | 67 | String flightInfo = "KL1653" 68 | + "2006-01-31T10:05:00.000+01:00" 69 | + "AMSSchiphol AirportAmsterdam" 70 | + "2006-01-31T12:25:00.000+01:00" 71 | + "VCEMarco Polo AirportVenice" 72 | + "economy"; 73 | 74 | Source getFlightsResponse = new StringSource("" + "" + flightInfo + "" + ""); 76 | 77 | mockServer.expect(payload(getFlightsRequest)).andRespond(withPayload(getFlightsResponse)); 78 | 79 | Source bookFlightResponse = new StringSource("" + "4" + "2010-07-28" 81 | + "JohnDoe" 82 | + "" + flightInfo + "" + ""); 83 | 84 | Map namespaces = Collections.singletonMap("m", MESSAGES_NS); 85 | 86 | mockServer.expect(xpath("/m:BookFlightRequest/m:flightNumber", namespaces).exists()) 87 | .andExpect(xpath("/m:BookFlightRequest/m:departureTime", namespaces).exists()) 88 | .andExpect(xpath("/m:BookFlightRequest/m:passengers", namespaces).exists()) 89 | .andRespond(withPayload(bookFlightResponse)); 90 | 91 | getFlights.getFlights(); 92 | 93 | mockServer.verify(); 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /airline/server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.ws 8 | spring-ws-samples 9 | 2.1.0-SNAPSHOT 10 | ../../pom.xml 11 | 12 | airline-server 13 | Spring Web Services Samples - Airline - Server 14 | 15 | 16 | ${project.basedir}/target/generated-sources/axis 17 | ${project.basedir}/target/classes 18 | ${project.basedir}/../airline.wsdl 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-artemis 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-data-jpa 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter-security 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-thymeleaf 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-web 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-starter-web-services 45 | 46 | 47 | org.springframework.ws 48 | spring-ws-security 49 | 50 | 51 | org.springframework.ws 52 | spring-ws-support 53 | 54 | 55 | org.apache.activemq 56 | artemis-jakarta-server 57 | 58 | 59 | wsdl4j 60 | wsdl4j 61 | 62 | 63 | 64 | com.h2database 65 | h2 66 | runtime 67 | 68 | 69 | org.apache.ws.xmlschema 70 | xmlschema-core 71 | runtime 72 | 73 | 74 | 75 | org.springframework.boot 76 | spring-boot-starter-test 77 | test 78 | 79 | 80 | 81 | 82 | 83 | 84 | org.springframework.boot 85 | spring-boot-maven-plugin 86 | 87 | 88 | org.codehaus.mojo 89 | jaxb2-maven-plugin 90 | 91 | 92 | xjc 93 | 94 | xjc 95 | 96 | 97 | 98 | 99 | ${project.basedir}/src/main/resources/messages.xsd 100 | org.springframework.ws.samples.airline.schema 101 | 3.0 102 | 103 | 104 | 105 | org.codehaus.mojo 106 | build-helper-maven-plugin 107 | 108 | 109 | add-source 110 | process-sources 111 | 112 | add-source 113 | 114 | 115 | 116 | target/generated-sources/xjc 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/AirlineServerApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline; 18 | 19 | import org.springframework.boot.SpringApplication; 20 | import org.springframework.boot.autoconfigure.SpringBootApplication; 21 | import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; 22 | 23 | @SpringBootApplication(exclude = SecurityAutoConfiguration.class) 24 | public class AirlineServerApplication { 25 | 26 | public static void main(String[] args) { 27 | SpringApplication.run(AirlineServerApplication.class, args); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/dao/AirportDao.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.dao; 18 | 19 | import org.springframework.data.repository.CrudRepository; 20 | import org.springframework.ws.samples.airline.domain.Airport; 21 | 22 | public interface AirportDao extends CrudRepository { 23 | 24 | } 25 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/dao/Databaseinit.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.dao; 18 | 19 | import java.time.ZoneId; 20 | import java.time.ZonedDateTime; 21 | 22 | import org.springframework.boot.CommandLineRunner; 23 | import org.springframework.context.annotation.Bean; 24 | import org.springframework.context.annotation.Configuration; 25 | import org.springframework.ws.samples.airline.domain.Airport; 26 | import org.springframework.ws.samples.airline.domain.Flight; 27 | import org.springframework.ws.samples.airline.domain.FrequentFlyer; 28 | import org.springframework.ws.samples.airline.domain.ServiceClass; 29 | 30 | @Configuration 31 | public class Databaseinit { 32 | 33 | @Bean 34 | CommandLineRunner initializeDatabase(AirportDao airportDao, FlightDao flightDao, 35 | FrequentFlyerDao frequentFlyerDao) { 36 | return args -> { 37 | Airport amsterdam = airportDao.save(new Airport("AMS", "Schiphol Airport", "Amsterdam")); 38 | Airport venice = airportDao.save(new Airport("VCE", "Marco Polo Airport", "Venice")); 39 | Airport rotterdam = airportDao.save(new Airport("RTM", "Rotterdam Airport", "Rotterdam")); 40 | Airport gardermoen = airportDao.save(new Airport("OSL", "Gardermoen", "Oslo")); 41 | 42 | Flight flight = new Flight(); 43 | flight.setNumber("KL1653"); 44 | flight.setDepartureTime(ZonedDateTime.of(2006, 1, 31, 10, 5, 0, 0, ZoneId.systemDefault())); 45 | flight.setFrom(amsterdam); 46 | flight.setArrivalTime(ZonedDateTime.of(2006, 1, 31, 12, 25, 0, 0, ZoneId.systemDefault())); 47 | flight.setTo(venice); 48 | flight.setServiceClass(ServiceClass.ECONOMY); 49 | flight.setSeatsAvailable(5); 50 | flight.setMiles(200); 51 | 52 | flightDao.save(flight); 53 | 54 | flight = new Flight(); 55 | flight.setNumber("KL1654"); 56 | flight.setDepartureTime(ZonedDateTime.of(2006, 2, 5, 12, 40, 0, 0, ZoneId.systemDefault())); 57 | flight.setFrom(venice); 58 | flight.setArrivalTime(ZonedDateTime.of(2006, 2, 5, 14, 15, 0, 0, ZoneId.systemDefault())); 59 | flight.setTo(amsterdam); 60 | flight.setServiceClass(ServiceClass.ECONOMY); 61 | flight.setSeatsAvailable(5); 62 | flight.setMiles(200); 63 | 64 | flightDao.save(flight); 65 | 66 | frequentFlyerDao.save(new FrequentFlyer("John", "Doe", "john", "changeme")); 67 | }; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/dao/FlightDao.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.ws.samples.airline.dao; 17 | 18 | import java.time.ZonedDateTime; 19 | import java.util.List; 20 | 21 | import org.springframework.data.jpa.repository.Query; 22 | import org.springframework.data.repository.CrudRepository; 23 | import org.springframework.data.repository.query.Param; 24 | import org.springframework.ws.samples.airline.domain.Flight; 25 | import org.springframework.ws.samples.airline.domain.ServiceClass; 26 | 27 | public interface FlightDao extends CrudRepository { 28 | 29 | @Query("SELECT f FROM Flight f WHERE f.from.code = :fromAirportCode " 30 | + "AND f.to.code = :toAirportCode AND f.departureTime >= :#{#date} AND f.departureTime <= :#{#date.plusDays(1)} AND " 31 | + "f.serviceClass = :class") 32 | List findFlights(@Param("fromAirportCode") String fromAirportCode, // 33 | @Param("toAirportCode") String toAirportCode, // 34 | @Param("date") ZonedDateTime date, // 35 | @Param("class") ServiceClass serviceClass); 36 | 37 | Flight findFlightByNumberAndDepartureTime(String flightNumber, ZonedDateTime departureTime); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/dao/FrequentFlyerDao.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.dao; 18 | 19 | import java.util.Optional; 20 | 21 | import org.springframework.data.repository.CrudRepository; 22 | import org.springframework.ws.samples.airline.domain.FrequentFlyer; 23 | 24 | public interface FrequentFlyerDao extends CrudRepository { 25 | 26 | Optional findByUsername(String username); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/dao/TicketDao.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.dao; 18 | 19 | import org.springframework.data.repository.CrudRepository; 20 | import org.springframework.ws.samples.airline.domain.Ticket; 21 | 22 | public interface TicketDao extends CrudRepository { 23 | 24 | } 25 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/domain/Airport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.domain; 18 | 19 | import jakarta.persistence.Column; 20 | import jakarta.persistence.Entity; 21 | import jakarta.persistence.Id; 22 | import jakarta.persistence.Table; 23 | 24 | import java.io.Serializable; 25 | 26 | @Entity 27 | @Table(name = "AIRPORT") 28 | public class Airport implements Serializable { 29 | 30 | @Id 31 | @Column(name = "CODE") 32 | private String code; 33 | 34 | @Column(name = "NAME") 35 | private String name; 36 | 37 | @Column(name = "CITY") 38 | private String city; 39 | 40 | public Airport() { 41 | } 42 | 43 | public Airport(String code, String name, String city) { 44 | this.code = code; 45 | this.name = name; 46 | this.city = city; 47 | } 48 | 49 | public String getCity() { 50 | return city; 51 | } 52 | 53 | public String getCode() { 54 | return code; 55 | } 56 | 57 | public String getName() { 58 | return name; 59 | } 60 | 61 | public boolean equals(Object other) { 62 | if (this == other) { 63 | return true; 64 | } 65 | if (!(other instanceof Airport)) { 66 | return false; 67 | } 68 | final Airport that = (Airport) other; 69 | return code.equals(that.code); 70 | } 71 | 72 | public int hashCode() { 73 | return code.hashCode(); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/domain/Flight.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.ws.samples.airline.domain; 17 | 18 | import jakarta.persistence.*; 19 | 20 | import java.io.Serializable; 21 | import java.time.ZonedDateTime; 22 | 23 | import org.springframework.data.annotation.Persistent; 24 | 25 | @Entity 26 | @Table(name = "FLIGHT") 27 | public class Flight implements Serializable { 28 | 29 | @Id 30 | @Column(name = "ID") 31 | @GeneratedValue(strategy = GenerationType.IDENTITY) 32 | private Long id; 33 | 34 | @Column(name = "NUMBER") 35 | private String number; 36 | 37 | @Column(name = "DEPARTURE_TIME") 38 | @Persistent 39 | private ZonedDateTime departureTime; 40 | 41 | @ManyToOne 42 | @JoinColumn(name = "FROM_AIRPORT_CODE", nullable = false) 43 | private Airport from; 44 | 45 | @Column(name = "ARRIVAL_TIME") 46 | @Persistent 47 | private ZonedDateTime arrivalTime; 48 | 49 | @ManyToOne 50 | @JoinColumn(name = "TO_AIRPORT_CODE", nullable = false) 51 | private Airport to; 52 | 53 | @Column(name = "SERVICE_CLASS") 54 | @Enumerated(EnumType.STRING) 55 | private ServiceClass serviceClass; 56 | 57 | @Column(name = "SEATS_AVAILABLE") 58 | private int seatsAvailable; 59 | 60 | @Column(name = "MILES") 61 | private int miles; 62 | 63 | public Flight() { 64 | } 65 | 66 | public Flight(Long id) { 67 | this.id = id; 68 | } 69 | 70 | public Long getId() { 71 | return id; 72 | } 73 | 74 | public ZonedDateTime getArrivalTime() { 75 | return arrivalTime; 76 | } 77 | 78 | public void setArrivalTime(ZonedDateTime arrivalTime) { 79 | this.arrivalTime = arrivalTime; 80 | } 81 | 82 | public ZonedDateTime getDepartureTime() { 83 | return departureTime; 84 | } 85 | 86 | public void setDepartureTime(ZonedDateTime departureTime) { 87 | this.departureTime = departureTime; 88 | } 89 | 90 | public Airport getFrom() { 91 | return from; 92 | } 93 | 94 | public void setFrom(Airport from) { 95 | this.from = from; 96 | } 97 | 98 | public int getMiles() { 99 | return miles; 100 | } 101 | 102 | public void setMiles(int miles) { 103 | this.miles = miles; 104 | } 105 | 106 | public String getNumber() { 107 | return number; 108 | } 109 | 110 | public void setNumber(String number) { 111 | this.number = number; 112 | } 113 | 114 | public int getSeatsAvailable() { 115 | return seatsAvailable; 116 | } 117 | 118 | public void setSeatsAvailable(int seatsAvailable) { 119 | this.seatsAvailable = seatsAvailable; 120 | } 121 | 122 | public ServiceClass getServiceClass() { 123 | return serviceClass; 124 | } 125 | 126 | public void setServiceClass(ServiceClass serviceClass) { 127 | this.serviceClass = serviceClass; 128 | } 129 | 130 | public Airport getTo() { 131 | return to; 132 | } 133 | 134 | public void setTo(Airport to) { 135 | this.to = to; 136 | } 137 | 138 | public void substractSeats(int count) { 139 | seatsAvailable -= count; 140 | } 141 | 142 | public boolean equals(Object o) { 143 | if (this == o) { 144 | return true; 145 | } 146 | if (o == null || getClass() != o.getClass()) { 147 | return false; 148 | } 149 | 150 | final Flight flight = (Flight) o; 151 | 152 | if (!departureTime.equals(flight.departureTime)) { 153 | return false; 154 | } 155 | return number.equals(flight.number); 156 | } 157 | 158 | public int hashCode() { 159 | int result = number.hashCode(); 160 | result = 29 * result + departureTime.hashCode(); 161 | return result; 162 | } 163 | 164 | public String toString() { 165 | return getNumber() + " " + getDepartureTime(); 166 | } 167 | 168 | } 169 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/domain/FrequentFlyer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.domain; 18 | 19 | import jakarta.persistence.Column; 20 | import jakarta.persistence.Entity; 21 | import jakarta.persistence.PrimaryKeyJoinColumn; 22 | import jakarta.persistence.Table; 23 | 24 | @Entity 25 | @Table(name = "FREQUENT_FLYER") 26 | @PrimaryKeyJoinColumn(name = "PASSENGER_ID") 27 | public class FrequentFlyer extends Passenger { 28 | 29 | @Column(name = "USERNAME") 30 | private String username; 31 | 32 | @Column(name = "PASSWORD") 33 | private String password; 34 | 35 | @Column(name = "MILES") 36 | private int miles; 37 | 38 | public FrequentFlyer() { 39 | } 40 | 41 | public FrequentFlyer(String username) { 42 | this.username = username; 43 | } 44 | 45 | public FrequentFlyer(String firstName, String lastName, String username, String password) { 46 | 47 | super(firstName, lastName); 48 | this.username = username; 49 | this.password = password; 50 | } 51 | 52 | public int getMiles() { 53 | return miles; 54 | } 55 | 56 | public void setMiles(int miles) { 57 | this.miles = miles; 58 | } 59 | 60 | public String getPassword() { 61 | return password; 62 | } 63 | 64 | public void setPassword(String password) { 65 | this.password = password; 66 | } 67 | 68 | public String getUsername() { 69 | return username; 70 | } 71 | 72 | public void setUsername(String username) { 73 | this.username = username; 74 | } 75 | 76 | public boolean equals(Object other) { 77 | 78 | if (this == other) { 79 | return true; 80 | } 81 | if (!(other instanceof FrequentFlyer)) { 82 | return false; 83 | } 84 | final FrequentFlyer that = (FrequentFlyer) other; 85 | return username.equals(that.username); 86 | } 87 | 88 | public int hashCode() { 89 | return username.hashCode(); 90 | } 91 | 92 | @Override 93 | public String toString() { 94 | return "FrequentFlyer{" + "username='" + username + '\'' + ", password='" + password + '\'' + ", miles=" + miles 95 | + '}'; 96 | } 97 | 98 | public void addMiles(int miles) { 99 | this.miles += miles; 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/domain/Passenger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.ws.samples.airline.domain; 17 | 18 | import jakarta.persistence.*; 19 | 20 | import java.io.Serializable; 21 | 22 | @Entity 23 | @Table(name = "PASSENGER") 24 | @Inheritance(strategy = InheritanceType.JOINED) 25 | public class Passenger implements Serializable { 26 | 27 | @Id 28 | @GeneratedValue(strategy = GenerationType.IDENTITY) 29 | @Column(name = "ID") 30 | private Long id; 31 | 32 | @Column(name = "FIRST_NAME") 33 | private String firstName; 34 | 35 | @Column(name = "LAST_NAME") 36 | private String lastName; 37 | 38 | public Passenger() { 39 | } 40 | 41 | public Passenger(String firstName, String lastName) { 42 | this.firstName = firstName; 43 | this.lastName = lastName; 44 | } 45 | 46 | public Passenger(Long id, String firstName, String lastName) { 47 | this.id = id; 48 | this.firstName = firstName; 49 | this.lastName = lastName; 50 | } 51 | 52 | public String getFirstName() { 53 | return firstName; 54 | } 55 | 56 | public Long getId() { 57 | return id; 58 | } 59 | 60 | public String getLastName() { 61 | return lastName; 62 | } 63 | 64 | public String toString() { 65 | return firstName + " " + lastName; 66 | } 67 | 68 | public boolean equals(Object o) { 69 | if (this == o) { 70 | return true; 71 | } 72 | if (o == null || getClass() != o.getClass()) { 73 | return false; 74 | } 75 | 76 | final Passenger passenger = (Passenger) o; 77 | 78 | if (!getFirstName().equals(passenger.getFirstName())) { 79 | return false; 80 | } 81 | if (!getLastName().equals(passenger.getLastName())) { 82 | return false; 83 | } 84 | 85 | return true; 86 | } 87 | 88 | public int hashCode() { 89 | int result = getFirstName().hashCode(); 90 | result = 29 * result + getLastName().hashCode(); 91 | return result; 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/domain/ServiceClass.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.domain; 18 | 19 | public enum ServiceClass { 20 | 21 | ECONOMY, 22 | 23 | BUSINESS, 24 | 25 | FIRST 26 | 27 | } 28 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/domain/Ticket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.domain; 18 | 19 | import jakarta.persistence.*; 20 | 21 | import java.io.Serializable; 22 | import java.time.LocalDate; 23 | import java.util.HashSet; 24 | import java.util.Set; 25 | 26 | import org.springframework.data.annotation.Persistent; 27 | 28 | @Entity 29 | @Table(name = "TICKET") 30 | public class Ticket implements Serializable { 31 | 32 | @Id 33 | @GeneratedValue(strategy = GenerationType.IDENTITY) 34 | private Long id; 35 | 36 | @Column(name = "ISSUE_DATE") 37 | @Persistent 38 | private LocalDate issueDate; 39 | 40 | @ManyToOne 41 | @JoinColumn(name = "FLIGHT_ID", nullable = false) 42 | private Flight flight; 43 | 44 | @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }) 45 | @JoinTable(name = "PASSENGER_TICKET", joinColumns = @JoinColumn(name = "TICKET_ID"), 46 | inverseJoinColumns = @JoinColumn(name = "PASSENGER_ID")) 47 | private Set passengers = new HashSet(); 48 | 49 | public Ticket() { 50 | } 51 | 52 | public Ticket(Long id) { 53 | this.id = id; 54 | } 55 | 56 | public Long getId() { 57 | return id; 58 | } 59 | 60 | public Flight getFlight() { 61 | return flight; 62 | } 63 | 64 | public void setFlight(Flight flight) { 65 | this.flight = flight; 66 | } 67 | 68 | public LocalDate getIssueDate() { 69 | return issueDate; 70 | } 71 | 72 | public void setIssueDate(LocalDate issueDate) { 73 | this.issueDate = issueDate; 74 | } 75 | 76 | public Set getPassengers() { 77 | return passengers; 78 | } 79 | 80 | public void setPassengers(Set passengers) { 81 | this.passengers = passengers; 82 | } 83 | 84 | public void addPassenger(Passenger passenger) { 85 | passengers.add(passenger); 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/jms/JmsConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.jms; 18 | 19 | import jakarta.jms.ConnectionFactory; 20 | 21 | import org.apache.activemq.artemis.api.core.TransportConfiguration; 22 | import org.apache.activemq.artemis.core.remoting.impl.netty.NettyAcceptorFactory; 23 | import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory; 24 | import org.apache.activemq.artemis.jms.client.ActiveMQQueue; 25 | import org.springframework.boot.autoconfigure.jms.artemis.ArtemisConfigurationCustomizer; 26 | import org.springframework.context.annotation.Bean; 27 | import org.springframework.context.annotation.Configuration; 28 | import org.springframework.jms.listener.DefaultMessageListenerContainer; 29 | import org.springframework.ws.WebServiceMessageFactory; 30 | import org.springframework.ws.transport.WebServiceMessageReceiver; 31 | import org.springframework.ws.transport.jms.WebServiceMessageListener; 32 | 33 | @Configuration 34 | public class JmsConfiguration { 35 | 36 | /** 37 | * Make embedded ActiveMQ broker open to tcp connections. 38 | */ 39 | @Bean 40 | ArtemisConfigurationCustomizer customizer() { 41 | return configuration -> { 42 | configuration.addConnectorConfiguration("nettyConnector", 43 | new TransportConfiguration(NettyConnectorFactory.class.getName())); 44 | configuration.addAcceptorConfiguration(new TransportConfiguration(NettyAcceptorFactory.class.getName())); 45 | }; 46 | } 47 | 48 | /** 49 | * Listen for JMS messages and route them into the SOAP-based 50 | * {@link WebServiceMessageListener}. 51 | */ 52 | @Bean 53 | DefaultMessageListenerContainer containerFactory(ConnectionFactory connectionFactory, 54 | WebServiceMessageListener messageListener) { 55 | 56 | DefaultMessageListenerContainer container = new DefaultMessageListenerContainer(); 57 | container.setConnectionFactory(connectionFactory); 58 | container.setDestination(new ActiveMQQueue("RequestQueue")); 59 | container.setMessageListener(messageListener); 60 | return container; 61 | } 62 | 63 | @Bean 64 | WebServiceMessageListener messageListener(WebServiceMessageFactory messageFactory, 65 | WebServiceMessageReceiver messageReceiver) { 66 | 67 | WebServiceMessageListener messageListener = new WebServiceMessageListener(); 68 | messageListener.setMessageFactory(messageFactory); 69 | messageListener.setMessageReceiver(messageReceiver); 70 | return messageListener; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/security/FrequentFlyerDetails.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.security; 18 | 19 | import java.util.Collection; 20 | import java.util.List; 21 | 22 | import org.springframework.security.core.GrantedAuthority; 23 | import org.springframework.security.core.authority.SimpleGrantedAuthority; 24 | import org.springframework.security.core.userdetails.UserDetails; 25 | import org.springframework.ws.samples.airline.domain.FrequentFlyer; 26 | 27 | public class FrequentFlyerDetails implements UserDetails { 28 | 29 | private static final List GRANTED_AUTHORITIES = List 30 | .of(new SimpleGrantedAuthority("ROLE_FREQUENT_FLYER")); 31 | 32 | private FrequentFlyer frequentFlyer; 33 | 34 | public FrequentFlyerDetails(FrequentFlyer frequentFlyer) { 35 | this.frequentFlyer = frequentFlyer; 36 | } 37 | 38 | public FrequentFlyer getFrequentFlyer() { 39 | return frequentFlyer; 40 | } 41 | 42 | @Override 43 | public Collection getAuthorities() { 44 | return GRANTED_AUTHORITIES; 45 | } 46 | 47 | @Override 48 | public String getUsername() { 49 | return frequentFlyer.getUsername(); 50 | } 51 | 52 | @Override 53 | public String getPassword() { 54 | return frequentFlyer.getPassword(); 55 | } 56 | 57 | @Override 58 | public boolean isAccountNonExpired() { 59 | return true; 60 | } 61 | 62 | @Override 63 | public boolean isAccountNonLocked() { 64 | return true; 65 | } 66 | 67 | @Override 68 | public boolean isCredentialsNonExpired() { 69 | return true; 70 | } 71 | 72 | @Override 73 | public boolean isEnabled() { 74 | return true; 75 | } 76 | 77 | @Override 78 | public String toString() { 79 | return "FrequentFlyerDetails{" + "frequentFlyer=" + frequentFlyer + '}'; 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/security/FrequentFlyerSecurityService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.security; 18 | 19 | import org.springframework.ws.samples.airline.domain.FrequentFlyer; 20 | import org.springframework.ws.samples.airline.service.NoSuchFrequentFlyerException; 21 | 22 | /** 23 | * Defines the business logic for handling frequent flyers. 24 | * 25 | * @author Arjen Poutsma 26 | */ 27 | public interface FrequentFlyerSecurityService { 28 | 29 | /** 30 | * Returns the FrequentFlyer with the given username. 31 | * @param username the username 32 | * @return the frequent flyer with the given username, or null if not 33 | * found 34 | * @throws NoSuchFrequentFlyerException when the frequent flyer cannot be found 35 | */ 36 | FrequentFlyer getFrequentFlyer(String username) throws NoSuchFrequentFlyerException; 37 | 38 | /** 39 | * Returns the FrequentFlyer that is currently logged in. 40 | * @return the frequent flyer that is currently logged in, or null if not 41 | * found 42 | */ 43 | FrequentFlyer getCurrentlyAuthenticatedFrequentFlyer(); 44 | 45 | } 46 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/security/SecurityConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.security; 18 | 19 | import org.springframework.context.annotation.Bean; 20 | import org.springframework.context.annotation.Configuration; 21 | import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; 22 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 23 | import org.springframework.security.crypto.password.NoOpPasswordEncoder; 24 | import org.springframework.security.crypto.password.PasswordEncoder; 25 | import org.springframework.security.web.SecurityFilterChain; 26 | import org.springframework.ws.samples.airline.dao.FrequentFlyerDao; 27 | 28 | @Configuration(proxyBeanMethods = false) 29 | @EnableMethodSecurity 30 | public class SecurityConfiguration { 31 | 32 | @Bean 33 | SpringSecurityFrequentFlyerService userDetailsService(FrequentFlyerDao frequentFlyerDao) { 34 | return new SpringSecurityFrequentFlyerService(frequentFlyerDao); 35 | } 36 | 37 | @Bean 38 | PasswordEncoder passwordEncoder() { 39 | return NoOpPasswordEncoder.getInstance(); 40 | } 41 | 42 | // @Bean 43 | // SecurityFilterChain securityFilterChain(HttpSecurity security) throws Exception { 44 | // 45 | // security.authorizeHttpRequests() // 46 | // .requestMatchers("/login", "/error", "/logout").permitAll() // 47 | // .anyRequest().authenticated() // 48 | // .and() // 49 | // .csrf().disable(); 50 | // 51 | // return security.build(); 52 | // } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/security/SpringSecurityFrequentFlyerService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.security; 18 | 19 | import org.apache.wss4j.common.principal.UsernameTokenPrincipal; 20 | import org.slf4j.Logger; 21 | import org.slf4j.LoggerFactory; 22 | import org.springframework.security.core.Authentication; 23 | import org.springframework.security.core.context.SecurityContextHolder; 24 | import org.springframework.security.core.userdetails.UserDetails; 25 | import org.springframework.security.core.userdetails.UserDetailsService; 26 | import org.springframework.security.core.userdetails.UsernameNotFoundException; 27 | import org.springframework.transaction.annotation.Transactional; 28 | import org.springframework.ws.samples.airline.dao.FrequentFlyerDao; 29 | import org.springframework.ws.samples.airline.domain.FrequentFlyer; 30 | import org.springframework.ws.samples.airline.service.NoSuchFrequentFlyerException; 31 | 32 | /** 33 | * Implementation of the {@link FrequentFlyerSecurityService} that uses Spring Security. 34 | * 35 | * @author Arjen Poutsma 36 | */ 37 | public class SpringSecurityFrequentFlyerService implements FrequentFlyerSecurityService, UserDetailsService { 38 | 39 | private static final Logger log = LoggerFactory.getLogger(SpringSecurityFrequentFlyerService.class); 40 | 41 | private final FrequentFlyerDao frequentFlyerDao; 42 | 43 | public SpringSecurityFrequentFlyerService(FrequentFlyerDao frequentFlyerDao) { 44 | this.frequentFlyerDao = frequentFlyerDao; 45 | } 46 | 47 | @Override 48 | @Transactional 49 | public FrequentFlyer getFrequentFlyer(String username) throws NoSuchFrequentFlyerException { 50 | return frequentFlyerDao.findByUsername(username) // 51 | .orElseThrow(() -> new NoSuchFrequentFlyerException(username)); 52 | } 53 | 54 | @Override 55 | @Transactional 56 | public FrequentFlyer getCurrentlyAuthenticatedFrequentFlyer() { 57 | Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); 58 | 59 | if (authentication != null) { 60 | UsernameTokenPrincipal principal = (UsernameTokenPrincipal) authentication.getPrincipal(); 61 | FrequentFlyerDetails frequentFlyerDetails = (FrequentFlyerDetails) loadUserByUsername(principal.getName()); 62 | return frequentFlyerDetails.getFrequentFlyer(); 63 | } 64 | 65 | return null; 66 | } 67 | 68 | @Override 69 | @Transactional 70 | public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 71 | log.debug("Looking up " + username); 72 | 73 | FrequentFlyerDetails details = frequentFlyerDao.findByUsername(username) // 74 | .map(FrequentFlyerDetails::new) // 75 | .orElseThrow(() -> new UsernameNotFoundException("Frequent flyer '" + username + "' not found")); 76 | 77 | log.debug("Found " + details); 78 | 79 | return details; 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/security/StubFrequentFlyerSecurityService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.security; 18 | 19 | import org.springframework.ws.samples.airline.domain.FrequentFlyer; 20 | import org.springframework.ws.samples.airline.service.NoSuchFrequentFlyerException; 21 | 22 | /** 23 | * Stub implementation of FrequentFlyerSecurityService. This implementation 24 | * is used by default by 25 | * {@link org.springframework.ws.samples.airline.service.impl.AirlineServiceImpl}, to 26 | * allow it to run without depending on Spring Security. 27 | * 28 | * @author Arjen Poutsma 29 | */ 30 | public class StubFrequentFlyerSecurityService implements FrequentFlyerSecurityService { 31 | 32 | private FrequentFlyer john; 33 | 34 | public StubFrequentFlyerSecurityService() { 35 | this.john = new FrequentFlyer("John", "Doe", "john", "changeme"); 36 | john.setMiles(10); 37 | } 38 | 39 | @Override 40 | public FrequentFlyer getFrequentFlyer(String username) throws NoSuchFrequentFlyerException { 41 | if (john.getUsername().equals(username)) { 42 | return john; 43 | } 44 | else { 45 | throw new NoSuchFrequentFlyerException(username); 46 | } 47 | } 48 | 49 | @Override 50 | public FrequentFlyer getCurrentlyAuthenticatedFrequentFlyer() { 51 | return john; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/service/AirlineService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.ws.samples.airline.service; 17 | 18 | import java.time.ZonedDateTime; 19 | import java.util.List; 20 | 21 | import org.springframework.ws.samples.airline.domain.*; 22 | 23 | /** 24 | * Defines the business logic of the Airline application. 25 | * 26 | * @author Arjen Poutsma 27 | */ 28 | public interface AirlineService { 29 | 30 | /** 31 | * Returns a single Flight with the given id. 32 | * @param id the flight identifier 33 | * @return the flight 34 | * @throws NoSuchFlightException if a flight with the specified flight iddoes not 35 | * exist 36 | */ 37 | Flight getFlight(Long id) throws NoSuchFlightException; 38 | 39 | /** 40 | * Returns a list of Flight objects that fall within the specified 41 | * criteria. 42 | * @param fromAirportCode the three-letter airport code to get flights from 43 | * @param toAirportCode the three-letter airport code to get flights to 44 | * @param departureDate the date of the flights 45 | * @param serviceClass the desired service class level. May be null 46 | * @return a list of flights 47 | */ 48 | List getFlights(String fromAirportCode, String toAirportCode, ZonedDateTime departureDate, 49 | ServiceClass serviceClass); 50 | 51 | /** 52 | * Books a single flight for a number of passengers. Passengers can be either 53 | * specified by name or by frequent flyer username. If a {@link FrequentFlyer} is 54 | * specified, the first and last name are looked up in the database. 55 | * @param flightNumber the number of the flight to book 56 | * @param departureTime the departure time of the flight to book 57 | * @param passengers the list of passengers for the flight to book. Can be either 58 | * {@link Passenger} objects with a first and last name, or {@link FrequentFlyer} 59 | * objects with a username. 60 | * @return the created ticket 61 | * @throws NoSuchFlightException if a flight with the specified flight number and 62 | * departure time does not exist 63 | * @throws NoSeatAvailableException if not enough seats are available for the flight 64 | * @throws NoSuchFrequentFlyerException if a specified {@link FrequentFlyer} cannot be 65 | * found 66 | * @see Passenger 67 | * @see FrequentFlyer 68 | */ 69 | Ticket bookFlight(String flightNumber, ZonedDateTime departureTime, List passengers) 70 | throws NoSuchFlightException, NoSeatAvailableException, NoSuchFrequentFlyerException; 71 | 72 | /** 73 | * Returns the amount of frequent flyer award miles for the currently logged in 74 | * frequent flyer. 75 | * @return the amount of frequent flyer miles 76 | */ 77 | int getFrequentFlyerMileage(); 78 | 79 | } 80 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/service/NoSeatAvailableException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.service; 18 | 19 | import org.springframework.ws.samples.airline.domain.Flight; 20 | import org.springframework.ws.soap.server.endpoint.annotation.FaultCode; 21 | import org.springframework.ws.soap.server.endpoint.annotation.SoapFault; 22 | 23 | /** 24 | * Exception thrown when not enough seats are available for a flight. 25 | * 26 | * @author Arjen Poutsma 27 | */ 28 | @SoapFault(faultCode = FaultCode.SERVER) 29 | public class NoSeatAvailableException extends Exception { 30 | 31 | private Flight flight; 32 | 33 | public NoSeatAvailableException(Flight flight) { 34 | super("Flight [" + flight + "] has not more seats available"); 35 | this.flight = flight; 36 | } 37 | 38 | public Flight getFlight() { 39 | return flight; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/service/NoSuchFlightException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.service; 18 | 19 | import java.time.ZonedDateTime; 20 | 21 | import org.springframework.ws.soap.server.endpoint.annotation.FaultCode; 22 | import org.springframework.ws.soap.server.endpoint.annotation.SoapFault; 23 | 24 | /** 25 | * Exception thrown when a specified flight cannot be found. 26 | * 27 | * @author Arjen Poutsma 28 | */ 29 | @SoapFault(faultCode = FaultCode.CLIENT) 30 | public class NoSuchFlightException extends Exception { 31 | 32 | private String flightNumber; 33 | 34 | private ZonedDateTime departureTime; 35 | 36 | public NoSuchFlightException(String flightNumber, ZonedDateTime departureTime) { 37 | super("No flight with number [" + flightNumber + "] and departure time [" + departureTime + "]"); 38 | this.flightNumber = flightNumber; 39 | this.departureTime = departureTime; 40 | } 41 | 42 | public NoSuchFlightException(Long id) { 43 | super("No flight with id [" + id + "]"); 44 | } 45 | 46 | public String getFlightNumber() { 47 | return flightNumber; 48 | } 49 | 50 | public ZonedDateTime getDepartureTime() { 51 | return departureTime; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/service/NoSuchFrequentFlyerException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.service; 18 | 19 | import org.springframework.ws.soap.server.endpoint.annotation.FaultCode; 20 | import org.springframework.ws.soap.server.endpoint.annotation.SoapFault; 21 | 22 | /** 23 | * Exception thrown when a specified frequent flyer cannot be found. 24 | * 25 | * @author Rossen Stoyanchev 26 | * @author Arjen Poutsma 27 | */ 28 | @SoapFault(faultCode = FaultCode.CLIENT) 29 | public class NoSuchFrequentFlyerException extends Exception { 30 | 31 | private String username; 32 | 33 | public NoSuchFrequentFlyerException(String username) { 34 | super("No frequent flyer with name [" + username + "]"); 35 | this.username = username; 36 | } 37 | 38 | public String getusername() { 39 | return username; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/service/impl/AirlineServiceImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.ws.samples.airline.service.impl; 17 | 18 | import java.time.LocalDate; 19 | import java.time.ZonedDateTime; 20 | import java.util.List; 21 | import java.util.Optional; 22 | 23 | import org.apache.commons.logging.Log; 24 | import org.apache.commons.logging.LogFactory; 25 | import org.springframework.beans.factory.annotation.Autowired; 26 | import org.springframework.security.access.prepost.PreAuthorize; 27 | import org.springframework.stereotype.Service; 28 | import org.springframework.transaction.annotation.Transactional; 29 | import org.springframework.util.Assert; 30 | import org.springframework.ws.samples.airline.dao.FlightDao; 31 | import org.springframework.ws.samples.airline.dao.TicketDao; 32 | import org.springframework.ws.samples.airline.domain.*; 33 | import org.springframework.ws.samples.airline.security.FrequentFlyerSecurityService; 34 | import org.springframework.ws.samples.airline.security.StubFrequentFlyerSecurityService; 35 | import org.springframework.ws.samples.airline.service.AirlineService; 36 | import org.springframework.ws.samples.airline.service.NoSeatAvailableException; 37 | import org.springframework.ws.samples.airline.service.NoSuchFlightException; 38 | import org.springframework.ws.samples.airline.service.NoSuchFrequentFlyerException; 39 | 40 | /** 41 | * Default implementation of the AirlineService interface. 42 | * 43 | * @author Arjen Poutsma 44 | */ 45 | @Service 46 | @Transactional(readOnly = true) 47 | public class AirlineServiceImpl implements AirlineService { 48 | 49 | private static final Log logger = LogFactory.getLog(AirlineServiceImpl.class); 50 | 51 | private FlightDao flightDao; 52 | 53 | private TicketDao ticketDao; 54 | 55 | private FrequentFlyerSecurityService frequentFlyerSecurityService = new StubFrequentFlyerSecurityService(); 56 | 57 | public AirlineServiceImpl(FlightDao flightDao, TicketDao ticketDao) { 58 | 59 | this.flightDao = flightDao; 60 | this.ticketDao = ticketDao; 61 | } 62 | 63 | @Autowired(required = false) 64 | public void setFrequentFlyerSecurityService(FrequentFlyerSecurityService frequentFlyerSecurityService) { 65 | this.frequentFlyerSecurityService = frequentFlyerSecurityService; 66 | } 67 | 68 | @Transactional(readOnly = false, rollbackFor = { NoSuchFlightException.class, NoSeatAvailableException.class, 69 | NoSuchFrequentFlyerException.class }) 70 | public Ticket bookFlight(String flightNumber, ZonedDateTime departureTime, List passengers) 71 | throws NoSuchFlightException, NoSeatAvailableException, NoSuchFrequentFlyerException { 72 | 73 | Assert.notEmpty(passengers, "No passengers given"); 74 | 75 | if (logger.isDebugEnabled()) { 76 | logger.debug("Booking flight '" + flightNumber + "' on '" + departureTime + "' for " + passengers); 77 | } 78 | 79 | Flight flight = flightDao.findFlightByNumberAndDepartureTime(flightNumber, departureTime); 80 | 81 | if (flight == null) { 82 | throw new NoSuchFlightException(flightNumber, departureTime); 83 | } 84 | else if (flight.getSeatsAvailable() < passengers.size()) { 85 | throw new NoSeatAvailableException(flight); 86 | } 87 | 88 | Ticket ticket = new Ticket(); 89 | ticket.setIssueDate(LocalDate.now()); 90 | ticket.setFlight(flight); 91 | 92 | for (Passenger passenger : passengers) { 93 | if (passenger instanceof FrequentFlyer && frequentFlyerSecurityService != null) { 94 | String username = ((FrequentFlyer) passenger).getUsername(); 95 | Assert.hasLength(username, "No username specified"); 96 | FrequentFlyer frequentFlyer = frequentFlyerSecurityService.getFrequentFlyer(username); 97 | frequentFlyer.addMiles(flight.getMiles()); 98 | ticket.addPassenger(frequentFlyer); 99 | } 100 | else { 101 | ticket.addPassenger(passenger); 102 | } 103 | } 104 | 105 | flight.substractSeats(passengers.size()); 106 | 107 | flightDao.save(flight); 108 | ticketDao.save(ticket); 109 | 110 | return ticket; 111 | } 112 | 113 | public Flight getFlight(Long id) throws NoSuchFlightException { 114 | 115 | return flightDao.findById(id) // 116 | .orElseThrow(() -> new NoSuchFlightException(id)); 117 | } 118 | 119 | public List getFlights(String fromAirportCode, String toAirportCode, ZonedDateTime departureDate, 120 | ServiceClass serviceClass) { 121 | 122 | if (serviceClass == null) { 123 | serviceClass = ServiceClass.ECONOMY; 124 | } 125 | 126 | if (logger.isDebugEnabled()) { 127 | logger 128 | .debug("Getting flights from '" + fromAirportCode + "' to '" + toAirportCode + "' on " + departureDate); 129 | } 130 | 131 | List flights = flightDao.findFlights(fromAirportCode, toAirportCode, departureDate, serviceClass); 132 | 133 | if (logger.isDebugEnabled()) { 134 | logger.debug("Returning " + flights.size() + " flights"); 135 | } 136 | 137 | return flights; 138 | } 139 | 140 | @Override 141 | @PreAuthorize("hasRole('FREQUENT_FLYER')") 142 | public int getFrequentFlyerMileage() { 143 | 144 | if (logger.isDebugEnabled()) { 145 | logger.debug("Using " + frequentFlyerSecurityService + " for security"); 146 | } 147 | 148 | return Optional.ofNullable(frequentFlyerSecurityService.getCurrentlyAuthenticatedFrequentFlyer()) 149 | .map(FrequentFlyer::getMiles) // 150 | .orElse(0); 151 | } 152 | 153 | } 154 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/web/FlightsController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.web; 18 | 19 | import java.time.LocalDate; 20 | import java.time.ZonedDateTime; 21 | 22 | import org.springframework.stereotype.Controller; 23 | import org.springframework.ui.Model; 24 | import org.springframework.util.Assert; 25 | import org.springframework.util.ObjectUtils; 26 | import org.springframework.util.StringUtils; 27 | import org.springframework.web.bind.annotation.GetMapping; 28 | import org.springframework.web.bind.annotation.PathVariable; 29 | import org.springframework.web.bind.annotation.RequestMapping; 30 | import org.springframework.web.bind.annotation.RequestParam; 31 | import org.springframework.ws.samples.airline.domain.ServiceClass; 32 | import org.springframework.ws.samples.airline.service.AirlineService; 33 | import org.springframework.ws.samples.airline.service.NoSuchFlightException; 34 | 35 | /** 36 | * @author Arjen Poutsma 37 | */ 38 | @Controller 39 | @RequestMapping("/flights") 40 | public class FlightsController { 41 | 42 | private AirlineService airlineService; 43 | 44 | public FlightsController(AirlineService airlineService) { 45 | 46 | Assert.notNull(airlineService, "'airlineService' must not be null"); 47 | this.airlineService = airlineService; 48 | } 49 | 50 | @GetMapping 51 | public String flightList(@RequestParam(value = "from", required = false) String fromAirportCode, 52 | @RequestParam(value = "to", required = false) String toAirportCode, 53 | @RequestParam(value = "departureDate", required = false) String departureDateString, 54 | @RequestParam(value = "serviceClass", required = false) String serviceClassString, Model model) { 55 | 56 | if (ObjectUtils.isEmpty(departureDateString)) { 57 | departureDateString = LocalDate.now().toString(); 58 | } 59 | if (ObjectUtils.isEmpty(serviceClassString)) { 60 | serviceClassString = "ECONOMY"; 61 | } 62 | ServiceClass serviceClass = ServiceClass.valueOf(serviceClassString); 63 | ZonedDateTime departureDate = ZonedDateTime.parse(departureDateString); 64 | 65 | if (StringUtils.hasLength(fromAirportCode) && StringUtils.hasLength(toAirportCode)) { 66 | model.addAttribute("from", fromAirportCode); 67 | model.addAttribute("to", toAirportCode); 68 | model.addAttribute("departureDate", departureDateString); 69 | model.addAttribute("serviceClass", serviceClassString); 70 | model.addAttribute("flights", 71 | airlineService.getFlights(fromAirportCode, toAirportCode, departureDate, serviceClass)); 72 | } 73 | return "flights"; 74 | } 75 | 76 | @GetMapping(value = "{id}") 77 | public String singleFlight(@PathVariable("id") long id, Model model) throws NoSuchFlightException { 78 | 79 | model.addAttribute(airlineService.getFlight(id)); 80 | return "flight"; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/ws/AirlineWebServiceConstants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.ws; 18 | 19 | /** 20 | * @author Arjen Poutsma 21 | */ 22 | public interface AirlineWebServiceConstants { 23 | 24 | String BOOK_FLIGHT_REQUEST = "BookFlightRequest"; 25 | 26 | String GET_FLIGHTS_REQUEST = "GetFlightsRequest"; 27 | 28 | String GET_FREQUENT_FLYER_MILEAGE_RESPONSE = "GetFrequentFlyerMileageResponse"; 29 | 30 | String MESSAGES_NAMESPACE = "http://www.springframework.org/spring-ws/samples/airline/schemas/messages"; 31 | 32 | String GET_FREQUENT_FLYER_MILEAGE_REQUEST = "GetFrequentFlyerMileageRequest"; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /airline/server/src/main/java/org/springframework/ws/samples/airline/ws/WebServicesConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.airline.ws; 18 | 19 | import javax.security.auth.callback.CallbackHandler; 20 | 21 | import org.springframework.boot.web.server.MimeMappings; 22 | import org.springframework.boot.web.server.WebServerFactoryCustomizer; 23 | import org.springframework.boot.web.servlet.ServletRegistrationBean; 24 | import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; 25 | import org.springframework.context.ApplicationContext; 26 | import org.springframework.context.annotation.Bean; 27 | import org.springframework.context.annotation.Configuration; 28 | import org.springframework.core.io.ClassPathResource; 29 | import org.springframework.security.core.userdetails.UserDetailsService; 30 | import org.springframework.util.MimeTypeUtils; 31 | import org.springframework.ws.soap.saaj.SaajSoapMessageFactory; 32 | import org.springframework.ws.soap.security.wss4j2.Wss4jSecurityInterceptor; 33 | import org.springframework.ws.soap.security.wss4j2.callback.SpringSecurityPasswordValidationCallbackHandler; 34 | import org.springframework.ws.soap.server.SoapMessageDispatcher; 35 | import org.springframework.ws.soap.server.endpoint.interceptor.PayloadRootSmartSoapEndpointInterceptor; 36 | import org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor; 37 | import org.springframework.ws.transport.http.MessageDispatcherServlet; 38 | import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition; 39 | import org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection; 40 | 41 | @Configuration 42 | public class WebServicesConfiguration { 43 | 44 | @Bean 45 | WebServerFactoryCustomizer wsMimeMappings() { 46 | 47 | return factory -> { 48 | MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT); 49 | mappings.add("xsd", MimeTypeUtils.TEXT_XML_VALUE); 50 | factory.setMimeMappings(mappings); 51 | }; 52 | } 53 | 54 | @Bean 55 | ServletRegistrationBean webServicesRegistration(ApplicationContext ctx) { 56 | 57 | MessageDispatcherServlet messageDispatcherServlet = new MessageDispatcherServlet(); 58 | messageDispatcherServlet.setApplicationContext(ctx); 59 | messageDispatcherServlet.setTransformWsdlLocations(true); 60 | 61 | return new ServletRegistrationBean<>(messageDispatcherServlet, "/airline-server/*", "*.wsdl"); 62 | } 63 | 64 | @Bean 65 | PayloadValidatingInterceptor payloadValidatingInterceptor(CommonsXsdSchemaCollection xsdSchemaCollection) { 66 | 67 | PayloadValidatingInterceptor payloadValidatingInterceptor = new PayloadValidatingInterceptor(); 68 | payloadValidatingInterceptor.setXsdSchemaCollection(xsdSchemaCollection); 69 | payloadValidatingInterceptor.setValidateRequest(true); 70 | payloadValidatingInterceptor.setValidateResponse(true); 71 | 72 | return payloadValidatingInterceptor; 73 | } 74 | 75 | @Bean 76 | Wss4jSecurityInterceptor securityInterceptor(SpringSecurityPasswordValidationCallbackHandler handler) { 77 | 78 | /** 79 | * 81 | * 82 | * 83 | */ 84 | Wss4jSecurityInterceptor securityInterceptor = new Wss4jSecurityInterceptor(); 85 | securityInterceptor.setValidationActions("UsernameToken"); 86 | securityInterceptor.setValidationCallbackHandlers(new CallbackHandler[] { handler }); 87 | securityInterceptor.setSecureResponse(false); 88 | return securityInterceptor; 89 | } 90 | 91 | @Bean 92 | PayloadRootSmartSoapEndpointInterceptor smartSoapEndpointInterceptor(Wss4jSecurityInterceptor securityInterceptor) { 93 | return new PayloadRootSmartSoapEndpointInterceptor(securityInterceptor, 94 | "http://www.springframework.org/spring-ws/samples/airline/schemas/messages", 95 | "GetFrequentFlyerMileageRequest"); 96 | } 97 | 98 | @Bean 99 | SpringSecurityPasswordValidationCallbackHandler springSecurityPasswordValidationCallbackHandler( 100 | UserDetailsService userDetailsService) { 101 | 102 | SpringSecurityPasswordValidationCallbackHandler handler = new SpringSecurityPasswordValidationCallbackHandler(); 103 | handler.setUserDetailsService(userDetailsService); 104 | return handler; 105 | } 106 | 107 | @Bean 108 | SaajSoapMessageFactory messageFactory() { 109 | return new SaajSoapMessageFactory(); 110 | } 111 | 112 | @Bean 113 | SoapMessageDispatcher dispatcher() { 114 | return new SoapMessageDispatcher(); 115 | } 116 | 117 | @Bean 118 | CommonsXsdSchemaCollection commonsXsdSchemaCollection() { 119 | 120 | CommonsXsdSchemaCollection commonsXsdSchemaCollection = new CommonsXsdSchemaCollection(); 121 | commonsXsdSchemaCollection.setXsds(new ClassPathResource("messages.xsd")); 122 | commonsXsdSchemaCollection.setInline(true); 123 | return commonsXsdSchemaCollection; 124 | } 125 | 126 | @Bean("services") 127 | DefaultWsdl11Definition airline(CommonsXsdSchemaCollection schemaCollection) { 128 | 129 | DefaultWsdl11Definition definition = new DefaultWsdl11Definition(); 130 | definition.setSchemaCollection(schemaCollection); 131 | definition.setPortTypeName("Airline"); 132 | definition.setLocationUri("http://localhost:8080/airline-server/services"); 133 | definition.setTargetNamespace("http://www.springframework.org/spring-ws/samples/airline/definitions"); 134 | return definition; 135 | } 136 | 137 | } 138 | -------------------------------------------------------------------------------- /airline/server/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.org.springframework.data=DEBUG 2 | logging.level.org.springframework.web=TRACE 3 | logging.level.org.springframework.jms=DEBUG 4 | logging.level.org.springframework.ws=DEBUG 5 | logging.level.org.springframework.security=TRACE 6 | #logging.level.org.apache.activemq=DEBUG 7 | logging.level.org.springframework.ws.client.MessageTracing.sent=DEBUG 8 | logging.level.org.springframework.ws.server.MessageTracing.sent=DEBUG 9 | logging.level.org.springframework.ws.client.MessageTracing.received=TRACE 10 | logging.level.org.springframework.ws.server.MessageTracing.received=TRACE 11 | logging.level.org.springframework.ws.samples=DEBUG 12 | -------------------------------------------------------------------------------- /airline/server/src/main/resources/messages.xsd: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /airline/server/src/main/resources/templates/flight.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Flights 4 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 14 | 18 | 19 | 20 | 21 | 24 | 25 | 26 | 27 | 31 | 32 | 33 | 34 | 37 | 38 |
Number: 9 | 10 |
From: 15 | 16 | () 17 |
Departure: 22 | 23 |
To: 28 | 29 | () 30 |
Departure: 35 | 36 |
39 | Flights 40 | 41 | -------------------------------------------------------------------------------- /airline/server/src/main/resources/templates/flights.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Flights 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 28 | 29 | 30 | 33 | 34 |
From:
To:
Departure Date:
Service Class: 22 | 27 |
31 | 32 |
35 |
36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | 52 | 57 | 58 |
NumberDepartsArrives
45 | 46 | 48 | 49 | () 50 | 51 | 53 | 54 | () 55 | 56 |
59 |
60 |
61 | 62 | -------------------------------------------------------------------------------- /airline/server/src/main/resources/templates/noSuchFlight.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | No Such Flight 4 | 5 | 6 |

7 | 8 |

No such flight:

9 | Flights 10 | 11 | 12 | -------------------------------------------------------------------------------- /airline/server/src/main/resources/types.xsd: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /echo/README.adoc: -------------------------------------------------------------------------------- 1 | = Echo Sample 2 | 3 | This sample shows a bare-bones echoing service. Incoming messages are handled 4 | via DOM, and a simple 'business logic' service is used to obtain the result. 5 | 6 | == Build and deploy 7 | 8 | See the main link:../README.adoc[README] for build instructions. 9 | 10 | == License 11 | 12 | https://projects.spring.io/spring-ws[Spring Web Services] is released under version 2.0 of the http://www.apache.org/licenses/LICENSE-2.0[Apache License]. -------------------------------------------------------------------------------- /echo/client/saaj/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.ws 8 | spring-ws-samples 9 | 2.1.0-SNAPSHOT 10 | ../../../pom.xml 11 | 12 | echo-client-saaj 13 | Spring Web Services Samples - Echo - Client - SAAJ 14 | 15 | 16 | 17 | org.springframework.boot 18 | spring-boot-starter 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-web-services 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-tomcat 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-maven-plugin 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /echo/client/saaj/src/main/java/org/springframework/ws/samples/echo/client/saaj/EchoClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.echo.client.saaj; 18 | 19 | import jakarta.xml.soap.*; 20 | 21 | import java.net.MalformedURLException; 22 | import java.net.URL; 23 | 24 | import org.slf4j.Logger; 25 | import org.slf4j.LoggerFactory; 26 | 27 | /** 28 | * A client for the Echo Web Service that uses SAAJ. 29 | * 30 | * @author Ben Ethridge 31 | * @author Arjen Poutsma 32 | */ 33 | public class EchoClient { 34 | 35 | public static final String NAMESPACE_URI = "http://www.springframework.org/spring-ws/samples/echo"; 36 | 37 | public static final String PREFIX = "tns"; 38 | 39 | private static final Logger logger = LoggerFactory.getLogger(EchoClient.class); 40 | 41 | private SOAPConnectionFactory connectionFactory; 42 | 43 | private MessageFactory messageFactory; 44 | 45 | private URL url; 46 | 47 | public EchoClient(String url) throws SOAPException, MalformedURLException { 48 | 49 | connectionFactory = SOAPConnectionFactory.newInstance(); 50 | messageFactory = MessageFactory.newInstance(); 51 | this.url = new URL(url); 52 | } 53 | 54 | private SOAPMessage createEchoRequest() throws SOAPException { 55 | 56 | SOAPMessage message = messageFactory.createMessage(); 57 | SOAPEnvelope envelope = message.getSOAPPart().getEnvelope(); 58 | Name echoRequestName = envelope.createName("echoRequest", PREFIX, NAMESPACE_URI); 59 | SOAPBodyElement echoRequestElement = message.getSOAPBody().addBodyElement(echoRequestName); 60 | echoRequestElement.setValue("Hello"); 61 | return message; 62 | } 63 | 64 | public void callWebService() throws SOAPException { 65 | 66 | SOAPMessage request = createEchoRequest(); 67 | SOAPConnection connection = connectionFactory.createConnection(); 68 | SOAPMessage response = connection.call(request, url); 69 | if (!response.getSOAPBody().hasFault()) { 70 | writeEchoResponse(response); 71 | } 72 | else { 73 | SOAPFault fault = response.getSOAPBody().getFault(); 74 | logger.error("Received SOAP Fault"); 75 | logger.error("SOAP Fault Code :" + fault.getFaultCode()); 76 | logger.error("SOAP Fault String :" + fault.getFaultString()); 77 | } 78 | } 79 | 80 | private void writeEchoResponse(SOAPMessage message) throws SOAPException { 81 | 82 | SOAPEnvelope envelope = message.getSOAPPart().getEnvelope(); 83 | Name echoResponseName = envelope.createName("echoResponse", PREFIX, NAMESPACE_URI); 84 | SOAPBodyElement echoResponseElement = (SOAPBodyElement) message.getSOAPBody() 85 | .getChildElements(echoResponseName) 86 | .next(); 87 | String echoValue = echoResponseElement.getTextContent(); 88 | logger.info("Echo Response [" + echoValue + "]"); 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /echo/client/saaj/src/main/java/org/springframework/ws/samples/echo/client/saaj/SaajEchoClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.echo.client.saaj; 18 | 19 | import jakarta.xml.soap.SOAPException; 20 | 21 | import java.net.MalformedURLException; 22 | 23 | import org.springframework.boot.SpringApplication; 24 | import org.springframework.boot.autoconfigure.SpringBootApplication; 25 | 26 | @SpringBootApplication 27 | public class SaajEchoClient { 28 | 29 | public static void main(String[] args) throws MalformedURLException, SOAPException { 30 | SpringApplication.run(SaajEchoClient.class); 31 | 32 | String url = "http://localhost:8080/echo-server/services"; 33 | if (args.length > 0) { 34 | url = args[0]; 35 | } 36 | 37 | EchoClient echoClient = new EchoClient(url); 38 | echoClient.callWebService(); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /echo/client/spring-ws/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.ws 8 | spring-ws-samples 9 | 2.1.0-SNAPSHOT 10 | ../../../pom.xml 11 | 12 | echo-client-spring-ws 13 | Spring Web Services Samples - Echo - Client - Spring WS 14 | 15 | 16 | 17 | org.springframework.boot 18 | spring-boot-starter 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-web-services 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-tomcat 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-maven-plugin 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /echo/client/spring-ws/src/main/java/org/springframework/ws/samples/echo/client/sws/EchoClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.echo.client.sws; 18 | 19 | import java.io.IOException; 20 | 21 | import javax.xml.transform.Source; 22 | 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | import org.springframework.core.io.Resource; 26 | import org.springframework.stereotype.Service; 27 | import org.springframework.ws.client.core.support.WebServiceGatewaySupport; 28 | import org.springframework.xml.transform.ResourceSource; 29 | import org.springframework.xml.transform.StringResult; 30 | 31 | @Service 32 | public class EchoClient extends WebServiceGatewaySupport { 33 | 34 | private static final Logger logger = LoggerFactory.getLogger(EchoClient.class); 35 | 36 | private Resource request; 37 | 38 | public void setRequest(Resource request) { 39 | this.request = request; 40 | } 41 | 42 | public void echo() throws IOException { 43 | 44 | Source requestSource = new ResourceSource(request); 45 | StringResult result = new StringResult(); 46 | getWebServiceTemplate().sendSourceAndReceiveToResult(requestSource, result); 47 | 48 | logger.info(result.toString()); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /echo/client/spring-ws/src/main/java/org/springframework/ws/samples/echo/client/sws/SpringWsEchoClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.echo.client.sws; 18 | 19 | import org.springframework.boot.CommandLineRunner; 20 | import org.springframework.boot.SpringApplication; 21 | import org.springframework.boot.autoconfigure.SpringBootApplication; 22 | import org.springframework.context.annotation.Bean; 23 | import org.springframework.core.io.ClassPathResource; 24 | 25 | @SpringBootApplication 26 | public class SpringWsEchoClient { 27 | 28 | public static void main(String[] args) { 29 | SpringApplication.run(SpringWsEchoClient.class, args); 30 | } 31 | 32 | @Bean 33 | CommandLineRunner invoke(EchoClient echoClient) { 34 | 35 | return args -> { 36 | echoClient.setDefaultUri("http://localhost:8080/echo-server/services"); 37 | echoClient.setRequest(new ClassPathResource("echoRequest.xml")); 38 | echoClient.echo(); 39 | }; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /echo/client/spring-ws/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | logging: 2 | level: 3 | org.springframework: 4 | ws: TRACE 5 | web: TRACE 6 | xml: DEBUG -------------------------------------------------------------------------------- /echo/client/spring-ws/src/main/resources/echoRequest.xml: -------------------------------------------------------------------------------- 1 | 2 | Hello 3 | -------------------------------------------------------------------------------- /echo/server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.ws 8 | spring-ws-samples 9 | 2.1.0-SNAPSHOT 10 | ../../pom.xml 11 | 12 | echo-server 13 | Spring Web Services Samples - Echo - Server 14 | 15 | 16 | ${project.basedir}/target/generated-sources/axis 17 | ${project.basedir}/target/classes 18 | ${project.basedir}/../airline.wsdl 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-web-services 25 | 26 | 27 | wsdl4j 28 | wsdl4j 29 | 30 | 31 | 32 | org.apache.ws.xmlschema 33 | xmlschema-core 34 | runtime 35 | 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-starter-test 40 | test 41 | 42 | 43 | 44 | 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-maven-plugin 49 | 50 | 51 | org.codehaus.mojo 52 | jaxb2-maven-plugin 53 | 54 | 55 | xjc 56 | 57 | xjc 58 | 59 | 60 | 61 | 62 | ${project.basedir}/src/main/resources/echo.xsd 63 | org.springframework.ws.samples.airline.schema 64 | 3.0 65 | 66 | 67 | 68 | org.codehaus.mojo 69 | build-helper-maven-plugin 70 | 71 | 72 | add-source 73 | process-sources 74 | 75 | add-source 76 | 77 | 78 | 79 | target/generated-sources/xjc 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /echo/server/src/main/java/org/springframework/ws/samples/echo/EchoApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.echo; 18 | 19 | import org.springframework.boot.SpringApplication; 20 | import org.springframework.boot.autoconfigure.SpringBootApplication; 21 | 22 | @SpringBootApplication 23 | public class EchoApplication { 24 | 25 | public static void main(String[] args) { 26 | SpringApplication.run(EchoApplication.class, args); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /echo/server/src/main/java/org/springframework/ws/samples/echo/config/EchoConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.echo.config; 18 | 19 | import java.util.List; 20 | 21 | import org.springframework.context.annotation.Bean; 22 | import org.springframework.context.annotation.Configuration; 23 | import org.springframework.core.io.ClassPathResource; 24 | import org.springframework.ws.config.annotation.WsConfigurerAdapter; 25 | import org.springframework.ws.server.EndpointInterceptor; 26 | import org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor; 27 | import org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor; 28 | import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition; 29 | import org.springframework.xml.xsd.SimpleXsdSchema; 30 | 31 | /** 32 | * Configuration class for the Echo sample. 33 | * 34 | * @author Arjen Poutsma 35 | */ 36 | @Configuration 37 | public class EchoConfig extends WsConfigurerAdapter { 38 | 39 | @Bean 40 | public SimpleXsdSchema echoXsd() { 41 | return new SimpleXsdSchema(new ClassPathResource("echo.xsd")); 42 | } 43 | 44 | @Override 45 | public void addInterceptors(List interceptors) { 46 | 47 | PayloadValidatingInterceptor validatingInterceptor = new PayloadValidatingInterceptor(); 48 | 49 | validatingInterceptor.setXsdSchema(echoXsd()); 50 | validatingInterceptor.setValidateRequest(true); 51 | validatingInterceptor.setValidateResponse(true); 52 | interceptors.add(validatingInterceptor); 53 | 54 | interceptors.add(new PayloadLoggingInterceptor()); 55 | } 56 | 57 | @Bean("echo-server") 58 | public DefaultWsdl11Definition echo(SimpleXsdSchema echoXsd) { 59 | 60 | DefaultWsdl11Definition definition = new DefaultWsdl11Definition(); 61 | definition.setPortTypeName("Echo"); 62 | definition.setLocationUri("http://localhost:8080/echo-server/services"); 63 | definition.setSchema(echoXsd); 64 | 65 | return definition; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /echo/server/src/main/java/org/springframework/ws/samples/echo/service/EchoService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.echo.service; 18 | 19 | /** 20 | * Defines the "business logic" of the web service. 21 | * 22 | * @author Ingo Siebert 23 | * @author Arjen Poutsma 24 | */ 25 | public interface EchoService { 26 | 27 | /** 28 | * Returns the given string. 29 | * @return message 30 | */ 31 | String echo(String message); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /echo/server/src/main/java/org/springframework/ws/samples/echo/service/impl/EchoServiceImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.echo.service.impl; 18 | 19 | import org.springframework.stereotype.Service; 20 | import org.springframework.ws.samples.echo.service.EchoService; 21 | 22 | /** 23 | * Default implementation of EchoService. 24 | * 25 | * @author Ingo Siebert 26 | * @author Arjen Poutsma 27 | */ 28 | @Service 29 | public class EchoServiceImpl implements EchoService { 30 | 31 | public String echo(String message) { 32 | return message; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /echo/server/src/main/java/org/springframework/ws/samples/echo/ws/EchoEndpoint.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.echo.ws; 18 | 19 | import javax.xml.parsers.DocumentBuilder; 20 | import javax.xml.parsers.DocumentBuilderFactory; 21 | import javax.xml.parsers.ParserConfigurationException; 22 | 23 | import org.springframework.util.Assert; 24 | import org.springframework.ws.samples.echo.service.EchoService; 25 | import org.springframework.ws.server.endpoint.annotation.Endpoint; 26 | import org.springframework.ws.server.endpoint.annotation.PayloadRoot; 27 | import org.springframework.ws.server.endpoint.annotation.RequestPayload; 28 | import org.springframework.ws.server.endpoint.annotation.ResponsePayload; 29 | import org.w3c.dom.Document; 30 | import org.w3c.dom.Element; 31 | import org.w3c.dom.Node; 32 | import org.w3c.dom.NodeList; 33 | import org.w3c.dom.Text; 34 | 35 | /** 36 | * Simple echoing Web service endpoint. Uses a EchoService to create a 37 | * response string. 38 | * 39 | * @author Ingo Siebert 40 | * @author Arjen Poutsma 41 | */ 42 | @Endpoint 43 | public class EchoEndpoint { 44 | 45 | /** 46 | * Namespace of both request and response. 47 | */ 48 | public static final String NAMESPACE_URI = "http://www.springframework.org/spring-ws/samples/echo"; 49 | 50 | /** 51 | * The local name of the expected request. 52 | */ 53 | public static final String ECHO_REQUEST_LOCAL_NAME = "echoRequest"; 54 | 55 | /** 56 | * The local name of the created response. 57 | */ 58 | public static final String ECHO_RESPONSE_LOCAL_NAME = "echoResponse"; 59 | 60 | private final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); 61 | 62 | private final EchoService echoService; 63 | 64 | public EchoEndpoint(EchoService echoService) { 65 | this.echoService = echoService; 66 | } 67 | 68 | /** 69 | * Reads the given requestElement, and sends a the response back. 70 | * @param requestElement the contents of the SOAP message as DOM elements 71 | * @return the response element 72 | */ 73 | @PayloadRoot(localPart = ECHO_REQUEST_LOCAL_NAME, namespace = NAMESPACE_URI) 74 | @ResponsePayload 75 | public Element handleEchoRequest(@RequestPayload Element requestElement) throws ParserConfigurationException { 76 | 77 | Assert.isTrue(NAMESPACE_URI.equals(requestElement.getNamespaceURI()), "Invalid namespace"); 78 | Assert.isTrue(ECHO_REQUEST_LOCAL_NAME.equals(requestElement.getLocalName()), "Invalid local name"); 79 | 80 | NodeList children = requestElement.getChildNodes(); 81 | Text requestText = null; 82 | 83 | for (int i = 0; i < children.getLength(); i++) { 84 | if (children.item(i).getNodeType() == Node.TEXT_NODE) { 85 | requestText = (Text) children.item(i); 86 | break; 87 | } 88 | } 89 | 90 | if (requestText == null) { 91 | throw new IllegalArgumentException("Could not find request text node"); 92 | } 93 | 94 | String echo = echoService.echo(requestText.getNodeValue()); 95 | 96 | DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); 97 | Document document = documentBuilder.newDocument(); 98 | Element responseElement = document.createElementNS(NAMESPACE_URI, ECHO_RESPONSE_LOCAL_NAME); 99 | Text responseText = document.createTextNode(echo); 100 | responseElement.appendChild(responseText); 101 | 102 | return responseElement; 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /echo/server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | logging: 2 | level: 3 | org.springframework: 4 | ws: TRACE 5 | web: TRACE 6 | xml: DEBUG 7 | spring: 8 | webservices: 9 | path: /echo-server -------------------------------------------------------------------------------- /echo/server/src/main/resources/echo.xsd: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /echo/server/src/main/webapp/EMTPY: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects/spring-ws-samples/e22a7833d6408730b35dff808f56b51443c9c0fe/echo/server/src/main/webapp/EMTPY -------------------------------------------------------------------------------- /echo/server/src/test/java/org/springframework/ws/samples/echo/ws/EchoEndpointTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.echo.ws; 18 | 19 | import static org.assertj.core.api.Assertions.*; 20 | import static org.mockito.Mockito.*; 21 | 22 | import javax.xml.parsers.DocumentBuilder; 23 | import javax.xml.parsers.DocumentBuilderFactory; 24 | 25 | import org.junit.jupiter.api.BeforeEach; 26 | import org.junit.jupiter.api.Test; 27 | import org.springframework.ws.samples.echo.service.EchoService; 28 | import org.w3c.dom.Document; 29 | import org.w3c.dom.Element; 30 | import org.w3c.dom.Text; 31 | 32 | public class EchoEndpointTest { 33 | 34 | private EchoEndpoint endpoint; 35 | 36 | private Document requestDocument; 37 | 38 | private Document responseDocument; 39 | 40 | private EchoService echoServiceMock; 41 | 42 | @BeforeEach 43 | public void setUp() throws Exception { 44 | 45 | DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); 46 | documentBuilderFactory.setNamespaceAware(true); 47 | DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); 48 | requestDocument = documentBuilder.newDocument(); 49 | responseDocument = documentBuilder.newDocument(); 50 | echoServiceMock = mock(EchoService.class); 51 | endpoint = new EchoEndpoint(echoServiceMock); 52 | } 53 | 54 | @Test 55 | public void testInvokeInternal() throws Exception { 56 | 57 | Element echoRequest = requestDocument.createElementNS(EchoEndpoint.NAMESPACE_URI, 58 | EchoEndpoint.ECHO_REQUEST_LOCAL_NAME); 59 | Text requestText = requestDocument.createTextNode("ABC"); 60 | echoRequest.appendChild(requestText); 61 | when(echoServiceMock.echo("ABC")).thenReturn("DEF"); 62 | 63 | Element echoResponse = endpoint.handleEchoRequest(echoRequest); 64 | 65 | assertThat(echoResponse.getNamespaceURI()).isEqualTo(EchoEndpoint.NAMESPACE_URI); 66 | assertThat(echoResponse.getLocalName()).isEqualTo(EchoEndpoint.ECHO_RESPONSE_LOCAL_NAME); 67 | assertThat(echoResponse.getChildNodes().item(0).getNodeValue()).isEqualTo("DEF"); 68 | 69 | verify(echoServiceMock); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /echo/server/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootCategory=WARN, stdout 2 | 3 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 4 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 5 | log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n 6 | -------------------------------------------------------------------------------- /mtom/README.adoc: -------------------------------------------------------------------------------- 1 | = MTOM Sample 2 | 3 | This sample shows how to use marshal and unmarshal MTOM attachments using JAXB2. 4 | 5 | == Build and deploy 6 | 7 | See the main link:../README.adoc[README] for build instructions. 8 | 9 | == License 10 | 11 | https://projects.spring.io/spring-ws[Spring Web Services] is released under version 2.0 of the http://www.apache.org/licenses/LICENSE-2.0[Apache License]. -------------------------------------------------------------------------------- /mtom/client/spring-ws/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.ws 8 | spring-ws-samples 9 | 2.1.0-SNAPSHOT 10 | ../../../pom.xml 11 | 12 | mtom-client-spring-ws 13 | Spring Web Services Samples - MTOM - Client - Spring WS 14 | 15 | 16 | ${project.basedir}/../../server/src/main/resources/contentStore.wsdl 17 | 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-web-services 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-tomcat 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-maven-plugin 41 | 42 | 43 | com.evolvedbinary.maven.jvnet 44 | jaxb30-maven-plugin 45 | 46 | 47 | 48 | generate 49 | 50 | 51 | 52 | 53 | WSDL 54 | org.springframework.ws.samples.mtom.client.sws 55 | 56 | 57 | ${wsdl} 58 | 59 | 60 | true 61 | 62 | 63 | 64 | org.codehaus.mojo 65 | build-helper-maven-plugin 66 | 67 | 68 | add-source 69 | process-sources 70 | 71 | add-source 72 | 73 | 74 | 75 | ${project.basedir}/target/generated-sources/xjc 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /mtom/client/spring-ws/src/main/java/org/springframework/ws/samples/mtom/client/sws/MtomClientConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.mtom.client.sws; 18 | 19 | import org.springframework.context.annotation.Bean; 20 | import org.springframework.context.annotation.Configuration; 21 | import org.springframework.oxm.jaxb.Jaxb2Marshaller; 22 | import org.springframework.ws.soap.saaj.SaajSoapMessageFactory; 23 | 24 | /** 25 | * @author Arjen Poutsma 26 | */ 27 | @Configuration 28 | public class MtomClientConfig { 29 | 30 | @Bean 31 | public SaajMtomClient saajClient(SaajSoapMessageFactory messageFactory, Jaxb2Marshaller marshaller) { 32 | 33 | SaajMtomClient client = new SaajMtomClient(messageFactory); 34 | client.setDefaultUri("http://localhost:8080/mtom-server/services"); 35 | client.setMarshaller(marshaller); 36 | client.setUnmarshaller(marshaller); 37 | return client; 38 | } 39 | 40 | @Bean 41 | public SaajSoapMessageFactory saajSoapMessageFactory() { 42 | return new SaajSoapMessageFactory(); 43 | } 44 | 45 | @Bean 46 | public Jaxb2Marshaller marshaller() { 47 | 48 | Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); 49 | marshaller.setContextPath("org.springframework.ws.samples.mtom.client.sws"); 50 | marshaller.setMtomEnabled(true); 51 | return marshaller; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /mtom/client/spring-ws/src/main/java/org/springframework/ws/samples/mtom/client/sws/SaajMtomClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.mtom.client.sws; 18 | 19 | import java.io.File; 20 | import java.io.FileOutputStream; 21 | import java.io.IOException; 22 | import java.io.InputStream; 23 | import java.io.OutputStream; 24 | 25 | import jakarta.activation.DataHandler; 26 | import org.slf4j.Logger; 27 | import org.slf4j.LoggerFactory; 28 | import org.springframework.boot.CommandLineRunner; 29 | import org.springframework.boot.SpringApplication; 30 | import org.springframework.boot.autoconfigure.SpringBootApplication; 31 | import org.springframework.context.annotation.Bean; 32 | import org.springframework.util.ClassUtils; 33 | import org.springframework.util.StopWatch; 34 | import org.springframework.ws.client.core.support.WebServiceGatewaySupport; 35 | import org.springframework.ws.soap.saaj.SaajSoapMessageFactory; 36 | 37 | /** 38 | * Simple client that demonstrates MTOM by invoking {@code StoreImage} and 39 | * {@code LoadImage} using a WebServiceTemplate and SAAJ. 40 | * 41 | * @author Tareq Abed Rabbo 42 | * @author Arjen Poutsma 43 | */ 44 | @SpringBootApplication 45 | public class SaajMtomClient extends WebServiceGatewaySupport { 46 | 47 | public static void main(String[] args) { 48 | SpringApplication.run(SaajMtomClient.class, args); 49 | } 50 | 51 | @Bean 52 | CommandLineRunner invoke(SaajMtomClient saajClient) { 53 | 54 | return args -> { 55 | saajClient.storeContent(); 56 | saajClient.loadContent(); 57 | }; 58 | } 59 | 60 | private static final Logger logger = LoggerFactory.getLogger(SaajMtomClient.class); 61 | 62 | private ObjectFactory objectFactory = new ObjectFactory(); 63 | 64 | private StopWatch stopWatch = new StopWatch(ClassUtils.getShortName(getClass())); 65 | 66 | public SaajMtomClient(SaajSoapMessageFactory messageFactory) { 67 | super(messageFactory); 68 | } 69 | 70 | public void storeContent() { 71 | 72 | StoreContentRequest storeContentRequest = this.objectFactory.createStoreContentRequest(); 73 | 74 | storeContentRequest.setName("spring-ws-logo"); 75 | storeContentRequest.setContent( 76 | new DataHandler(Thread.currentThread().getContextClassLoader().getResource("spring-ws-logo.png"))); 77 | 78 | this.stopWatch.start("store"); 79 | 80 | getWebServiceTemplate().marshalSendAndReceive(storeContentRequest); 81 | 82 | this.stopWatch.stop(); 83 | 84 | logger.info(this.stopWatch.prettyPrint()); 85 | } 86 | 87 | public void loadContent() throws IOException { 88 | 89 | LoadContentRequest loadContentRequest = this.objectFactory.createLoadContentRequest(); 90 | loadContentRequest.setName("spring-ws-logo"); 91 | 92 | String tmpDir = System.getProperty("java.io.tmpdir"); 93 | File out = new File(tmpDir, "spring_mtom_tmp.bin"); 94 | 95 | long freeBefore = Runtime.getRuntime().freeMemory(); 96 | 97 | this.stopWatch.start("load"); 98 | 99 | LoadContentResponse loadContentResponse = (LoadContentResponse) getWebServiceTemplate() 100 | .marshalSendAndReceive(loadContentRequest); 101 | 102 | this.stopWatch.stop(); 103 | 104 | DataHandler content = loadContentResponse.getContent(); 105 | long freeAfter = Runtime.getRuntime().freeMemory(); 106 | 107 | logger.info("Memory usage [kB]: " + ((freeAfter - freeBefore) / 1024)); 108 | 109 | this.stopWatch.start("loadAttachmentContent"); 110 | 111 | long size = saveContentToFile(content, out); 112 | 113 | this.stopWatch.stop(); 114 | 115 | logger.info("Received file size [kB]: " + size); 116 | logger.info("Stored at " + out.getAbsolutePath()); 117 | logger.info(this.stopWatch.prettyPrint()); 118 | } 119 | 120 | private static long saveContentToFile(DataHandler content, File outFile) throws IOException { 121 | 122 | long size = 0; 123 | 124 | byte[] buffer = new byte[1024]; 125 | try (InputStream in = content.getInputStream()) { 126 | try (OutputStream out = new FileOutputStream(outFile)) { 127 | for (int readBytes; (readBytes = in.read(buffer, 0, buffer.length)) > 0;) { 128 | size += readBytes; 129 | out.write(buffer, 0, readBytes); 130 | } 131 | } 132 | } 133 | 134 | return size; 135 | } 136 | 137 | } 138 | -------------------------------------------------------------------------------- /mtom/client/spring-ws/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | logging: 2 | level: 3 | org.springframework.ws: DEBUG -------------------------------------------------------------------------------- /mtom/client/spring-ws/src/main/resources/spring-ws-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects/spring-ws-samples/e22a7833d6408730b35dff808f56b51443c9c0fe/mtom/client/spring-ws/src/main/resources/spring-ws-logo.png -------------------------------------------------------------------------------- /mtom/server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.ws 8 | spring-ws-samples 9 | 2.1.0-SNAPSHOT 10 | ../../pom.xml 11 | 12 | mtom-server 13 | Spring Web Services Samples - MTOM - Server 14 | 15 | 16 | ${project.basedir}/src/main/resources/contentStore.wsdl 17 | 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-web-services 23 | 24 | 25 | org.apache.ws.xmlschema 26 | xmlschema-core 27 | 28 | 29 | wsdl4j 30 | wsdl4j 31 | 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-test 36 | test 37 | 38 | 39 | 40 | 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-maven-plugin 45 | 46 | 47 | com.evolvedbinary.maven.jvnet 48 | jaxb30-maven-plugin 49 | 50 | 51 | 52 | generate 53 | 54 | 55 | 56 | 57 | WSDL 58 | org.springframework.ws.samples.mtom.schema 59 | 60 | 61 | ${wsdl} 62 | 63 | 64 | true 65 | 66 | 67 | 68 | org.codehaus.mojo 69 | build-helper-maven-plugin 70 | 71 | 72 | add-source 73 | process-sources 74 | 75 | add-source 76 | 77 | 78 | 79 | target/generated-sources/xjc 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /mtom/server/src/main/java/org/springframework/ws/samples/mtom/MtomServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.mtom; 18 | 19 | import org.springframework.boot.SpringApplication; 20 | import org.springframework.boot.autoconfigure.SpringBootApplication; 21 | 22 | @SpringBootApplication 23 | public class MtomServer { 24 | 25 | public static void main(String[] args) { 26 | SpringApplication.run(MtomServer.class, args); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /mtom/server/src/main/java/org/springframework/ws/samples/mtom/config/MtomServerConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.mtom.config; 18 | 19 | import java.util.Collections; 20 | 21 | import org.springframework.boot.web.servlet.ServletRegistrationBean; 22 | import org.springframework.context.ApplicationContext; 23 | import org.springframework.context.annotation.Bean; 24 | import org.springframework.context.annotation.Configuration; 25 | import org.springframework.core.io.ClassPathResource; 26 | import org.springframework.oxm.jaxb.Jaxb2Marshaller; 27 | import org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter; 28 | import org.springframework.ws.server.endpoint.adapter.method.MarshallingPayloadMethodProcessor; 29 | import org.springframework.ws.transport.http.MessageDispatcherServlet; 30 | import org.springframework.ws.wsdl.wsdl11.SimpleWsdl11Definition; 31 | 32 | /** 33 | * @author Arjen Poutsma 34 | */ 35 | @Configuration 36 | public class MtomServerConfiguration { 37 | 38 | @Bean 39 | ServletRegistrationBean webServicesRegistration(ApplicationContext ctx) { 40 | 41 | MessageDispatcherServlet messageDispatcherServlet = new MessageDispatcherServlet(); 42 | messageDispatcherServlet.setApplicationContext(ctx); 43 | messageDispatcherServlet.setTransformWsdlLocations(true); 44 | 45 | return new ServletRegistrationBean<>(messageDispatcherServlet, "/mtom-server/*", "*.wsdl"); 46 | } 47 | 48 | @Bean 49 | public Jaxb2Marshaller marshaller() { 50 | 51 | Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); 52 | marshaller.setContextPath("org.springframework.ws.samples.mtom.schema"); 53 | marshaller.setMtomEnabled(true); 54 | return marshaller; 55 | } 56 | 57 | @Bean 58 | public MarshallingPayloadMethodProcessor methodProcessor(Jaxb2Marshaller marshaller) { 59 | return new MarshallingPayloadMethodProcessor(marshaller); 60 | } 61 | 62 | @Bean 63 | DefaultMethodEndpointAdapter endpointAdapter(MarshallingPayloadMethodProcessor methodProcessor) { 64 | 65 | DefaultMethodEndpointAdapter adapter = new DefaultMethodEndpointAdapter(); 66 | adapter.setMethodArgumentResolvers(Collections.singletonList(methodProcessor)); 67 | adapter.setMethodReturnValueHandlers(Collections.singletonList(methodProcessor)); 68 | return adapter; 69 | } 70 | 71 | @Bean 72 | public SimpleWsdl11Definition contentStore() { 73 | 74 | SimpleWsdl11Definition definition = new SimpleWsdl11Definition(); 75 | definition.setWsdl(new ClassPathResource("/contentStore.wsdl")); 76 | return definition; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /mtom/server/src/main/java/org/springframework/ws/samples/mtom/service/ContentRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.mtom.service; 18 | 19 | import jakarta.activation.DataHandler; 20 | 21 | import java.io.File; 22 | import java.io.IOException; 23 | 24 | /** 25 | * @author Arjen Poutsma 26 | */ 27 | public interface ContentRepository { 28 | 29 | File loadContent(String name); 30 | 31 | void storeContent(String name, DataHandler content) throws IOException; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /mtom/server/src/main/java/org/springframework/ws/samples/mtom/service/ContentRepositoryImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.mtom.service; 18 | 19 | import jakarta.activation.DataHandler; 20 | 21 | import java.io.*; 22 | 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | import org.springframework.beans.factory.annotation.Value; 26 | import org.springframework.stereotype.Service; 27 | 28 | /** 29 | * @author Arjen Poutsma 30 | */ 31 | @Service 32 | class ContentRepositoryImpl implements ContentRepository { 33 | 34 | private static final Logger logger = LoggerFactory.getLogger(ContentRepositoryImpl.class); 35 | 36 | @Value(value = "#{ systemProperties['java.io.tmpdir'] }") // 37 | private String fileStorePath; 38 | 39 | @Override 40 | public File loadContent(String name) { 41 | return new File(this.fileStorePath, name + ".tmp"); 42 | } 43 | 44 | @Override 45 | public void storeContent(String name, DataHandler content) throws IOException { 46 | 47 | File outFile = new File(this.fileStorePath, name + ".tmp"); 48 | logger.info("Storing content in file: {}", outFile.getAbsolutePath()); 49 | 50 | int i = 0; 51 | byte[] buffer = new byte[1024]; 52 | try (InputStream in = content.getInputStream()) { 53 | try (OutputStream out = new FileOutputStream(outFile)) { 54 | while ((i = in.read(buffer, 0, buffer.length)) > 0) { 55 | out.write(buffer, 0, i); 56 | } 57 | } 58 | } 59 | logger.info("Content stored."); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /mtom/server/src/main/java/org/springframework/ws/samples/mtom/ws/ContentRepositoryEndpoint.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.ws.samples.mtom.ws; 18 | 19 | import jakarta.activation.DataHandler; 20 | import jakarta.activation.FileDataSource; 21 | 22 | import java.io.File; 23 | import java.io.IOException; 24 | 25 | import org.springframework.util.Assert; 26 | import org.springframework.ws.samples.mtom.schema.*; 27 | import org.springframework.ws.samples.mtom.service.ContentRepository; 28 | import org.springframework.ws.server.endpoint.annotation.Endpoint; 29 | import org.springframework.ws.server.endpoint.annotation.PayloadRoot; 30 | import org.springframework.ws.server.endpoint.annotation.RequestPayload; 31 | import org.springframework.ws.server.endpoint.annotation.ResponsePayload; 32 | 33 | /** 34 | * @author Arjen Poutsma 35 | */ 36 | @Endpoint 37 | public class ContentRepositoryEndpoint { 38 | 39 | private ContentRepository contentRepository; 40 | 41 | private ObjectFactory objectFactory; 42 | 43 | public ContentRepositoryEndpoint(ContentRepository contentRepository) { 44 | 45 | Assert.notNull(contentRepository, "'imageRepository' must not be null"); 46 | 47 | this.contentRepository = contentRepository; 48 | this.objectFactory = new ObjectFactory(); 49 | } 50 | 51 | @PayloadRoot(localPart = "StoreContentRequest", namespace = "http://www.springframework.org/spring-ws/samples/mtom") 52 | @ResponsePayload 53 | public StoreContentResponse store(@RequestPayload StoreContentRequest storeContentRequest) throws IOException { 54 | 55 | this.contentRepository.storeContent(storeContentRequest.getName(), storeContentRequest.getContent()); 56 | StoreContentResponse response = this.objectFactory.createStoreContentResponse(); 57 | response.setMessage("Success"); 58 | return response; 59 | } 60 | 61 | @PayloadRoot(localPart = "LoadContentRequest", namespace = "http://www.springframework.org/spring-ws/samples/mtom") 62 | @ResponsePayload 63 | public LoadContentResponse load(@RequestPayload LoadContentRequest loadContentRequest) throws IOException { 64 | 65 | LoadContentResponse response = this.objectFactory.createLoadContentResponse(); 66 | 67 | File contentFile = this.contentRepository.loadContent(loadContentRequest.getName()); 68 | DataHandler dataHandler = new DataHandler(new FileDataSource(contentFile)); 69 | response.setName(loadContentRequest.getName()); 70 | response.setContent(dataHandler); 71 | return response; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /mtom/server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | logging: 2 | level: 3 | org.springframework.ws: DEBUG -------------------------------------------------------------------------------- /mtom/server/src/main/resources/contentStore.wsdl: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 11 | 12 | 13 | 14 | 15 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /tutorial/README.adoc: -------------------------------------------------------------------------------- 1 | = Spring Web Service Tutorial 2 | 3 | This sample contains the code for the tutorial, which can be found in the 4 | https://spring.io/projects/spring-ws[Spring Web Services] reference documentation. 5 | 6 | == Build and deploy 7 | 8 | . See the main link:../README.adoc[README] for build instructions. 9 | 10 | . Access the WSDL at the following URL: 11 | 12 | http://localhost:8080/tutorial/holiday.wsdl 13 | 14 | == License 15 | 16 | https://projects.spring.io/spring-ws[Spring Web Services] is released under version 2.0 of the http://www.apache.org/licenses/LICENSE-2.0[Apache License]. 17 | -------------------------------------------------------------------------------- /tutorial/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.ws 8 | spring-ws-samples 9 | 2.1.0-SNAPSHOT 10 | ../pom.xml 11 | 12 | tutorial 13 | 0.0.1-SNAPSHOT 14 | Spring Web Services Samples - Tutorial 15 | 16 | 17 | ${project.basedir}/target/generated-sources/axis 18 | ${project.basedir}/target/classes 19 | ${project.basedir}/../airline.wsdl 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-web-services 26 | 27 | 28 | org.springframework.ws 29 | spring-ws-support 30 | 31 | 32 | jaxen 33 | jaxen 34 | 35 | 36 | org.jdom 37 | jdom2 38 | 39 | 40 | 41 | org.apache.ws.xmlschema 42 | xmlschema-core 43 | runtime 44 | 45 | 46 | wsdl4j 47 | wsdl4j 48 | runtime 49 | 50 | 51 | 52 | org.springframework.boot 53 | spring-boot-starter-test 54 | test 55 | 56 | 57 | 58 | 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-maven-plugin 63 | 64 | 65 | org.codehaus.mojo 66 | jaxb2-maven-plugin 67 | 68 | 69 | xjc 70 | 71 | xjc 72 | 73 | 74 | 75 | 76 | ${project.basedir}/src/main/resources/hr.xsd 77 | org.springframework.ws.samples.tutorial.schema 78 | 3.0 79 | 80 | 81 | 82 | org.codehaus.mojo 83 | build-helper-maven-plugin 84 | 85 | 86 | add-source 87 | process-sources 88 | 89 | add-source 90 | 91 | 92 | 93 | target/generated-sources/xjc 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /tutorial/src/main/java/com/mycompany/hr/HrApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.mycompany.hr; 18 | 19 | import org.springframework.boot.SpringApplication; 20 | import org.springframework.boot.autoconfigure.SpringBootApplication; 21 | 22 | @SpringBootApplication 23 | public class HrApplication { 24 | 25 | public static void main(String[] args) { 26 | SpringApplication.run(HrApplication.class, args); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /tutorial/src/main/java/com/mycompany/hr/config/HRConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.mycompany.hr.config; 18 | 19 | import org.springframework.context.annotation.Bean; 20 | import org.springframework.context.annotation.Configuration; 21 | import org.springframework.core.io.ClassPathResource; 22 | import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition; 23 | import org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection; 24 | 25 | /** 26 | * @author Arjen Poutsma 27 | */ 28 | @Configuration 29 | public class HRConfiguration { 30 | 31 | @Bean 32 | public DefaultWsdl11Definition holiday() { 33 | 34 | DefaultWsdl11Definition definition = new DefaultWsdl11Definition(); 35 | definition.setPortTypeName("HumanResource"); 36 | definition.setLocationUri("/holidayService/"); 37 | definition.setTargetNamespace("http://mycompany.com/hr/definitions"); 38 | definition.setSchemaCollection(holidayXsd()); 39 | return definition; 40 | } 41 | 42 | @Bean 43 | public CommonsXsdSchemaCollection holidayXsd() { 44 | 45 | CommonsXsdSchemaCollection collection = new CommonsXsdSchemaCollection(new ClassPathResource("/hr.xsd")); 46 | collection.setInline(true); 47 | return collection; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /tutorial/src/main/java/com/mycompany/hr/service/HumanResourceService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.mycompany.hr.service; 18 | 19 | import java.util.Date; 20 | 21 | /** 22 | * This interface defined the contract for a HR business service. It is used by the 23 | * {@link com.mycompany.hr.ws.HolidayEndpoint}. 24 | * 25 | * @author Arjen Poutsma 26 | */ 27 | public interface HumanResourceService { 28 | 29 | /** 30 | * Books a holiday. 31 | * @param startDate the start date of the holiday 32 | * @param endDate the end date of the holiday 33 | * @param name the name of the person taking the holiday 34 | */ 35 | void bookHoliday(Date startDate, Date endDate, String name); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /tutorial/src/main/java/com/mycompany/hr/service/StubHumanResourceService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.mycompany.hr.service; 18 | 19 | import java.util.Date; 20 | 21 | import org.springframework.stereotype.Service; 22 | 23 | import org.apache.commons.logging.Log; 24 | import org.apache.commons.logging.LogFactory; 25 | 26 | /** 27 | * Simple stub implementation of {@link HumanResourceService}, which does nothing but 28 | * logging. 29 | * 30 | * @author Arjen Poutsma 31 | */ 32 | @Service 33 | public class StubHumanResourceService implements HumanResourceService { 34 | 35 | private static final Log logger = LogFactory.getLog(StubHumanResourceService.class); 36 | 37 | public void bookHoliday(Date startDate, Date endDate, String name) { 38 | logger.info("Booking holiday for [" + startDate + "-" + endDate + "] for [" + name + "] "); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /tutorial/src/main/java/com/mycompany/hr/ws/HolidayEndpoint.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.mycompany.hr.ws; 18 | 19 | import java.text.ParseException; 20 | import java.text.SimpleDateFormat; 21 | import java.util.Date; 22 | 23 | import org.jdom2.Element; 24 | import org.jdom2.Namespace; 25 | import org.jdom2.filter.Filters; 26 | import org.jdom2.xpath.XPathExpression; 27 | import org.jdom2.xpath.XPathFactory; 28 | import org.springframework.beans.factory.annotation.Autowired; 29 | import org.springframework.ws.server.endpoint.annotation.Endpoint; 30 | import org.springframework.ws.server.endpoint.annotation.PayloadRoot; 31 | import org.springframework.ws.server.endpoint.annotation.RequestPayload; 32 | 33 | import com.mycompany.hr.service.HumanResourceService; 34 | 35 | /** 36 | * This endpoint handles holiday requests. It uses a combination of JDOM and XPath to 37 | * extract interesting pieces of XML from the incoming message, and invoked the injected 38 | * {@link HumanResourceService} with those. 39 | * 40 | * @author Arjen Poutsma 41 | */ 42 | @Endpoint 43 | public class HolidayEndpoint { 44 | 45 | private static final String NAMESPACE_URI = "http://mycompany.com/hr/schemas"; 46 | 47 | private XPathExpression startDateExpression; 48 | 49 | private XPathExpression endDateExpression; 50 | 51 | private XPathExpression firstNameExpression; 52 | 53 | private XPathExpression lastNameExpression; 54 | 55 | private HumanResourceService humanResourceService; 56 | 57 | @Autowired 58 | public HolidayEndpoint(HumanResourceService humanResourceService) { 59 | 60 | this.humanResourceService = humanResourceService; 61 | Namespace namespace = Namespace.getNamespace("hr", NAMESPACE_URI); 62 | XPathFactory xPathFactory = XPathFactory.instance(); 63 | startDateExpression = xPathFactory.compile("//hr:StartDate", Filters.element(), null, namespace); 64 | endDateExpression = xPathFactory.compile("//hr:EndDate", Filters.element(), null, namespace); 65 | firstNameExpression = xPathFactory.compile("//hr:FirstName", Filters.element(), null, namespace); 66 | lastNameExpression = xPathFactory.compile("//hr:LastName", Filters.element(), null, namespace); 67 | } 68 | 69 | @PayloadRoot(namespace = NAMESPACE_URI, localPart = "HolidayRequest") 70 | public void handleHolidayRequest(@RequestPayload Element holidayRequest) throws Exception { 71 | 72 | Date startDate = parseDate(startDateExpression, holidayRequest); 73 | Date endDate = parseDate(endDateExpression, holidayRequest); 74 | String name = firstNameExpression.evaluateFirst(holidayRequest).getText() + " " 75 | + lastNameExpression.evaluateFirst(holidayRequest).getText(); 76 | 77 | humanResourceService.bookHoliday(startDate, endDate, name); 78 | } 79 | 80 | private Date parseDate(XPathExpression expression, Element element) throws ParseException { 81 | 82 | Element result = expression.evaluateFirst(element); 83 | 84 | if (result != null) { 85 | SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 86 | return dateFormat.parse(result.getText()); 87 | } 88 | else { 89 | throw new IllegalArgumentException("Could not evaluate [" + expression + "] on [" + element + "]"); 90 | } 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /tutorial/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | logging.level.org.springframework.ws=DEBUG 2 | logging.level.org.springframework.xml=DEBUG 3 | logging.level.com.mycompany.hr=DEBUG 4 | -------------------------------------------------------------------------------- /tutorial/src/main/resources/hr.xsd: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /tutorial/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2007 the original author or authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | log4j.rootLogger=WARN, stdout 18 | log4j.logger.org.springframework.ws=DEBUG 19 | log4j.logger.org.springframework.xml=DEBUG 20 | log4j.logger.com.mycompany.hr=DEBUG 21 | 22 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 23 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 24 | log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n -------------------------------------------------------------------------------- /tutorial/src/main/webapp/EMPTY: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects/spring-ws-samples/e22a7833d6408730b35dff808f56b51443c9c0fe/tutorial/src/main/webapp/EMPTY -------------------------------------------------------------------------------- /tutorial/src/test/java/com/mycompany/hr/ws/HolidayEndpointTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2006-2025 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.mycompany.hr.ws; 18 | 19 | import static org.mockito.Mockito.*; 20 | 21 | import java.io.InputStream; 22 | import java.util.Calendar; 23 | 24 | import org.jdom2.Document; 25 | import org.jdom2.input.SAXBuilder; 26 | import org.junit.jupiter.api.BeforeEach; 27 | import org.junit.jupiter.api.Test; 28 | 29 | import com.mycompany.hr.service.HumanResourceService; 30 | 31 | public class HolidayEndpointTest { 32 | 33 | private Document holidayRequest; 34 | 35 | private HolidayEndpoint endpoint; 36 | 37 | private HumanResourceService serviceMock; 38 | 39 | private Calendar startCalendar; 40 | 41 | private Calendar endCalendar; 42 | 43 | @BeforeEach 44 | public void setUp() throws Exception { 45 | 46 | serviceMock = mock(HumanResourceService.class); 47 | SAXBuilder builder = new SAXBuilder(); 48 | InputStream is = getClass().getResourceAsStream("holidayRequest.xml"); 49 | try { 50 | holidayRequest = builder.build(is); 51 | } 52 | finally { 53 | is.close(); 54 | } 55 | endpoint = new HolidayEndpoint(serviceMock); 56 | startCalendar = Calendar.getInstance(); 57 | startCalendar.clear(); 58 | startCalendar.set(2006, Calendar.JULY, 3); 59 | endCalendar = Calendar.getInstance(); 60 | endCalendar.clear(); 61 | endCalendar.set(2006, Calendar.JULY, 7); 62 | } 63 | 64 | @Test 65 | public void handleHolidayRequest() throws Exception { 66 | 67 | serviceMock.bookHoliday(startCalendar.getTime(), endCalendar.getTime(), "John Doe"); 68 | 69 | endpoint.handleHolidayRequest(holidayRequest.getRootElement()); 70 | 71 | verify(serviceMock); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /tutorial/src/test/resources/com/mycompany/hr/ws/holidayRequest.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 2006-07-03 20 | 2006-07-07 21 | 22 | 23 | 42 24 | John 25 | Doe 26 | 27 | --------------------------------------------------------------------------------