How to make Spring Boot see my images from resources - java

Hi I Have such images in resources/static and put them into my index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8"/>
<title>Test</title>
</head>
<body>
<div>
<form method="POST" enctype="multipart/form-data" action="/">
<p>
<img src="../static/image1.png" alt="Image 1"/>
<img src="../static/image2.png" alt="Image 2"/>
<tr>
<td></td>
<td><input type="submit" value="Test"/></td>
</tr>
</p>
</form>
</div>
<div th:if="${success}">
<img src="/static/result.png"/>
</div>
</body>
</html>
Then, in ResourceConfig
#Configuration
#EnableWebMvc
#ComponentScan
public class ResourceConfig extends WebMvcConfigurerAdapter {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
"classpath:/META-INF/resources/", "classpath:/images/",
"classpath:/static/", "classpath:/public/" };
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!registry.hasMappingForPattern("/webjars/**")) {
registry.addResourceHandler("/webjars/**").addResourceLocations(
"classpath:/META-INF/resources/webjars/");
}
if (!registry.hasMappingForPattern("/**")) {
registry.addResourceHandler("/**").addResourceLocations(
CLASSPATH_RESOURCE_LOCATIONS);
}
}
}
The problem is, that application doesn't see my images. I've added resource handler, but it hasn't worked. The output is
Output

This #Override method addResourceHandlers shows Spring Framework where are all you static resources. So... your folder which contains images which are also a static resource must be under your root static resource handler. Set it like this and create this folder under WebContent folder in your project.
#Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/assets/**").addResourceLocations("/assets/");
}

This line in your html template
<div th:if="${success}">
makes me think you are using Thymeleaf as your template engine. If that is that case, you should use this to refer to static content:
<img th:src="#{/result.png}"}/>
if your png file is indeed in the root of your static folder.

Related

SpringBoot Thymeleaf: No mapping for GET /css/style.css

I'm trying to add .css file to my index.html using Thymeleaf. But browser throws some strange errors:
GET http://localhost:8080/css/style.css net::ERR_ABORTED 404
And on server i got:
o.s.web.servlet.PageNotFound : No mapping for GET /css/style.css
Why it's happens? Also, it happens with all static components like .js and .css files. I have not any security. Please, help!
Sources:
WebConfig.java
#Configuration
#EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedMethods("*").allowedOrigins("*");
}
}
AdminPanel.java
#ConditionalOnProperty("app.is_debugging")
#Controller
public class AdminPanel {
#RequestMapping(value = { "/", "/index" }, method = RequestMethod.GET)
public String getIndex(Model model) {
return "index";
}
}
index.html
<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Custom messanger</title>
<link rel="stylesheet" type="text/css" th:href="#{/css/style.css}"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/3.0.0/handlebars.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/list.js/1.1.1/list.min.js"></script>
<!-- libs for stomp and sockjs-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.4.0/sockjs.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script>
<!-- end libs for stomp and sockjs-->
<script type="text/javascript" th:src="#{/js/chat.js}"></script>
</head>
<body>
<div class="container clearfix">
<input type="text" id="name" placeholder="name">
<button onclick="createRoom()">Create room</button>
<input type="text" id="roomId" placeholder="roomId">
<button onclick="connectToTheRoom()">Connect</button>
<button onclick="connectToSocket()">Connect to socket</button>
<input type="text" id="message" placeholder="message">
<button onclick="sendMsg()">Send</button>
</div>
<div id="messagesList">
<a class="messagesConsole">Test msg1</a>
<a class="messagesConsole">Test msg2</a>
</div>
</body>
</html>
My file structure

Form lost Polish characters

I lost my mind trying to add Polish characters like "ą, ę, ć, ł" etc. to my MySQL database. Steps I have done :
Set up "Method comparing inscription" to utf8_unicode_ciin my MySQL database.
Set up for all varchar fields Method comparing inscription to utf8_unicode_ci
In application.properties set :
spring.datasource.url: jdbc:mysql://localhost:3306/database?characterEncoding=UTF-8
spring.mandatory-file-encoding=UTF-8
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.datasource.sqlScriptEncoding=UTF-8
To be sure in all HTML files add in <head></head> brackets <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
Set the configuration file like this:
#Configuration
public class Config extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
filter.setForceEncoding(true);
}
}
When I try to add some Polish words in my controller, for example player.setName("ĆŁĘ")- it's OK. The name in the database is correctly inserted.
But when I take the name of player in controller from Thymeleaf, it returns ÄÅÄ instead of CŁĘ. My form attendant Thymeleaf looks like this:
<form action="#" th:action="#{/editPlayer}" th:object="${player}" method="post">
<div class="info">Name:</div>
<div class="error" th:if="${#fields.hasErrors('name')}" th:errors="*{name}"/>
<input type="text" th:field="*{name}" placeholder="Name" th:class="${#fields.hasErrors('name')}? 'error'"/><br/>
<input type="button" id="cancel" class="button2 button-cancel" value="CANCEL"/>
<input type="submit" class="button button-submit" value="SUBMIT"/>
</form>
I have no idea what else I need to do to get correct characters from Thymeleaf.
I found solution. It take me some steps:
Add annotation #EnableWebSecurity to my Config class,
Write http.addFilterBefore(filter, CsrfFilter.class) under filter.setForceEncoding(true)
Create class ApplicationSecurityInitializer
public class ApplicationSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
#Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
super.beforeSpringSecurityFilterChain(servletContext);
FilterRegistration.Dynamic characterEncodingFilter;
characterEncodingFilter = servletContext.addFilter("encodingFilter",
new CharacterEncodingFilter());
characterEncodingFilter.setInitParameter("encoding", "UTF-8");
characterEncodingFilter.setInitParameter("forceEncoding", "true");
characterEncodingFilter.addMappingForUrlPatterns(null, false, "/*");
}
}
Take a breath and be calm :)

Cannot call Play Framework static method from view

I have server and I should make request on button pressed also I have to call this method and when it is works I should parse json but my doesn't see controller method only main method is available
How to call
<input type="submit" onclick="#routes.Login.resp()" value="LOGIN" >
because it is not worrking Cannot resolve symbol
GET /login controllers.Login.main()
My controller:
package controllers;
import play.libs.F;
import play.libs.WS;
import play.mvc.Controller;
import play.mvc.Result;
public class Login extends Controller {
public static Result main() {
return ok(views.html.login.render());
}
public static F.Promise<Result> resp() {
String feedUrl="http://validate.jsontest.com/?json=%7B%22key%22:%22value%22%7D";
final F.Promise<Result> resultPromise = WS.url(feedUrl).get().flatMap(
new F.Function<WS.Response, F.Promise<Result>>() {
public F.Promise<Result> apply(WS.Response response) {
return WS.url(response.asJson().findPath("empty").asText()).get().map(
new F.Function<WS.Response, Result>() {
public Result apply(WS.Response response) {
return ok("size" + response.asJson().findPath("count").asInt());
}
}
);
}
}
);
return resultPromise;
}
}
view:
<!--
Author: W3layouts
Author URL: http://w3layouts.com
License: Creative Commons Attribution 3.0 Unported
License URL: http://creativecommons.org/licenses/by/3.0/
-->
<!DOCTYPE html>
<html>
<head>
<title>LOGIN</title>
<meta charset="utf-8">
<link rel="stylesheet" media="screen" href="#routes.Assets.at("stylesheets/stylelogin.css")">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="application/x-javascript"> addEventListener("load", function() { setTimeout(hideURLbar, 0); }, false); function hideURLbar(){ window.scrollTo(0,1); } </script>
<!--webfonts-->
<link href='http://fonts.googleapis.com/css?family=Open+Sans:600italic,400,300,600,700' rel='stylesheet' type='text/css'>
<!--//webfonts-->
</head>
<body>
<!-----start-main---->
<div class="main">
<div class="login-form">
<h1>Member Login</h1>
<div class="head">
<img src="#routes.Assets.at("images/user.png")" alt=""/>
</div>
<form>
<input type="text" class="text" value="USERNAME" onfocus="this.value = '';" onblur="if (this.value == '') {this.value = 'USERNAME';}" >
<input type="password" value="Password" onfocus="this.value = '';" onblur="if (this.value == '') {this.value = 'Password';}">
<div class="submit">
<input type="submit" onclick="#routes.Login.main()" value="LOGIN" >
</div>
</form>
</div>
<!--//End-login-form-->
<!-----start-copyright---->
<!-----//end-copyright---->
</div>
<!-----//end-main---->
</body>
</html>
I am not sure if I also parse json properly,how to make proper GET,POST requests and parse it
As far as I know with the onclick attribute you always call a function in your JavaScript. If you want to specify an URL you need to put it into your form tag with an action attribute like <form action="#routes.Login.main()">.
The default for the HTML form tag is to send a GET. If you want to send a POST you have to specify it via an additional method="post" like <form action="#routes.Login.main()" method="post">. But then you have to change your routing too: POST /login controllers.Login.main(). If you want to post login data I'd strongly recommend to use POST because with GET your data including the password turns up in the query string of your URL.
Additionally your #routes.Login.main() method just returns the login view return ok(views.html.login.render());. Instead it should evaluate the form data you are sending.

Including css and javascript files in spring 4 project

I'm making a web app using Spring 4, the Spring security module and tomcat 8. I'm trying to include some css files and js files in a .jsp file, but it's not working. When I check in the sources tag in Chrome the content of the css seems to be a log in form. I suspect that it may have something to do with spring security.
My css file is included like this in the .jsp
<link href="<c:url value='resources/css/materialize.min.css' />" rel="stylesheet"
type="text/css"></link>
This is the WebConfig file
#Configuration
#ComponentScan(basePackages = "mypackage")
#EnableWebMvc
#EnableTransactionManagement
public class WebAppConfig extends WebMvcConfigurerAdapter {
#Bean
public InternalResourceViewResolver viewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
#Autowired
#Bean
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory){
HibernateTransactionManager transactionManager = new HibernateTransactionManager(sessionFactory);
return transactionManager;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
This is the SecurityConfig file
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/js/**", "/resources/css/**", "/resources/img/**", "/resources/font/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin().loginPage("/signin")
.failureUrl("/signin?param.error=bad_credentials")
.and().logout().logoutUrl("/signout")
.and().authorizeRequests()
.antMatchers("/favicon.ico", "/resources/css/**", "/resources/font/**",
"/resources/js/**", "/auth/**", "/signin/**", "/signup/**", "/disconnect/facebook").permitAll()
.antMatchers("/**").authenticated()
.and()
.rememberMe().
and().csrf();
}
}
According to other answers here in stackoverflow it should work with the code that I have but the css only returns this:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:social="http://spring.io/springsocial"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorator="layout">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<div id="content" >
<form id="signin" action="signup" method="post">
<input type="hidden" name="" value=""/>
<div class="formInfo">
</div>
<fieldset>
<label for="login">Email</label>
<input id="login" name="email" type="text" size="25"></input>
<label for="Nombre">Email</label>
<input id="nombre" name="nombre" type="text" size="25"></input>
<label for="password">Password</label>
<input id="password" name="contrasena" type="password" size="25"></input>
</fieldset>
<button type="submit">Sign In</button>
<p>Or you can signin with a new account.</p>
</form>
</div>
All my css and js files are inside WebContent/resources
I solved the problem, apparently there was an ambiguous routing in one of my controllers, so when I tried to access a url that started with "/resources" it routed it to the controller, and thus returned a .jsp instead of the css/js/image. My original controller binded the url in the #Controller, and left the #RequestMapping without indicating the route.
#Controller("/signup")
public class SignUpController {
#RequestMapping(method=RequestMethod.GET)
public String signUpForm(){
...
}
#RequestMapping(method=RequestMethod.POST)
public String crearUsuario(HttpServletRequest request){
...
}
So I changed the #Controller annotation, and put the url in each #RequestMapping like this:
#Controller
public class SignUpController {
#RequestMapping(value="/signup", method=RequestMethod.GET)
public String signUpForm(){}
#RequestMapping(value="/signup",method=RequestMethod.POST)
public String crearUsuario(HttpServletRequest request){}
}

Jsp custom tags get replaced with html content in wrong order

I have learned in last class that jsp's custom tags are replaced with html content after evaluation of custom tag.
But putting this concept in practice, I faced following problem.
I have 3 div inside a jsp , 2 of them are static and middle div has a custom tag in it. So html content generated by middle div's custom tag should be replaced in middle div only.
But, output suggests something else, please point me out if there is something wrong with the code, or the statement used in starting of question needs some modification.
home.jsp
<div style="height: 80px; background-color: #FFA500;">
<%# include file="banner.html"%>
</div>
<div style="height: 450px;">
<connect:dbConnector user="root" password="" url="jdbc:mysql://localhost/musicstore" scope="session">
</connect:dbConnector>
<connect:Query where="select * from musicstore.songs;">
<ui:addTable name="musicList">
<c:forEach var="value" items="${result }">
<c:set scope="session" var="currentRow" value="${value }"></c:set>
<ui:addRow data="currentRow" scope="session">
</ui:addRow>
</c:forEach>
</ui:addTable>
</connect:Query>
</div>
<div style="height: 80px; background-color: #FFA500;">Footer
content</div>
html content that i can see on web browser are
<table border="1" name=" musicList ">
<tr> <td>Tum hi ho</td>
<td>Arjit Singh</td>
<td>45</td></tr>
<tr> <td>Manjha</td>
<td>Amit Trivedi</td>
<td>30</td></tr>
<tr> <td>Ranjhanna</td>
<td>A.R Rehman</td>
<td>25</td></tr>
<tr> <td>Sawar Loon</td>
<td>Monali Thankur</td>
<td>20</td></tr>
</table>
<!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">
<title>Insert title here</title>
</head>
<body>
<div style="height: 80px; background-color: #FFA500;">
<img src="/WEB-INF/resources/music_banner.png" ></img>
</div>
<div style="height: 450px;">
</div>
<div style="height: 80px; background-color: #FFA500;">Footer
content</div>
</body>
</html>
AddRowTag.java
public class AddRowTag extends TagSupport {
// some getter, setter and other utility methods here.
#Override
public int doStartTag() throws JspException {
try {
System.out.println("AddRowTag--> doStartTag");
Row content = getDataToDisplay();
StringBuilder htmlContent = new StringBuilder();
htmlContent.append(startTableRow);
htmlContent.append(startTableData);
htmlContent.append(content.getTitle());
htmlContent.append(endableData);
htmlContent.append(startTableData);
htmlContent.append(content.getArtist());
htmlContent.append(endableData);
htmlContent.append(startTableData);
htmlContent.append(content.getPrice());
htmlContent.append(endableData);
htmlContent.append(endableRow);
System.out.println(htmlContent.toString());
pageContext.getResponse().getWriter().print(htmlContent);
} catch (IOException e) {
e.printStackTrace();
}
return SKIP_BODY;
}
}
Summarizing the problem:
Where(in context of location of placement of converted code(html code)) jsp custom tag code is placed in final html file.
What I need to modify in my current my current jsp code, if I want middle div should be updated on basis of custom tag.
Any suggestion/explanation is will be highly appreciated.
The tag should not write to the response directly. By doing that, it bypasses the JspWriter, which also writes to the response but buffers its output.
Replace
pageContext.getResponse().getWriter().print(htmlContent);
by
pageContext.getOut().print(htmlContent);

Categories