Reputation: 125
I am making a TicTacToe Application using Springboot and Thymeleaf. But I am facing issues to redirect my index.html
to message.html
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<title>Tic Tac Toe</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="js/app-main.js"></script>
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
<link rel="stylesheet" href="css/app-layout.css" />
<link rel="icon" type="image/png" href="images/tic-tac-toe.png" />
</head>
<body>
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<span class="navbar-brand"> <img alt="Brand"
src="images/tic-tac-toe.png" /> Tic Tac Toe
</span>
</div>
</div>
</nav>
<div class="game-area panel panel-default">
<div class="panel-body">
<h4 class="game-status">
<span th:if="${game.getPlayerState().isInProgress()}"
class="label label-default"> Your turn. Think very carefully
and click a square when ready.</span> <span
th:if="${game.getPlayerState().isWin()}"
class="label label-success"> YOU WIN! Your superior
intellect prevailed and assured a sound victory. Click here to <a
href="/message">view your reward</a>
</span> <span th:if="${game.getPlayerState().isLoss()}"
class="label label-danger"> You've lost. Better luck next
time!</span> <span th:if="${game.getPlayerState().isDraw()}"
class="label label-info"> Mheh! A smelly draw. Beats losing
though, right?</span>
</h4>
<table class="board">
<tr th:each="row : ${game.getBoard().getTiles()}" class="board-row">
<td th:each="tile : ${row}">
<div th:id="${tile.getId()}" class="board-row-tile"
th:classappend="${!tile.isEmpty()} ? ${tile} + '-value' : (${!game.isGameOver()} ? 'available')"
th:text="${tile}"> </div>
</td>
</tr>
</table>
<form id="form_mark_tile" th:action="@{/}" method="POST"
class="form-inline">
<div class="checkbox">
<label><input name="player_go_first" type="checkbox"
th:checked="${game.isPlayerGoFirst()}" /> Play First</label>
</div>
<div class="btn-new-game-wrap">
<a id="btn-new-game" class="btn btn-success btn-lg"
href="javascript:void(0);" role="button">New Game</a>
</div>
<input id="is_game_over" type="hidden"
th:value="${game.isGameOver()}" /> <input id="tile_id"
name="tile_id" type="hidden" value="" /> <input id="new_game"
name="new_game" type="hidden" value="" />
</form>
</div>
</div>
</body>
</html>
@Controller
@SessionAttributes("game")
public class TicTacToeController {
@RequestMapping(value = "/", method = RequestMethod.GET)
public String index(@ModelAttribute("game") Game game) {
return "index";
}
@RequestMapping(value = "/", method = RequestMethod.POST)
public String markTile(@ModelAttribute("game") Game game, @RequestParam("tile_id") String tileId,
@RequestParam(value = "new_game", required = false, defaultValue = "false") boolean newGame,
@RequestParam(value = "player_go_first", required = false, defaultValue = "false") boolean playerGoFirst) {
if (newGame) {
game.reset();
game.setPlayerGoFirst(playerGoFirst);
if (!playerGoFirst) {
// give computer a small advantage by always placing X in the center as its
// first move
game.markTile("1-1");
}
} else {
game.markTile(tileId); // Player Turn
game.markTileRandom(); // Computer Turn
}
return "index";
}
@GetMapping(value = "/message")
public String message() {
return "redirect:/message.html";
}
@ModelAttribute("game")
public Game populateGame() {
return new Game();
}
}
Can someone guide me with a piece of code on how to redirect it to a new HTML page, message.html
. I am not passing any specific data from index.html
. I am getting the following error while running on the href
attribute.
Upvotes: 0
Views: 1613
Reputation: 387
Firstly i suggest you to make use of ErrorController interface, so you can track better where your errors are.
https://www.baeldung.com/spring-boot-custom-error-page
As for your error, I assume your other controller endpoints are working fine (if it's not the case, check @ComponentScan related issues), and also that you have a message.html template on your templates folder (in case you don't have your message.html then surely you get 404 error). But assuming you have all this:
Go http://localhost:8080/message.html directly from your browser and see how it fails. So from here we know that it's not a problem caused by your redirect
If it's not a problem from the redirect, it means the problem is that this URL can't be resolved. So at some point Spring doesn't know where to find your page (because no body told him :( )
So now you move your "messaga.html" file to "src/main/resources/static/" folder and... Tadaaa ! magically works.
Why it works now ? Basically because of where Spring looks for static content by default (https://docs.spring.io/spring-boot/docs/1.1.5.RELEASE/reference/htmlsingle/#boot-features-spring-mvc-static-content).
If you want to keep it as a static page, it has no sense to go /message endpoint for a redirect to /message.html, you can directly set your href attr like /message.html
If you want your message.html page to don't be static, make it a template and return it with ModelAndView or whatever. https://www.baeldung.com/spring-mvc-model-model-map-model-view
In case you still want to redirect more stuff. https://www.baeldung.com/spring-redirect-and-forward
Upvotes: 2