Vaadin 23 Rest-API and UI in Spring Boot app - java

I've developed a small application with Vaadin 23.3.5. Until now I only used Spring Boot Security in combination with the default LoginView to authenticate and then use the MainLayout to navigate through my application. But now I require the possibility to access certain informations from outside the app. So the best way to do that would be to implement a REST-API.
But no matter what I try, I just can't seem to get it working. I read that I should not use JAX-RS with Spring Boot applications when I want to have stateless webservices, so I tried to stick with libraries offered by Spring. I also tried to integrate working examples from other people into my application, but none of them worked for me.
I want to have some configuration, when I use http://localhost:8080/project/ui, then I can access my view layer (i.e. LoginView), but when I use http://localhost:8080/project/api, I want to be able to call my webservices.
in my applicatoin.properties, I declared "/project" to be my context-path and "/ui/*" to be my urlMapping like this:
server.servlet.context-path=/project
server.port=${PORT:8080}
vaadin.urlMapping=/ui/*
vaadin.excludeUrls=/api/**
My configuration used in my class extending from VaadinWebSecurity:
#Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
setLoginView(http, LoginView.class, LOGOUT_SUCCESS_URL);
this.applyUrlMapping("api");
http.rememberMe().key("ABC")
.tokenValiditySeconds(2 * 24 * 60 * 60)
.userDetailsService(this.userDetailsService);
http.logout()
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID", "remember-me");
}
#Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
web.ignoring().antMatchers("/images/*.png");
}
and finally my Controller class I want to access via postman:
#RequestMapping("/test")
#RestController()
public class TestRestController {
#GetMapping("/hello")
public String hello() {
return "Hello World!";
}
}
It seems like I can access the "hello"-method when using http://localhost:8080/project/test/hello in my browser, but there are two things not working:
the "/api/*" path is not recognized
(this is more critical) when I use postman to access the same resource, I can some auto-generated doc as response instead of "Hello World"...
<!doctype html><!--
This file is auto-generated by Vaadin.
-->
<html lang="en">
<head>
<script initial="">window.Vaadin = window.Vaadin || {};window.Vaadin.VaadinLicenseChecker = { maybeCheck: (productInfo) => { }};window.Vaadin.devTools = window.Vaadin.devTools || {};window.Vaadin.devTools.createdCvdlElements = window.Vaadin.devTools.createdCvdlElements || [];const originalCustomElementDefineFn = window.customElements.define;window.customElements.define = function (tagName, constructor, ...args) {const { cvdlName, version } = constructor;if (cvdlName && version) { const { connectedCallback } = constructor.prototype; constructor.prototype.connectedCallback = function () { window.Vaadin.devTools.createdCvdlElements.push(this); if (connectedCallback) { connectedCallback.call(this); } }}originalCustomElementDefineFn.call(this, tagName, constructor, ...args);};</script>
<script initial="">window.Vaadin = window.Vaadin || {};window.Vaadin.ConsoleErrors = window.Vaadin.ConsoleErrors || [];const browserConsoleError = window.console.error.bind(window.console);console.error = (...args) => { browserConsoleError(...args); window.Vaadin.ConsoleErrors.push(args);};window.onerror = (message, source, lineno, colno, error) => {const location=source+':'+lineno+':'+colno;window.Vaadin.ConsoleErrors.push([message, '('+location+')']);};window.addEventListener('unhandledrejection', e => { window.Vaadin.ConsoleErrors.push([e.reason]);});</script>
<script initial="">window.Vaadin = window.Vaadin || {};window.Vaadin.TypeScript= {};</script>
<meta name="_csrf_parameter" content="_csrf">
<meta name="_csrf_header" content="X-CSRF-TOKEN">
<meta name="_csrf" content="df39cb78-0c37-4125-8d87-68e986050db5"><base href=".">
<script type="text/javascript">window.JSCompiler_renameProperty = function(a) { return a;}</script>
<script type="module">import { inject } from "/project/ui/VAADIN/#vite-plugin-checker-runtime";
inject({
overlayConfig: {},
base: "/project/ui/VAADIN/",
});</script>
<script type="module" src="/project/ui/VAADIN/#vite/client"></script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body, #outlet {
height: 100vh;
width: 100%;
margin: 0;
}
</style> <!-- index.ts is included here automatically (either by the dev server or during the build) -->
<script type="module" src="/project/ui/VAADIN/generated/vite-devmode.ts"></script>
<script type="module" src="/project/ui/VAADIN/generated/vaadin.ts"></script>
<style>.v-reconnect-dialog,.v-system-error {position: absolute;color: black;background: white;top: 1em;right: 1em;border: 1px solid black;padding: 1em;z-index: 10000;max-width: calc(100vw - 4em);max-height: calc(100vh - 4em);overflow: auto;} .v-system-error {color: indianred;pointer-events: auto;} .v-system-error h3, .v-system-error b {color: red;}</style>
<style>[hidden] { display: none !important; }</style>
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-touch-fullscreen" content="yes">
<meta name="apple-mobile-web-app-title" content="project">
<meta name="theme-color" content="#ffffff">
<meta name="apple-mobile-web-app-status-bar-style" content="#ffffff">
<link rel="manifest" href="manifest.webmanifest">
<link sizes="16x16" rel="shortcut icon" href="icons/icon-16x16.png" type="image/png">
<link sizes="32x32" rel="icon" href="icons/icon-32x32.png" type="image/png">
<link sizes="96x96" rel="icon" href="icons/icon-96x96.png?1713631522" type="image/png">
<link sizes="180x180" rel="apple-touch-icon" href="icons/icon-180x180.png?-533695959" type="image/png">
<link sizes="2048x2732" rel="apple-touch-startup-image" media="screen and (device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="icons/icon-2048x2732.png?-1201942874" type="image/png">
<link sizes="2732x2048" rel="apple-touch-startup-image" media="screen and (device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="icons/icon-2732x2048.png?266277477" type="image/png">
<link sizes="1668x2388" rel="apple-touch-startup-image" media="screen and (device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="icons/icon-1668x2388.png?-1539431919" type="image/png">
<link sizes="2388x1668" rel="apple-touch-startup-image" media="screen and (device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="icons/icon-2388x1668.png?598404288" type="image/png">
<link sizes="1668x2224" rel="apple-touch-startup-image" media="screen and (device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="icons/icon-1668x2224.png?1678662124" type="image/png">
<link sizes="2224x1668" rel="apple-touch-startup-image" media="screen and (device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="icons/icon-2224x1668.png?746534339" type="image/png">
<link sizes="1620x2160" rel="apple-touch-startup-image" media="screen and (device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="icons/icon-1620x2160.png?-770300885" type="image/png">
<link sizes="2160x1620" rel="apple-touch-startup-image" media="screen and (device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="icons/icon-2160x1620.png?-525914264" type="image/png">
<link sizes="1536x2048" rel="apple-touch-startup-image" media="screen and (device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="icons/icon-1536x2048.png?713310212" type="image/png">
<link sizes="2048x1536" rel="apple-touch-startup-image" media="screen and (device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="icons/icon-2048x1536.png?1750378074" type="image/png">
<link sizes="1284x2778" rel="apple-touch-startup-image" media="screen and (device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="icons/icon-1284x2778.png?1984992155" type="image/png">
<link sizes="2778x1284" rel="apple-touch-startup-image" media="screen and (device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="icons/icon-2778x1284.png?389448020" type="image/png">
<link sizes="1170x2532" rel="apple-touch-startup-image" media="screen and (device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="icons/icon-1170x2532.png?-743684054" type="image/png">
<link sizes="2532x1170" rel="apple-touch-startup-image" media="screen and (device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="icons/icon-2532x1170.png?2114630635" type="image/png">
<link sizes="1125x2436" rel="apple-touch-startup-image" media="screen and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="icons/icon-1125x2436.png?-688834165" type="image/png">
<link sizes="2436x1125" rel="apple-touch-startup-image" media="screen and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="icons/icon-2436x1125.png?-221066565" type="image/png">
<link sizes="1242x2688" rel="apple-touch-startup-image" media="screen and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="icons/icon-1242x2688.png?-313405698" type="image/png">
<link sizes="2688x1242" rel="apple-touch-startup-image" media="screen and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="icons/icon-2688x1242.png?20506735" type="image/png">
<link sizes="828x1792" rel="apple-touch-startup-image" media="screen and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="icons/icon-828x1792.png?1276193420" type="image/png">
<link sizes="1792x828" rel="apple-touch-startup-image" media="screen and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="icons/icon-1792x828.png?1725405299" type="image/png">
<link sizes="1242x2208" rel="apple-touch-startup-image" media="screen and (device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="icons/icon-1242x2208.png?1508207887" type="image/png">
<link sizes="2208x1242" rel="apple-touch-startup-image" media="screen and (device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="icons/icon-2208x1242.png?-167637239" type="image/png">
<link sizes="750x1334" rel="apple-touch-startup-image" media="screen and (device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="icons/icon-750x1334.png?-1346703542" type="image/png">
<link sizes="1334x750" rel="apple-touch-startup-image" media="screen and (device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="icons/icon-1334x750.png?-1196513029" type="image/png">
<link sizes="640x1136" rel="apple-touch-startup-image" media="screen and (device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="icons/icon-640x1136.png?893776263" type="image/png">
<link sizes="1136x640" rel="apple-touch-startup-image" media="screen and (device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="icons/icon-1136x640.png?-1834685424" type="image/png">
<script>if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('sw.js')
});
}</script>
</head>
<body><!-- This outlet div is where the views are rendered -->
<div id="outlet"></div>
<script>window.Vaadin = window.Vaadin || {};
window.Vaadin.registrations = window.Vaadin.registrations || [];
window.Vaadin.registrations.push({"is":"flow/SpringInstantiator","version":"23.3.0.alpha1"},{"is":"routing/server","version":"23.3.0.alpha1"},{"is":"flow/AtmospherePushConnection","version":"2.7.3.slf4jvaadin4"},{"is":"java","version":"17.0.5"});</script><vaadin-dev-tools url="" springbootlivereloadport="35729"></vaadin-dev-tools>
</body>
</html>
I tried using code examples from Stackoverflow and the official Vaadin forum, as well as examples from Github and other places. But I found no example or description that would fit my requirements as having both ":8080/project/ui/" and ":8080/project/api/" working together.
Could anyone possibly point me in the right direction please?

#RequestMapping("/test")
does not contain api! So it should be:
#RequestMapping("/api/test")
Then you must also adjust the security configuration:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.requestMatchers(new AntPathRequestMatcher("/api/**").permitAll();
super.configure(http);
setLoginView(http, LoginView.class, LOGOUT_SUCCESS_URL);
http.rememberMe().key("ABC")
.tokenValiditySeconds(2 * 24 * 60 * 60)
.userDetailsService(this.userDetailsService);
http.logout()
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID", "remember-me");
}
#Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
web.ignoring().antMatchers("/images/*.png");
}

Related

Spring Boot ignores CSS / JS when loading page

My page (order.mustache) uses several CSS styles (external and local), images, background video and JS element. Most of the page layout is described in style.css, which is located in the 'resourses/static/css' directory.
When I start a page through Chrome as an HTML document, it displays correctly. But if I run it through Spring Boot (as a mustache page) - all local styles, images, JS and even youtube videos are ignored.
The browser console indicates an error 'Resource interpreted as Stylesheet but transferred with MIME type text / html:' http: // localhost: 8080 / static / css / style.css'.' On the Response tab of the Chrome developer panel, style.css is displayed as a copy of the order.mustache page. On the Headers tab, its type is text / html.
I can’t understand at what point these changes are happening, and what should I change so that the page works properly.
HTML:
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>...</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link href="../static/css/style.css" type="text/css" rel="stylesheet">
<link href='http://fonts.googleapis.com/css?family=Roboto:400,300,100,500,700,900' rel='stylesheet' type="text/css">
<link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet" type="text/css">
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
</head>
Controller:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Date;
import java.util.Map;
#Controller
public class GreetingController {
#Autowired
private ClientRepo repo;
#GetMapping
public String main(Map<String, Object> model) {
Iterable<Client> clients = repo.findAll();
model.put("clients", clients);
return "order";
}
#PostMapping
public String add(#RequestParam String firstName, #RequestParam String lastName, #RequestParam String nationality,
#RequestParam String sex, #RequestParam Date birthDate, #RequestParam long passNumber, Map<String, Object> model) {
Client client = new Client(firstName, lastName, nationality, sex, birthDate, passNumber);
repo.save(client);
Iterable<Client> clients = repo.findAll();
model.put("clients", client);
return "order";
}
}
Main:
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
public ViewResolver getViewResolver(ResourceLoader resourceLoader) {
MustacheViewResolver mustacheViewResolver
= new MustacheViewResolver();
mustacheViewResolver.setPrefix("templates/");
mustacheViewResolver.setSuffix(".mustache");
mustacheViewResolver.setCache(false);
return mustacheViewResolver;
}
Try to swap
<link href="../static/css/style.css" type="text/css" rel="stylesheet">
Maybe your custom styles cannot load after bootstrap.
Do like that :
<!-- My styles firstly -->
<link href="../static/css/style.css" type="text/css" rel="stylesheet">
<!-- And then bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link href='http://fonts.googleapis.com/css?family=Roboto:400,300,100,500,700,900' rel='stylesheet' type="text/css">
<link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet" type="text/css">

xlsx file becomes corrupt/ empty(0 bytes) sending across in a http request

I am sending an xlsx file over http request but the file becomes corrupt.
I just dont understand why the file becomes corrupt just sending across.
Please help, I am new at this.
Here is the jsp file :
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html ng-app="myApplication">
<head>
<!-- <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> -->
<title>Preptune</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script>
angular.module('myApplication',["ngRoute"]).
directive('fileInput',['$parse',function($parse){
return {
restrict:'A',
link: function(scope,elm,attrs) {
elm.bind('change',function() {
$parse(attrs.fileInput)
.assign(scope,elm[0].files)
scope.$apply()
})
}
}
}])
.controller('myController',['$scope','$http',
function($scope,$http) {
$scope.message = "Test message";
$scope.filesChanged = function(elm) {
$scope.files=elm.files;
$scope.$apply();
};
$scope.upload = function() {
var fd = new FormData();
angular.forEach($scope.files,function(file){
fd.append('file',file);
})
$http.post('http://localhost:80/simple-web-services/uploadQuestions', fd,{
transformRequest : angular.identity,
headers:{'Content-Type':undefined}
})
.success(function(d){
console.log(d);
})
};
}
])
.config(function($routeProvider) {
$routeProvider
.when("/preptune", {
templateUrl : "/webPortal/homePage/welcome"
})
.when("/upload", {
templateUrl : "/webPortal/resources/html/uploadQuestion.html"
})
.when("/download", {
templateUrl : "/webPortal/resources/html/downloadTemplate.html"
})
.otherwise({redirectTo:'/'});
});
</script>
</head>
<body ng-controller="myController">
<nav class="navbar navbar-default">
<div class="container-fluid bg-info">
<div class="navbar-header">
<a class="navbar-brand" href="#prep">Prep</a>
</div>
<ul class="nav navbar-nav">
<li>Upload Question Paper</li>
<li>Download Question Template</li>
</ul>
</div>
</nav>
<div ng-view></div>
</body>
</html>
Here is the form : (uploadQuestion.html)
<form method="post">
<input type="file"
file-input="files"
multiple></input>
<button ng-click="upload()"> Upload </button>
<li ng-repeat="file in files" >{{file.name}} </li>
</form>
The exception says
java.lang.RuntimeException: org.apache.cxf.interceptor.Fault: Your InputStream was neither an OLE2 stream, nor an OOXML stream

Spring Boot + Swagger + custom swagger-ui.html

I've got problems migrating a war application to a spring boot jar application.
I'm using spring boot 1.4.1 and swagger 2.6.0.
To customize swagger ui in a war you have to put a custom swagger-ui.html to /webapp directory. In spring boot it is not recommend to use the webapp directory because it does not work in a bundled jar. But putting a custom swagger-ui.html to /resources/static will be ignored by swagger.
Is there any simple solution (instead of adding the whole swagger distribution to my application)?
My custom swagger-ui.html looks like
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>API</title>
<link rel="icon" type="image/png" href="webjars/springfox-swagger-ui/images/favicon-32x32.png" sizes="32x32"/>
<link rel="icon" type="image/png" href="webjars/springfox-swagger-ui/images/favicon-16x16.png" sizes="16x16"/>
<link href='webjars/springfox-swagger-ui/css/typography.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='webjars/springfox-swagger-ui/css/reset.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='webjars/springfox-swagger-ui/css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='webjars/springfox-swagger-ui/css/reset.css' media='print' rel='stylesheet' type='text/css'/>
<link href='webjars/springfox-swagger-ui/css/print.css' media='print' rel='stylesheet' type='text/css'/>
<script src='webjars/springfox-swagger-ui/lib/jquery-1.8.0.min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/jquery.slideto.min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/jquery.wiggle.min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/handlebars-2.0.0.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/underscore-min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/backbone-min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/swagger-ui.min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/highlight.7.3.pack.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/jsoneditor.min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/marked.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/swagger-oauth.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/springfox.js' type='text/javascript'></script>
<style>
.swagger-section #header {
background-color: #ff5722;
}
</style>
</head>
<body class="swagger-section">
<div id='header'>
<div class="swagger-ui-wrap">
<a id="logo" href="http://www.my-app.com">my-app.com API</a>
<form id='api_selector'>
<div class='input' style="display: none">
<select id="select_baseUrl" name="select_baseUrl"/>
</div>
<div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl"
type="text"/>
</div>
<!--
<div class='input'><input placeholder="Enter authorization token" id="input_apiKey" name="apiKey" type="text"/></div>
<div class='input' style="display: none"><a id="explore" href="#" data-sw-translate>Explore</a></div>
-->
</form>
</div>
</div>
<script type="text/javascript">
function addApiKeyAuthorization() {
var key = $('#input_apiKey')[0].value;
console.log("key: " + key);
if (key && key.trim() != "") {
var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("Authorization", key, "header");
window.swaggerUi.api.clientAuthorizations.add("bearer", apiKeyAuth);
//window.authorizations.add("Authorization", new ApiKeyAuthorization("Authorization", key, "query"));
console.log("Set authorization token: " + key);
}
}
$('#input_apiKey').change(function () {
addApiKeyAuthorization();
});
</script>
<div id="message-bar" class="swagger-ui-wrap" data-sw-translate> </div>
<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
</body>
</html>
I have found this simple way to customize Swagger into a Spring Boot application with just two files copied from original springfox-swagger-ui
First of all i have disabled #Configuration from SwaggerConfig.java:
//#Configuration <-- Attention, disable Configuration
#EnableSwagger2
public class SwaggerConfig {
#Bean
public Docket productApi() {
return new Docket(DocumentationType.SWAGGER_2)
.ignoredParameterTypes(Pageable.class)
.select().apis(RequestHandlerSelectors.any())
.paths(regex("/v1/.*"))
.build();
}
}
Then I have extended a WebMvcConfigurerAdapter:
#Configuration
#Import(SwaggerConfig.class)
public class MvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/doc/v1/**").addResourceLocations("classpath:/doc/v1/");
registry.addResourceHandler("/doc/v1/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
Then I have just copied original file swagger-ui.html into src/main/resources/doc/v1/api.html with just a simple modification.
I have substituted this line:
<script src='webjars/springfox-swagger-ui/springfox.js' type='text/javascript'></script>
with this line:
<script src='js/swagger.js' type='text/javascript'></script>
This is my api.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link rel="icon" type="image/png" href="webjars/springfox-swagger-ui/images/favicon-32x32.png" sizes="32x32"/>
<link rel="icon" type="image/png" href="webjars/springfox-swagger-ui/images/favicon-16x16.png" sizes="16x16"/>
<link href='webjars/springfox-swagger-ui/css/typography.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='webjars/springfox-swagger-ui/css/reset.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='webjars/springfox-swagger-ui/css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='webjars/springfox-swagger-ui/css/reset.css' media='print' rel='stylesheet' type='text/css'/>
<link href='webjars/springfox-swagger-ui/css/print.css' media='print' rel='stylesheet' type='text/css'/>
<script src='webjars/springfox-swagger-ui/lib/object-assign-pollyfill.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/jquery-1.8.0.min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/jquery.slideto.min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/jquery.wiggle.min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/handlebars-4.0.5.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/lodash.min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/backbone-min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/swagger-ui.min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/highlight.9.1.0.pack.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/highlight.9.1.0.pack_extended.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/jsoneditor.min.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/marked.js' type='text/javascript'></script>
<script src='webjars/springfox-swagger-ui/lib/swagger-oauth.js' type='text/javascript'></script>
<script src='js/springfox.js' type='text/javascript'></script>
</head>
<body class="swagger-section">
<div id='header'>
<div class="swagger-ui-wrap">
<a id="logo" href="http://swagger.io"><img class="logo__img" alt="swagger" height="30" width="30" src="webjars/springfox-swagger-ui/images/logo_small.png" /><span class="logo__title">swagger</span></a>
<form id='api_selector'>
<div class='input'>
<select id="select_baseUrl" name="select_baseUrl"/>
</div>
<div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text"/></div>
<div id='auth_container'></div>
<div class='input'><a id="explore" class="header__btn" href="#" data-sw-translate>Explore</a></div>
</form>
</div>
</div>
<div id="message-bar" class="swagger-ui-wrap" data-sw-translate> </div>
<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
</body>
</html>
After that i have copied original springfox.js into src/main/resources/doc/v1/js/springfox.js where i have changed these lines:
"baseUrl": function() {
var urlMatches = /(.*)\/swagger-ui.html.*/.exec(window.location.href);
return urlMatches[1];
},
with these lines:
"baseUrl": function() {
return window.location.origin;
},
This is my complete springfox.js
$(function() {
var springfox = {
"baseUrl": function() {
return window.location.origin;
},
"securityConfig": function(cb) {
$.getJSON(this.baseUrl() + "/swagger-resources/configuration/security", function(data) {
cb(data);
});
},
"uiConfig": function(cb) {
$.getJSON(this.baseUrl() + "/swagger-resources/configuration/ui", function(data) {
cb(data);
});
}
};
window.springfox = springfox;
window.oAuthRedirectUrl = springfox.baseUrl() + '/webjars/springfox-swagger-ui/o2c.html';
window.springfox.uiConfig(function(data) {
window.swaggerUi = new SwaggerUi({
dom_id: "swagger-ui-container",
validatorUrl: data.validatorUrl,
supportedSubmitMethods: data.supportedSubmitMethods || ['get', 'post', 'put', 'delete', 'patch'],
docExpansion: data.docExpansion || 'none',
jsonEditor: JSON.parse(data.jsonEditor) || false,
apisSorter: data.apisSorter || 'alpha',
defaultModelRendering: data.defaultModelRendering || 'schema',
showRequestHeaders: data.showRequestHeaders || true,
timeout: data.requestTimeout,
onComplete: function(swaggerApi, swaggerUi) {
initializeSpringfox();
if (window.SwaggerTranslator) {
window.SwaggerTranslator.translate();
}
$('pre code').each(function(i, e) {
hljs.highlightBlock(e)
});
},
onFailure: function(data) {
log("Unable to Load SwaggerUI");
},
});
initializeBaseUrl();
function addApiKeyAuthorization(security) {
var apiKeyVehicle = security.apiKeyVehicle || 'query';
var apiKeyName = security.apiKeyName || 'api_key';
var apiKey = security.apiKey || '';
if (apiKey && apiKey.trim() != "") {
var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization(apiKeyName, apiKey, apiKeyVehicle);
window.swaggerUi.api.clientAuthorizations.add(apiKeyName, apiKeyAuth);
log("added key " + apiKey);
}
}
function log() {
if ('console' in window) {
console.log.apply(console, arguments);
}
}
function oAuthIsDefined(security) {
return security.clientId
&& security.clientSecret
&& security.appName
&& security.realm;
}
function initializeSpringfox() {
var security = {};
window.springfox.securityConfig(function(data) {
security = data;
addApiKeyAuthorization(security);
if (typeof initOAuth == "function" && oAuthIsDefined(security)) {
initOAuth(security);
}
});
}
});
$('#select_baseUrl').change(function() {
window.swaggerUi.headerView.trigger('update-swagger-ui', {
url: $('#select_baseUrl').val()
});
});
function maybePrefix(location, withRelativePath) {
var pat = /^https?:\/\//i;
if (pat.test(location)) {
return location;
}
return withRelativePath + location;
}
function initializeBaseUrl() {
var relativeLocation = springfox.baseUrl();
$('#input_baseUrl').hide();
$.getJSON(relativeLocation + "/swagger-resources", function(data) {
var $urlDropdown = $('#select_baseUrl');
$urlDropdown.empty();
$.each(data, function(i, resource) {
var option = $('<option></option>')
.attr("value", maybePrefix(resource.location, relativeLocation))
.text(resource.name + " (" + resource.location + ")");
$urlDropdown.append(option);
});
$urlDropdown.change();
});
}
});
This is my folder structure
Now you have just to run application and go to http://localhost:8080/doc/v1/api.html
Solution if you are using maven:
You should copy swagger-ui.html into src/main/webapp
Make your editions or replace screen.css by your theme.css
Than add these code into your pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resource>
<directory>${basedir}/src/main/webapp</directory>
<filtering>true</filtering>
<includes>
<include>*.css</include>
<include>*.html</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>

Recieving JSON data on server but not able to display it in jqgrid

Not able to display the json data on jsp using jqgrid.
Need help eagarly.
Please find my JSP below:
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<!-- <link rel="stylesheet" type="text/css" media="screen" href="css/jquery-ui-1.10.2.custom.css" /> -->
<link rel="stylesheet" type="text/css" media="screen" href="css/jquery-ui.css" />
<link rel="stylesheet" type="text/css" media="screen" href="css/ui.jqgrid.css" />
<script src="js/jquery-1.11.0.min.js" type="text/javascript"></script>
<script src="js/jquery-ui.js" type="text/javascript"></script>
<script src="js/grid.locale-en.js" type="text/javascript"></script>
<script src="js/jquery.jqGrid.min.js" type="text/javascript"></script>
<title>List Users</title>
<script type="text/javascript">
jQuery().ready(function (){
//alert('Hi');
jQuery("#list1").jqGrid({
url:'dataTablesAction',
datatype: "json",
colNames:['User Id','First Name', 'Last Name', 'Username','Email'],
colModel:[
{name:'name',index:'name', width:75},
{name:'rowId',index:'rowId', width:90},
{name:'task',index:'task', width:100},
{name:'taskTime',index:'taskTime', width:80},
{name:'uId',index:'uId', width:80}
],
rowNum:10,
autowidth: true,
rowList:[10,20,30],
pager: jQuery('#pager1'),
sortname: 'id',
viewrecords: true,
// sortorder: "desc",
caption:"Users"
}).navGrid('#pager1',{edit:false,add:false,del:false});
});
</script>
</head>
<body>
<table id="list1"></table>
<div id="pager1"></div>
</body>
</html>
Here is my Action:
public class TaskViewAction implements Action {
private List<DailyTasks> detailsList;
public List<DailyTasks> getDetailsList() {
return detailsList;
}
public void setDetailsList(List<DailyTasks> detailsList) {
this.detailsList = detailsList;
}
#Override
public String execute() throws Exception {
detailsList = ExcelServices.readFromExcel("U:\\test.xlsx");
return Action.SUCCESS;
}
}
Struts.xml
<struts>
<package name="default" extends="json-default">
<action name="dataTablesAction" class="com.action.TaskViewAction">
<result type="json">
<param name="excludeNullProperties">true</param>
<param name="noCache">true</param>
</result>
<result type="json" />
</action>
</package>
</struts>
I am receiving data in browser's console. I have checked this from developer's tool present in chrome.
Also there are no errors or exceptions.
Do I have to make changes in JSP?

read jSON response

I am trying to read a json response from my python based backend. I am using this code for accessing the information.
URL for first call
public static final String JSON_RESPONSE_STRING="http://192.168.2.5:8000/mobile/";
URL forsecond call
public static final String PICKUP_DETAILS="http://192.168.2.5:8000/mobile/shippments/";
common method using
public static String GetJSONResponse(String stringUrl) throws IOException
{
StringBuilder response = new StringBuilder();
URL url = new URL(stringUrl);
HttpURLConnection httpconn = (HttpURLConnection)url.openConnection();
if (httpconn.getResponseCode() == HttpURLConnection.HTTP_OK)
{
BufferedReader input = new BufferedReader(new InputStreamReader(httpconn.getInputStream()),8192);
String strLine = null;
while ((strLine = input.readLine()) != null)
{
response.append(strLine);
}
input.close();
}
return response.toString();
}
django url patterns
urlpatterns = patterns('mobile_api.views',
url(r'^$','login_authenticate'),
url(r'^shippments/(?P<id>\w+)','pickup_details'),
url(r'^report/post/','pickup_report')
)
I am using this method twice in my code. For the first time this code is working absolutely fine and parsing the json response .
When I am using this method at other place I am call it
pick_up_id=getIntent().getStringExtra("pickup_id");
String stringUrl=Constants.PICKUP_DETAILS+"555";
String response = null;
try {
response = PickupList.GetJSONResponse(stringUrl);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//String response=GetPickUpDetails(pick_up_id);
System.out.println("second call response"+response);
and getting this response
03-22 12:19:37.979: I/System.out(20703): second call response<!doctype html> <!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]--> <!--[if IE 8]> <html class="no-js ie8 oldie" lang="en"> <![endif]--> <!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]--> <head> <meta charset="utf-8"> <title>ECOM</title> <meta http-equiv="X-UA-Compatible" content="IE=Edge;chrome=1" > <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0"> <meta name="description" content=""> <meta name="author" content=""> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" /> <meta property="og:image" content="http://www.domain.com/images/logo.png"/> <meta property="og:title" content="-- description here --"/> <meta property="og:url" content="http://www.domain.com"/> <link rel="shortcut icon" href="/static/assets/img/favicon.ico" /> <link rel="apple-touch-icon" href="/static/assets/img/apple-touch-icon.png"> <link rel="apple-touch-icon" sizes="72x72" href="/static/assets/img/apple-touch-icon-72x72.png"> <link rel="apple-touch-icon" sizes="114x114" href="/static/assets/img/apple-touch-icon-114x114.png"> <link rel="stylesheet" href="/static/assets/css/styles.css" /> <script src="/static/assets/js/libs/modernizr.custom.60077.js"></script> <link rel="stylesheet" href="/static/assets/css/popup.css" /> <script src="/static/assets/js/jquery-1.7.2.min.js"></script> <script src="/static/assets/authentication/js/popup.js"></script> </head><body><div id="backgroundPopup"></div> <div class="header" style="text-align:center; padding-top:10px;"> <img src="/static/assets/img/Ecomlogo.png"/> </div> <div class="container-fluid" roll="main" id="main"> <div class="span6">Track Shipment <div class="login"> <div class="title"> Login </div> <div class="content-login"> <form action="." method="POST"> <div style='display:none'><input type='hidden' name='csrfmiddlewaretoken' value='p0SPV6QzpX2nP2p588V5lDU9s9LLWZDO' /></div> <input type= "text" name ="username" placeholder="Username" class="user-name"/> <input type= "Password" name="password" placeholder="Password"/> <input type="submit" class="button-login"/> Forgot Your Password? </form> </div> </div> </div> <div class="span6"> <div class="login"> <div class="title"> Ecom Express News </div> <div class="content-login"> </div> </div> </div> </div> <!-- modal --> <div class="modal hide modal-add-revlet" id="add-revlet"> <div class="modal-header"> <a class="close" data-dismiss="modal">×</a> <h3>Record</h3> </div> <div class="modal-body"> </div> </div><!--modal end--> <div id="popupContact"> <a id="popupContactClose">x</a> </div> <!-- uncomment pre-deloy --> <!--<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>--> <script>window.jQuery || document.write('<script src="assets/js/libs/jquery-1.7.1.min.js"><\/script>')</script> <!-- bootstrap --> <script src="/static/assets/js/bootstrap-transition.js"></script> <script src="/static/assets/js/bootstrap-alert.js"></script> <script src="/static/assets/js/bootstrap-modal.js"></script> <script src="/static/assets/js/bootstrap-dropdown.js"></script> <script src="/static/assets/js/bootstrap-scrollspy.js"></script> <script src="/static/assets/js/bootstrap-tab.js"></script> <script src="/static/assets/js/bootstrap-tooltip.js"></script> <script src="/static/assets/js/bootstrap-popover.js"></script> <script src="/static/assets/js/bootstrap-button.js"></script>
P.S Also, if there is any problem with the code then why is it working for first call.
NOTE 1 Both the response are json objects I have verified several times.my backend is dJango. On hitting the url on browser I am getting the correct response in .json format
check for csrf_exempt or proper permission for access to the url from app

Categories