Issue
I've created a Spring Boot App, in which I am fetching data from external API, store them in database and then displaying them back at front-end in HTML using Thymeleaf. Everything works perfectly fine except one thing.
One of the columns in db, has the name "HEADLINE" which is mapped as String variable and contains news headlines. I am using this column values as texted hyperlinks in my Spring Boot app combined with URLs stored in the same database ("news_link" column), to redirect to the source of them. Below I am showing my front-end code.
Front-End Page
<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:c="http://www.w3.org/1999/XSL/Transform">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Spring Boot Thymeleaf Hello World Example</title>
<link rel="stylesheet" th:href="@{/webjars/bootstrap/css/bootstrap.min.css}"/>
<link rel="stylesheet" th:href="@{/styles/db.css}"/>
<script type="text/javascript" th:src="@{/webjars/bootstrap/js/bootstrap.min.js}"></script>
</head>
<body>
<ul>
<li><a href="http://localhost:8080/">Home</a></li>
<li><a href="https://github.com/Andreas-Kreouzos">Github</a></li>
</ul>
<main role="main" class="container">
<div class="starter-template">
<h1>IoT Application</h1>
</div>
</main>
<!--Display DB contents on HTML and Thymeleaf-->
<div class="container text-center" id="tasksDiv">
<h3>Database Contents</h3>
<hr>
<div class="table-responsive">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>news_id</th>
<th>news_provider_name</th>
<th>HEADLINE</th>
<th>news_link</th>
<th>related_image</th>
<th>Timestamp</th>
</tr>
</thead>
<tbody>
<tr th:each="rate: ${rates}">
<td th:text="${rate.news_id}"> </td>
<td th:text="${rate.news_provider_name}"> </td>
<td th:text="${rate.HEADLINE}"> </td>
<td> <a th:href="${rate.news_link}"> <p th:text="${rate.HEADLINE}"> </a> </td>
<td> <img th:src="${rate.related_image}" alt="error displaying image"> </td>
<td th:text="${rate.timestamp}"> </td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
When I am running my application everything displays just fine, but as soon as I press the texted hyperlinks, I am redirected at the home page instead of the given URLs which I've stored in my DB. Below, I am showing you my printscreen in which you can definitely see that URLs have been fetched and assigned properly, when I am hovering my cursor above them in my browser, just before I press them. But as soon as they do get pressed, I am getting redirection here, instead of here.
Any ideas about what am I doing wrong?
UPDATE
I tried to change the th:href="${rate.news_link}
to th:href="@{${rate.news_link}}
but still nothing works. If, for example, my initial URL is
https://www.investing.com/news/cryptocurrency-news/tether-liquidates-celsius-position-with-no-losses-to-stablecoin-issuer-2845626
gets chopped off to https://www.investing.com/
UPDATE 2
I created the following controller but I am getting null URL -> http://localhost:8080/null
@RequestMapping(value = "/redirect", method = RequestMethod.GET)
public ModelAndView method(
@RequestParam(name = "news_link", required = false) String news_link) {
return new ModelAndView("redirect:" + news_link);
}
Solution
I have created a controller with 2 methods :
@GetMapping("/hello")
public String hello(Model model) {
model.addAttribute("message", "Hello World!");
//I have set below manually just for demo, but in real code, you can fetch this details from database & then set.
model.addAttribute("news_linkvalue", "https://www.investing.com/news/cryptocurrency-news/tether-liquidates-celsius-position-with-no-losses-to-stablecoin-issuer-2845626");
return "helloworld";
}
@RequestMapping(value = "/redirect", method = RequestMethod.GET)
public ModelAndView method(@RequestParam(name = "news_link", required = false) String news_link) {
return new ModelAndView("redirect:" + news_link);
}
And then in helloworld.html
I have used below anchor tag:
<p><a th:href="@{/redirect(news_link=${news_linkvalue})}">Click here</a></p>
After starting spring boot with http://localhost:8080/hello
when I click on Click here
option, it is going to home page of https://www.investing.com/ and giving HTTP 301
response while I clicked on link.
This behaviour be viewed by clicking network
-> clicking on first record->Headers
section.
This mostly means, site is blocking any cross origin unsecure requests (i.e. requests originated from a domain having http
protocol ) to their specific pages other than home pages.
If you use any online javascript editor or stackoverflow editor, use same anchor tag for specific page, it will load because request is coming from secure origin (https), example is as below:
<!DOCTYPE html>
<html>
<body>
<p>Checking Cross origin requests </p>
<p><a href="https://www.investing.com/news/cryptocurrency-news/tether-liquidates-celsius-position-with-no-losses-to-stablecoin-issuer-2845626">Click</a></p>
</body>
</html>
This mostly means, This site's specific pages(other than home page) will only be accessible if and only if protocol security level is same (i.e. HTTPS) while accessing specific page.
Local spring boot uses default http
protocol & that is reason when we access specific page of this website, we always redirects to main page.
How you can fix:
Check if you can run your local spring boot code with
https
(i.e. by enabling ssl with either one-way auth or mutual auth). You can find few sample examples online of using spring boot with secure http.You can deploy your application to any secure application server or any cloud environment based on availability & check if running application over non-local environments fix this issue. Your application url must be accessible via
https
here.
Answered By - Ashish Patil
Answer Checked By - Terry (JavaFixing Volunteer)