Thymeleaf HTML page forward problem to External Website in Spring Boot App

Viewed 365

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?

Browser View

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);
    }
3 Answers

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:

  1. 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.

  2. 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.

You are using a dynamic link, so it seems correct to me how you set up the code in the page:

<a th:href="${link}">Link</a>

Rather check what the controller is giving you back, it should be something like this:

return new ModelAndView("page").addObject("link", <link>)

If in doubt, try to put the complete link to the entire field as proof:

<td> <a th:href="http://www.test.com"> <p th:text="${rate.HEADLINE}"> </a> </td>

edit: I didn't understand your "UPDATE 2" ... you have to read on a list of objects, so the controller will have to return the list object to the page. You don't need to do the opposite if you don't alter this data, so nothing has to go back to the controller from the page.

Your thymeleaf is correct. You can check the resulting html with your browser's dev tools, in elements tab. You should also check the ongoing requests under the network tab.

The server is redirecting you to the home page after accessing an article. I doubt anyone say why, this is server side logic. It may be best to get in contact with the owners about the issue.

Related