How to enter angular4 pages from spring mvc - spring

I have angular4 + spring mvc project here is my project hierarchy
my index.html content
<!DOCTYPE html><html lang="en"><head>
<meta charset="utf-8">
<title>MonitoringFront</title>
<base href="./">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
<script type="text/javascript" src="runtime.js"></script><script type="text/javascript" src="polyfills.js"></script><script type="text/javascript" src="styles.js"></script><script type="text/javascript" src="vendor.js"></script><script type="text/javascript" src="main.js"></script></body></html>
and my web Configuration class
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = { "ge.mvc"})
public class WebMvcConfig implements WebMvcConfigurer {
#Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setViewClass(JstlView.class);
resolver.setPrefix("/WEB-INF/monitoringFront");
return resolver;
}
}
and when I want to enter my pages for example login page which is my default page I am getting page not fount error when i am trying to enter http://localhost:8080/springMvcApp/ url . Did I do something wrong ?
my router urls from angular 4 app.module.ts file
const appRoutes:Routes = [
{
path: '',
component: LoginComponent
},
{
path: 'dashboard',
component: DashboardComponent
}
]

I considere that your problem is equals with this question, because you want to render only de angular application,
How to serve .html files with Spring
In my point of view you need to split the problems to have a better architecture in one side you need your front end using angular 5 and in the other side spring mvc to create rest services, and also you probably will need JWT for authentication.

Related

Template might not exist or might not be accessible by any of the configured Template Resolvers springboot

I have a microservice app built-in spring boot, the main module is working at 8080 port and the other module is working at 7070 port. At /clicker endpoint I'm trying to redirect to
the site which is located on this port but always when I'm using /clicker endpoint I can see an error like this. But when I try to get [http://192.168.254.115:7070] directly from the browser, everything is working fine so I think that's not because of the bad config in the application.properties.
Error resolving template [http://192.168.254.115:7070], template might not exist or might not be accessible by any of the configured Template Resolvers
This controller works at 8080 port.
#CrossOrigin(origins = "*")
public class MainController {
#RequestMapping("/")
public String index() {
return "redirect:/login";
}
#RequestMapping("/home")
public String home(){
return "home.html";
}
#CrossOrigin
#RequestMapping("/clicker")
public ModelAndView goToClicker(HttpServletRequest request) {
//http://localhost:7070/
//http://192.168.254.115:7070/
String url = "http://" + request.getServerName() + ":" + "7070";
return new ModelAndView(url);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Home</title>
<link rel="stylesheet" type="text/css" th:href="#{/styles/style.css}"/>
</head>
<body>
<div class = "main">
<div class = "container">
<button type="button">CLICKER</button>
</div>
</div>
</body>
</html>
And that's the controller which works at 7070 port.
#Controller
#CrossOrigin(origins = "*")
public class ClickerController {
#CrossOrigin
#RequestMapping("/")
public String index() {
return "clicker.html";
}
}

Bootsrap not working with spring boot thymeleaf pdf template

I have a problem adding bootstrap into my thymeleaf template. I want to export that template as pdf.
Bootsrap is not applied to my template. I tried webjars and static bootsrap js and css files but it doesn't work. Is there any other way that i can do? These are webjars links that I have added inside html;
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" th:href="#{webjars/bootstrap/css/bootstrap.min.css}" type="text/css"/>
<script th:src="#{webjars/bootstrap/js/bootstrap.min.js}"></script>
<script th:src="#{webjars/jquery/jquery.min.js}"></script>
</head>
This is java code;
public byte[] getReportByTestId(Long testId, String templateName) throws IOException, DocumentException {
Optional<Test> test = testRepository.findById(testId);
if (test.isPresent()) {
Test _test = test.get();
ObjectMapper oMapper = new ObjectMapper();
Map map = oMapper.convertValue(_test, Map.class);
Context context = new Context();
context.setVariables(map);
String htmlContentToRender = templateEngine.process(templateName, context);
String xHtml = xhtmlConvert(htmlContentToRender);
ITextRenderer renderer = new ITextRenderer();
String baseUrl = FileSystems
.getDefault()
.getPath("src", "main", "resources", "templates")
.toUri()
.toURL()
.toString();
renderer.setDocumentFromString(xHtml, baseUrl);
renderer.layout();
ByteOutputStream outputStream = new ByteOutputStream();
renderer.createPDF(outputStream);
byte[] pdfAsBytes = outputStream.getBytes();
outputStream.close();
return pdfAsBytes;
}
return null;
}
private String xhtmlConvert(String html) throws UnsupportedEncodingException {
Tidy tidy = new Tidy();
tidy.setInputEncoding("UTF-8");
tidy.setOutputEncoding("UTF-8");
tidy.setXHTML(true);
ByteArrayInputStream inputStream = new ByteArrayInputStream(html.getBytes(StandardCharsets.UTF_8));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
tidy.parseDOM(inputStream, outputStream);
return outputStream.toString("UTF-8");
}
When I add like this;
<script th:src="#{../static/vendor/bootstrap5/bootstrap.min.js}"></script>
It partially works. Only colors are applied.
Thanks for any help.

MimeMessageHelper Spring boot to send email

I am using spring boot to sent an email. Code snippet from my email service
private #Autowired JavaMailSender mailSender;
AND
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message,
MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED, StandardCharsets.UTF_8.name());
helper.setTo(bo.getToEmails().parallelStream().toArray(String[]::new));
helper.setBcc(bo.getBccEmails().parallelStream().toArray(String[]::new));
helper.setCc(bo.getCcEmails().parallelStream().toArray(String[]::new));
helper.setText(htmlBody, true);
helper.setText(textBody, false);
helper.setSubject(bo.getSubject());
helper.setFrom(new InternetAddress(bo.getFromEmail(),bo.getSenderLabel()));
First I set the htmlBody and then textBody
helper.setText(htmlBody, true);
helper.setText(textBody, false);
it override htmlBody to textBody . How can I send both text and html body using org.springframework.mail.javamail.MimeMessageHelper; any update ?
You can use thymeleaf as your HTML template engine.
Sample HTML code:
MySampleHTML.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
<title>Sample Email</title>
</head>
<body>
<div th:text="${sampleText}"></div>
</body>
<html>
Sample Java Code:
public class EmailSample {
#Autowired
private JavaMailSender mailSender;
#Autowired
private TemplateEngine templateEngine; // From Thymeleaf
public void initiateEmailSend() {
String processedHTMLTemplate = this.constructHTMLTemplate();
// Start preparing the email
MimeMessagePreparator preparator = message -> {
MimeMessageHelper helper = new MimeMessageHelper(message, MimeMessageHelper.MULTIPART_MODE_MIXED, "UTF-8");
helper.setFrom("Sample <sample#example.com>");
helper.setTo("recipient#example.com");
helper.setSubject("Sample Subject");
helper.setText(processedHTMLTemplate, true);
};
mailSender.send(preparator); //send the email
}
// Fills up the HTML file
private String constructHTMLTemplate() {
Context context = new Context();
context.setVariable("sampleText", "My text sample here");
return templateEngine.process("MySampleHTML", context);
}
}
And include thymeleaf on your pom.xml
<!-- For email HTML templating -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
NOTE: Put the MySampleHTML.html file on resources/templates/ folder for thymeleaf to see it.
instead of
helper.setText(htmlBody, true);
helper.setText(textBody, false);
Use
helper.setText(htmlBody, textBody);

Embedding Vaadin spring-boot application into HTML

I've already posted this question in the Vaadin Forum, unfortunately I did not get any response - maybe answer of the question lies somewhere between spring-boot and Vaadin.
currently I'm having a hard time embedding a Vaadin application into an HTML page.
What do I use:
Vaadin 7.6.6
vaadin-spring
spring-boot 1.3.5.RELEASE
To enable CORS in combination with spring-boot, I adapted Sami's Blog entry and created the following custom CORS servlet:
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import com.vaadin.spring.server.SpringVaadinServlet;
/**
* This custom {#link SpringVaadinServlet} enables CORS in combination with
* Spring.
*
* #author Christoph Guse
*
*/
public class CORSServlet extends SpringVaadinServlet {
/**
*
*/
private static final long serialVersionUID = -2482991123719720492L;
/**
* Override to handle the CORS requests.
*/
#Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// Origin is needed for all CORS requests
String origin = request.getHeader("Origin");
if (origin != null && isAllowedRequestOrigin(origin)) {
// Handle a preflight "option" requests
if ("options".equalsIgnoreCase(request.getMethod())) {
response.addHeader("Access-Control-Allow-Origin", origin);
response.setHeader("Allow", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS");
// allow the requested method
String method = request.getHeader("Access-Control-Request-Method");
response.addHeader("Access-Control-Allow-Methods", method);
// allow the requested headers
String headers = request.getHeader("Access-Control-Request-Headers");
response.addHeader("Access-Control-Allow-Headers", headers);
response.addHeader("Access-Control-Allow-Credentials", "true");
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
response.getWriter().flush();
return;
} // Handle UIDL post requests
else if ("post".equalsIgnoreCase(request.getMethod())) {
response.addHeader("Access-Control-Allow-Origin", origin);
response.addHeader("Access-Control-Allow-Credentials", "true");
super.service(request, response);
return;
}
}
// All the other requests nothing to do with CORS
super.service(request, response);
}
/**
* Check that the page Origin header is allowed.
*/
private boolean isAllowedRequestOrigin(String origin) {
// TODO: Remember to limit the origins.
return origin.matches(".*");
}
}
Additionally I found some documentation about spring-boot and CORS, so I added this Spring configuration:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import CORSServlet;
/**
* #author Christoph Guse
*
*/
#Configuration
public class AuthAppVaadinApplicationConfiguration {
#Bean
public WebMvcConfigurer corsConfigurer(){
return new WebMvcConfigurerAdapter() {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins(".*");
}
};
}
#Bean(name="vaadinServlet")
public CORSServlet corsServlet(){
return new CORSServlet();
}
}
My HTML looks like this:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible"
content="IE=9;chrome=1" />
<title>Embedding a Vaadin Application in HTML Page</title>
<!-- Set up the favicon from the Vaadin theme -->
<link rel="shortcut icon" type="image/vnd.microsoft.icon"
href="/VAADIN/themes/reindeer/favicon.ico" />
<link rel="icon" type="image/vnd.microsoft.icon"
href="/VAADIN/themes/reindeer/favicon.ico" />
</head>
<body>
<!-- Loads the Vaadin widget set, etc. -->
<script type="text/javascript"
src="http://vaadin.poc:8090/VAADIN/vaadinBootstrap.js?v=7.6.6"></script>
<h1>Embedding a Vaadin UI</h1>
<p>This is a static web page that contains an embedded Vaadin
application. It's here:</p>
<!-- So here comes the div element in which the Vaadin -->
<!-- application is embedded. -->
<div style="width: 100%; height: 75vh; border: 2px solid green;"
id="helloworld" class="v-app">
<!-- Optional placeholder for the loading indicator -->
<div class=" v-app-loading"></div>
<!-- Alternative fallback text -->
<noscript>You have to enable javascript in your browser to
use an application built with Vaadin.</noscript>
</div>
<script type="text/javascript">//<![CDATA[
if (!window.vaadin)
alert("Failed to load the bootstrap JavaScript: "+
"VAADIN/vaadinBootstrap.js");
/* The UI Configuration */
vaadin.initApplication("helloworld", {
"browserDetailsUrl": "http://vaadin.poc:8090/",
"serviceUrl": "http://vaadin.poc:8090/",
"theme": "valo",
"versionInfo": {"vaadinVersion": "7.6.6"},
"widgetset": "com.vaadin.DefaultWidgetSet",
"vaadinDir": "http://vaadin.poc:8090/VAADIN/",
"heartbeatInterval": 300,
"debug": true,
"standalone": false,
"authErrMsg": {
"message": "Take note of any unsaved data, "+
"and <u>click here<\/u> to continue.",
"caption": "Authentication problem"
},
"comErrMsg": {
"message": "Take note of any unsaved data, "+
"and <u>click here<\/u> to continue.",
"caption": "Communication problem"
},
"sessExpMsg": {
"message": "Take note of any unsaved data, "+
"and <u>click here<\/u> to continue.",
"caption": "Session Expired"
}
});//]] >
</script>
<p>Please view the page source to see how embedding works.</p>
</body>
</html>
My problem is the application is initally loaded, but several icons are missing and if I trigger an action in the appliction, i.e. open a dropbox, then the application is not able to do the connect to the spring-boot application.
Error messages look like this:
XMLHttpRequest cannot load http://vaadin.poc:8090/UIDL/?v-uiId=0. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 403.
Is there anybody out there who managed to embed a Vaadin spring-boot application into another HTML application?
Any hint is highly appreciated!
Christoph
fortunately someone in the Vaadin forum gave me the missing link. I forgot to add some JavaScript in the standalone HTML:
<script>
XMLHttpRequest.prototype._originalSend = XMLHttpRequest.prototype.send;
var sendWithCredentials = function(data) {
this.withCredentials = true;
this._originalSend(data);
};
XMLHttpRequest.prototype.send = sendWithCredentials;
</script>
That helped, but the fonts were not properly loaded by CORS problems, so I removed the custom Vaadin CORSServlet and added the filter based CORS support provided by spring-boot (as explained in this blog article).
My example now runs properly, the demo application is fully functional, fonts are loaded and used correctly.
Please have a look at https://github.com/flexguse/vaadin-html-embedding to get the fully working example.
Cheers,
Christoph

Keep getting 401 (Authorization Required) with spring social twitter

I've been trying this Spring Social Accessing Twitter Data guide. And though I've double, triple an so on checked everything I keep getting this error when I click "Connect to Twitter" button:
POST request for "https://api.twitter.com/oauth/request_token" resulted in 401 (Authorization Required); invoking error handler
Here is my code:
src/main/resources/templates/connect/twitterConnect.html
<html>
<head>
<title>Hello Twitter</title>
</head>
<body>
<h3>Connect to Twitter</h3>
<form action="/connect/twitter" method="POST">
<div class="formInfo">
<p>You aren't connected to Twitter yet. Click the button to connect this application with your Twitter account.</p>
</div>
<p><button type="submit">Connect to Twitter</button></p>
</form>
</body>
src/main/resources/templates/connect/twitterConnected.html
<html>
<head>
<title>Hello Twitter</title>
</head>
<body>
<h3>Connected to Twitter</h3>
<p>
You are now connected to your Twitter account.
Click here to see your Twitter friends.
</p>
</body>
src/main/resources/templates/hello.html
<html>
<head>
<title>Hello Twitter</title>
</head>
<body>
<h3>Hello, <span th:text="${twitterProfile.name}">Some User</span>!</h3>
<h4>These are your friends:</h4>
<ul>
<li th:each="friend:${friends}" th:text="${friend.name}">Friend</li>
</ul>
</body>
src/main/java/hello/HelloController.java
#Controller
#RequestMapping("/")
public class HelloController {
private Twitter twitter;
private ConnectionRepository connectionRepository;
#Inject
public HelloController(Twitter twitter, ConnectionRepository connectionRepository) {
this.twitter = twitter;
this.connectionRepository = connectionRepository;
}
#RequestMapping(method=RequestMethod.GET)
public String helloTwitter(Model model) {
if (connectionRepository.findPrimaryConnection(Twitter.class) == null) {
return "redirect:/connect/twitter";
}
model.addAttribute(twitter.userOperations().getUserProfile());
CursoredList<TwitterProfile> friends = twitter.friendOperations().getFriends();
model.addAttribute("friends", friends);
return "hello";
}
}
src/main/java/hello/Application.java
#Configuration
#EnableAutoConfiguration
#ComponentScan
public class Application {
/*
* SPRING BOOTSTRAP MAIN
*/
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
I ran into the same problem.
After some investigation I found out the problem is in the callback url. Spring social sets this to yourap/signin/twitter. For facebook and linkedin this is fine, but for some reason twitter nees a filled in callback url in the application settings as well.
So the solution: Go to your twitter application settings, and fill in a callback url (this doesn't even have to be the actual callback url your going to use, just fill in any url!). Most likely this is the cause of your problems.
What does your application.properties file look like? It should have entries for spring.social.twitter.appId and spring.social.twitter.appSecret, populated with values you get when registering your application with Twitter.
Be sure that you have those in application.properties and that there are no curly-braces around the values (the guide's text shows curly-braces, but those are meant as placeholders, not something you should actually have in application.properties).

Resources