36 |
Congratulations, your transaction was successfully completed !
37 |
38 |
39 |
40 |
41 |
42 | Transaction ID:
43 |
44 |
45 | | Stock Name |
46 | Quantity |
47 | Price per stock |
48 | Price |
49 |
50 |
51 |
52 |
53 |
54 | |
55 | |
56 | |
57 | |
58 |
59 |
60 |
61 |
62 |
63 |
64 | |
65 | |
66 |
67 | Service Charge
68 | |
69 |
70 | |
71 |
72 |
73 |
74 | |
75 | |
76 |
77 | Total
78 | |
79 |
80 | |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | Transaction ID:
92 |
93 |
94 | | Stock Name |
95 | Quantity |
96 | Price per stock |
97 | Price |
98 |
99 |
100 |
101 |
102 |
103 | |
104 | |
105 | |
106 | |
107 |
108 |
109 |
110 |
111 |
112 |
113 | |
114 | |
115 |
116 | Service Charge
117 | |
118 |
119 | |
120 |
121 |
122 |
123 | |
124 | |
125 |
126 | Total
127 | |
128 |
129 | |
130 |
131 |
132 |
133 |
134 |
135 |
Thank you for your business!
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
--------------------------------------------------------------------------------
/stocktrading/src/main/java/com/neu/edu/stocktrading/service/HomePageService.java:
--------------------------------------------------------------------------------
1 | package com.neu.edu.stocktrading.service;
2 |
3 | import java.util.ArrayList;
4 | import java.util.HashMap;
5 | import java.util.Iterator;
6 | import java.util.List;
7 | import java.util.Map;
8 |
9 | import com.fasterxml.jackson.databind.ObjectMapper;
10 | import com.neu.edu.stocktrading.dao.HomePageDAO;
11 | import com.neu.edu.stocktrading.model.Stock;
12 | import com.neu.edu.stocktrading.model.StockAPIBean;
13 |
14 | import org.json.simple.JSONArray;
15 | import org.json.simple.JSONObject;
16 | import org.json.simple.parser.JSONParser;
17 | import org.json.simple.parser.ParseException;
18 | import org.slf4j.Logger;
19 | import org.slf4j.LoggerFactory;
20 | import org.springframework.beans.factory.annotation.Autowired;
21 | import org.springframework.stereotype.Service;
22 | import org.springframework.web.client.RestTemplate;
23 |
24 | import net.sf.json.JSONSerializer;
25 |
26 | @Service
27 | public class HomePageService
28 | {
29 | @Autowired
30 | private HomePageDAO homePageDAO;
31 |
32 | private static final Logger logger = LoggerFactory.getLogger(HomePageService.class);
33 |
34 | @Autowired
35 | private RestTemplate restTemplate;
36 |
37 | // final String stockUri = "https://marketdata.websol.barchart.com/getQuote.json?apikey=b0ccbbb0dae9d39ce81f65718f0ecd10&symbols=AMZN,GOOG,AAPL,GOOG,NFLX,TSLA,FB,CSCO,ORCL,INTC,QCOM,EBAY,DELL,COST,MSFT,TWTR,AABA,SNAP,AMD,ATVI,ZNGA,WDC,BKNG&fields=fiftyTwoWkHigh%2CfiftyTwoWkHighDate%2CfiftyTwoWkLow%2CfiftyTwoWkLowDate";
38 | final String stockUri1 = "https://marketdata.websol.barchart.com/getQuote.json?apikey=b0ccbbb0dae9d39ce81f65718f0ecd10&symbols=AMZN,GOOG,AAPL,NFLX,TSLA,FB,CSCO,ORCL,INTC,QCOM,EBAY,DELL,COST,MSFT,TWTR,AABA,SNAP,AMD,ATVI,ZNGA&fields=fiftyTwoWkHigh%2CfiftyTwoWkHighDate%2CfiftyTwoWkLow%2CfiftyTwoWkLowDate";
39 |
40 | final String stockUri2 = "https://marketdata.websol.barchart.com/getQuote.json?apikey=b0ccbbb0dae9d39ce81f65718f0ecd10&symbols=WDC,BKNG,VZ,HPQ,SNE,W,BABA,JNJ,JPM,XOM,BAC,WMT,WFC,V,PG,BUD,T,UNH,HD,C&fields=fiftyTwoWkHigh%2CfiftyTwoWkHighDate%2CfiftyTwoWkLow%2CfiftyTwoWkLowDate";
41 |
42 |
43 |
44 | final String currencyUri = "https://www.worldtradingdata.com/api/v1/forex?base=USD&sort=newest&api_token=uRqeU8C651htqmF8iI5N6VvSBEIpTiQ5xvvKkz9Slsm1D9jFvIGdG97m0RpF";
45 |
46 | public List
getTopStocks ()
47 | {
48 | List stocks = new ArrayList();
49 |
50 | String result = this.restTemplate.getForObject(stockUri1, String.class);
51 | Object obj = null;
52 | JSONObject jo = null;
53 | try {
54 | obj = new JSONParser().parse(result);
55 | jo = (JSONObject) obj;
56 | } catch (ParseException e) {
57 | logger.error(e.toString());
58 | obj = null;
59 | jo = null;
60 | }
61 |
62 | if (obj != null && jo != null) {
63 | JSONArray ja = (JSONArray) jo.get("results");
64 |
65 | Iterator itr2 = ja.iterator();
66 |
67 | while (itr2.hasNext()) {
68 |
69 | Map map = (Map) itr2.next();
70 | ObjectMapper mapper = new ObjectMapper(); // jackson's objectmapper
71 | StockAPIBean pojo = mapper.convertValue(map, StockAPIBean.class);
72 | stocks.add(pojo);
73 | }
74 | }
75 |
76 | result = this.restTemplate.getForObject(stockUri2, String.class);
77 | obj = null;
78 | jo = null;
79 | try {
80 | obj = new JSONParser().parse(result);
81 | jo = (JSONObject) obj;
82 | } catch (ParseException e) {
83 | logger.error(e.toString());
84 | obj = null;
85 | jo = null;
86 | }
87 |
88 | if (obj != null && jo != null)
89 | {
90 | JSONArray ja = (JSONArray) jo.get("results");
91 |
92 | Iterator itr2 = ja.iterator();
93 |
94 | while (itr2.hasNext()) {
95 |
96 | Map map = (Map) itr2.next();
97 | ObjectMapper mapper = new ObjectMapper(); // jackson's objectmapper
98 | StockAPIBean pojo = mapper.convertValue(map, StockAPIBean.class);
99 | stocks.add(pojo);
100 | }
101 | }
102 |
103 | saveAllStocks(stocks);
104 |
105 | logger.info("size::" + stocks.size());
106 | return stocks;
107 |
108 | }
109 |
110 | public void saveAllStocks(List stocks)
111 | {
112 |
113 | logger.info("Saving stock object to database");
114 | for (StockAPIBean stock : stocks) {
115 | Stock temp = null;
116 | try {
117 | temp = this.homePageDAO.checkIfStockExists(stock.getSymbol());
118 | } catch (Exception e) {
119 | temp = null;
120 | }
121 | if (temp == null)
122 | {
123 | //this.homePageDAO.saveStock(stock);
124 | }
125 | else {
126 | this.homePageDAO.updateStock(stock, temp.getId());
127 |
128 | }
129 |
130 | }
131 | logger.info("Done updating stock table");
132 |
133 | }
134 |
135 | public Map getTopCurrencies ()
136 | {
137 | String result = this.restTemplate.getForObject(currencyUri, String.class);
138 |
139 | net.sf.json.JSONObject json = (net.sf.json.JSONObject) JSONSerializer.toJSON( result );
140 | net.sf.json.JSONObject data = json.getJSONObject("data");
141 |
142 | Map map = new HashMap();
143 | Iterator iter = data.keys();
144 |
145 | while(iter.hasNext())
146 | {
147 | String key = (String)iter.next();
148 | String value = data.getString(key);
149 | map.put(key,value);
150 | }
151 |
152 | Map resultMap = new HashMap();
153 |
154 | String eur = map.get("EUR");
155 | String jpy = map.get("JPY");
156 | String inr = map.get("INR");
157 |
158 | resultMap.put("Euro", eur);
159 | resultMap.put("Yen", jpy);
160 | resultMap.put("Rupee", inr);
161 |
162 | return resultMap;
163 |
164 | }
165 |
166 |
167 |
168 | }
--------------------------------------------------------------------------------
/stocktrading/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM https://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM set title of command window
39 | title %0
40 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
42 |
43 | @REM set %HOME% to equivalent of $HOME
44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
45 |
46 | @REM Execute a user defined script before this one
47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
49 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
50 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
51 | :skipRcPre
52 |
53 | @setlocal
54 |
55 | set ERROR_CODE=0
56 |
57 | @REM To isolate internal variables from possible post scripts, we use another setlocal
58 | @setlocal
59 |
60 | @REM ==== START VALIDATION ====
61 | if not "%JAVA_HOME%" == "" goto OkJHome
62 |
63 | echo.
64 | echo Error: JAVA_HOME not found in your environment. >&2
65 | echo Please set the JAVA_HOME variable in your environment to match the >&2
66 | echo location of your Java installation. >&2
67 | echo.
68 | goto error
69 |
70 | :OkJHome
71 | if exist "%JAVA_HOME%\bin\java.exe" goto init
72 |
73 | echo.
74 | echo Error: JAVA_HOME is set to an invalid directory. >&2
75 | echo JAVA_HOME = "%JAVA_HOME%" >&2
76 | echo Please set the JAVA_HOME variable in your environment to match the >&2
77 | echo location of your Java installation. >&2
78 | echo.
79 | goto error
80 |
81 | @REM ==== END VALIDATION ====
82 |
83 | :init
84 |
85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
86 | @REM Fallback to current working directory if not found.
87 |
88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
90 |
91 | set EXEC_DIR=%CD%
92 | set WDIR=%EXEC_DIR%
93 | :findBaseDir
94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
95 | cd ..
96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
97 | set WDIR=%CD%
98 | goto findBaseDir
99 |
100 | :baseDirFound
101 | set MAVEN_PROJECTBASEDIR=%WDIR%
102 | cd "%EXEC_DIR%"
103 | goto endDetectBaseDir
104 |
105 | :baseDirNotFound
106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
107 | cd "%EXEC_DIR%"
108 |
109 | :endDetectBaseDir
110 |
111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
112 |
113 | @setlocal EnableExtensions EnableDelayedExpansion
114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
116 |
117 | :endReadAdditionalConfig
118 |
119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
122 |
123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
124 | FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO (
125 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
126 | )
127 |
128 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
129 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data.
130 | if exist %WRAPPER_JAR% (
131 | echo Found %WRAPPER_JAR%
132 | ) else (
133 | echo Couldn't find %WRAPPER_JAR%, downloading it ...
134 | echo Downloading from: %DOWNLOAD_URL%
135 | powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"
136 | echo Finished downloading %WRAPPER_JAR%
137 | )
138 | @REM End of extension
139 |
140 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
141 | if ERRORLEVEL 1 goto error
142 | goto end
143 |
144 | :error
145 | set ERROR_CODE=1
146 |
147 | :end
148 | @endlocal & set ERROR_CODE=%ERROR_CODE%
149 |
150 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
151 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
152 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
153 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
154 | :skipRcPost
155 |
156 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
157 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
158 |
159 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
160 |
161 | exit /B %ERROR_CODE%
162 |
--------------------------------------------------------------------------------
/stocktrading/src/main/java/com/neu/edu/stocktrading/controller/StockTradeController.java:
--------------------------------------------------------------------------------
1 | package com.neu.edu.stocktrading.controller;
2 |
3 | import java.io.ByteArrayInputStream;
4 | import java.util.ArrayList;
5 | import java.util.HashMap;
6 | import java.util.List;
7 | import java.util.Map;
8 | import java.util.Random;
9 |
10 | import javax.servlet.http.HttpServletRequest;
11 |
12 | import com.mysql.cj.Session;
13 | import com.neu.edu.stocktrading.model.Trade;
14 | import com.neu.edu.stocktrading.model.Transaction;
15 | import com.neu.edu.stocktrading.model.User;
16 | import com.neu.edu.stocktrading.service.StockTradeService;
17 | import com.neu.edu.stocktrading.util.FileReaderUtil;
18 | import com.neu.edu.stocktrading.util.GeneratePdfUtil;
19 | import com.neu.edu.stocktrading.util.SessionManagementUtil;
20 |
21 | import org.slf4j.Logger;
22 | import org.slf4j.LoggerFactory;
23 | import org.springframework.beans.factory.annotation.Autowired;
24 | import org.springframework.core.io.InputStreamResource;
25 | import org.springframework.http.HttpHeaders;
26 | import org.springframework.http.MediaType;
27 | import org.springframework.http.ResponseEntity;
28 | import org.springframework.stereotype.Controller;
29 | import org.springframework.web.bind.annotation.GetMapping;
30 | import org.springframework.web.bind.annotation.PostMapping;
31 | import org.springframework.web.bind.annotation.RequestBody;
32 | import org.springframework.web.servlet.ModelAndView;
33 |
34 | @Controller
35 | public class StockTradeController {
36 | private static final Logger logger = LoggerFactory.getLogger(StockTradeController.class);
37 |
38 | @Autowired
39 | private StockTradeService stockTradeService;
40 |
41 | @Autowired
42 | private SessionManagementUtil sessionMgmtUtils;
43 |
44 | @PostMapping(value = "/check/account.htm" , consumes = MediaType.APPLICATION_JSON_VALUE)
45 | public ResponseEntity> checkIfAccountAttached (HttpServletRequest request , @RequestBody HashMap stockSymbol)
46 | {
47 | logger.info("checkIfAccountAttached::");
48 | String email = (String) request.getSession().getAttribute("user");
49 | User user = this.stockTradeService.getProfileAttributes(email);
50 |
51 | boolean result = this.stockTradeService.checkIfAccountAttached(user);
52 |
53 | if (!result){
54 | return ResponseEntity.badRequest().body("No user bank details found for user");
55 | }
56 | else {
57 | Map res = new HashMap();
58 | res.put("result", "Success");
59 | return ResponseEntity.ok(res);
60 | }
61 |
62 | }
63 |
64 | @PostMapping(value = "/trade/watchlist.htm")
65 | public ModelAndView addToTrade(HttpServletRequest request) {
66 | logger.info("addToTrade::");
67 | String email = (String) request.getSession().getAttribute("user");
68 | User user = this.stockTradeService.getProfileAttributes(email);
69 |
70 | String[] stockSymbols = request.getParameterValues("checkedRows");
71 |
72 | Map> stockList = this.stockTradeService.retrieveBuyList(user, stockSymbols);
73 | ModelAndView mv = new ModelAndView();
74 | mv.addObject("stockList", stockList);
75 | mv.setViewName("user-trade");
76 |
77 | request.getSession().setAttribute("stockList", stockList);
78 |
79 | return mv;
80 | }
81 |
82 | @PostMapping(value = "/trade/transaction.htm")
83 | public ModelAndView showTradeTransaction(HttpServletRequest request) {
84 | logger.info("showTradeTransaction::");
85 | String email = (String) request.getSession().getAttribute("user");
86 | User user = this.stockTradeService.getProfileAttributes(email);
87 |
88 | String[] quantities = request.getParameterValues("quantity");
89 |
90 | String[] selling = request.getParameterValues("checkedRows");
91 |
92 | Map> stockList = (Map>) request.getSession()
93 | .getAttribute("stockList");
94 |
95 | List extends Object> stockBuying = stockList.get("Buy");
96 |
97 | ModelAndView mv = new ModelAndView();
98 | mv.setViewName("user-transaction");
99 |
100 | mv.addObject("transactionBuyId", new Random().nextInt(1000000));
101 | mv.addObject("transactionSellId", new Random().nextInt(1000000));
102 |
103 | Transaction t = this.stockTradeService.completeTransaction(user, quantities, stockBuying, selling);
104 | logger.info("showTradeTransaction::"+t.getId());
105 |
106 | List currentBuyTrades = this.stockTradeService.getBuyTradesUsingCurrentTransaction (user , t);
107 |
108 | List currentSellTrades = new ArrayList();
109 | currentSellTrades = this.stockTradeService.getSellTradesUsingCurrentTransaction (user , t);
110 |
111 |
112 |
113 | mv.addObject("tradeBuyList", currentBuyTrades);
114 | mv.addObject("tradeSellList", currentSellTrades);
115 |
116 |
117 |
118 |
119 | Double serviceCharge = Double.parseDouble( FileReaderUtil.readServiceChargeValue() );
120 | Double buyTax = (serviceCharge/100 * this.stockTradeService.getTotalPrice(currentBuyTrades));
121 | mv.addObject("serviceBuyTax", buyTax);
122 |
123 | Double sellTax = (serviceCharge/100 * this.stockTradeService.getTotalPrice(currentSellTrades));
124 | mv.addObject("serviceSellTax", sellTax);
125 |
126 | mv.addObject("totalBuyPrice", this.stockTradeService.getTotalPrice(currentBuyTrades) + buyTax);
127 | mv.addObject("totalSellPrice", this.stockTradeService.getTotalPrice(currentSellTrades) + sellTax);
128 |
129 | return mv;
130 | }
131 |
132 | @GetMapping(value = "/statement.htm")
133 | public ModelAndView home(HttpServletRequest request)
134 | {
135 | if (!this.sessionMgmtUtils.doesSessionExist(request))
136 | {
137 | logger.info("Please login to access this page");
138 | ModelAndView mv = new ModelAndView("login-form");
139 | mv.addObject("user", new User());
140 | mv.addObject("errorMessage", "Please login to access this page");
141 | return mv;
142 |
143 | }
144 |
145 | ModelAndView mv = new ModelAndView("account-statement");
146 | String email = (String) request.getSession().getAttribute("user");
147 |
148 | List temp = this.stockTradeService.getAllTransactions(email);
149 |
150 | List result = new ArrayList();
151 | if (temp !=null)
152 | {
153 | for (Transaction t : temp)
154 | {
155 | if (Double.compare(t.getTotalPrice(), 0.0) !=0)
156 | {
157 | result.add(t);
158 | }
159 | }
160 | }
161 |
162 | mv.addObject("transactionList", result);
163 | return mv;
164 | }
165 |
166 | @GetMapping(value = "/transaction.pdf" , produces = MediaType.APPLICATION_PDF_VALUE)
167 | public ResponseEntity generatePdf(HttpServletRequest request)
168 | {
169 | String email = (String) request.getSession().getAttribute("user");
170 | List temp = this.stockTradeService.getAllTransactions(email);
171 | List result = new ArrayList();
172 | if (temp !=null)
173 | {
174 | for (Transaction t : temp)
175 | {
176 | if (Double.compare(t.getTotalPrice(), 0.0) !=0)
177 | {
178 | result.add(t);
179 | }
180 | }
181 | }
182 |
183 | ByteArrayInputStream bis = GeneratePdfUtil.transactionReport(result);
184 |
185 | HttpHeaders headers = new HttpHeaders();
186 | headers.add("Content-Disposition", "inline; filename=transactionReport.pdf");
187 |
188 | return ResponseEntity
189 | .ok()
190 | .headers(headers)
191 | .contentType(MediaType.APPLICATION_PDF)
192 | .body(new InputStreamResource(bis));
193 |
194 | }
195 |
196 | }
--------------------------------------------------------------------------------