Returning HTML page in a JSON property in Spring Boot conditionally - spring

So I'm in a scenario writing Restful Services where based on request data, I've to return either a short string or HTML page IN A JSON variable. lets say like this:
response {
result : YourRequestedString
}
OR
response {
result : <html>...</html>
}
The decision of what will be returned is on server side.
So, is there a way that I can render my Thymeleaf (or any other maybe plain HTML) templates while I'm in the same controller method (directly or by calling some controller method that returns me the rendered page). That I can send back to the client.

Thanks to #Leffchik I got it working, here's my setup with Thymeleaf so it can help others.
Setup htmlTemplateEngine
#Bean
public TemplateEngine htmlTemplateEngine() {
final SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.addTemplateResolver(htmlTemplateResolver());
return templateEngine;
}
private ITemplateResolver htmlTemplateResolver() {
final ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setResolvablePatterns(Collections.singleton("html/*"));
templateResolver.setPrefix("/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode(TemplateMode.HTML);
templateResolver.setCharacterEncoding("utf-8");
templateResolver.setCacheable(false);
return templateResolver;
}
Here's the html page in src/main/resources/templates/html/hello.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="'Hello, ' + ${name} + '!'" />
</body>
</html>
RestController goes like this
#RestController
public class TestController {
#Autowired
TemplateEngine htmlTemplateEngine;
#RequestMapping("/testHello")
public ResponseEntity<?> test(#RequestParam(value = "name", required = false, defaultValue = "World") String name) {
final org.thymeleaf.context.Context ctx = new org.thymeleaf.context.Context();
ctx.setVariable("name", name);
// Rendered template in String, You can now return in a JSON property
final String htmlContent = this.htmlTemplateEngine.process("html/hello.html", ctx);
return ResponseEntity.ok().body(htmlContent);
}
}
Hope it helps !

Returning an HTML Page in a REST Api is not encouraged. But if you fancy you can return a ResponseEntity<Response> from your controller.
#GetMapping("/mymethod")
public ResponseEntity<Response> myMethod() {
ResponseEntity responseEntity = null;
if(string) {
responseEntity = new ResponseEntity(getString(), HttpStatus.OK);
} else {
responseEntity = new ResponseEntity(getHtml(), HttpStatus.OK);
}
return responseEntity;
}

Related

Springboot homepage after login

I just want to display the homepage and the users name after login but I keep getting a 404 not found error.
here is the index.html page
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1 th:action="#{/index}">Hello<h1 th: th:text="${name}"></h1> </h1>
</body>
</html>
And here is my controller
#Controller
#AllArgsConstructor
public class UserController {
private final UserService userService;
private final ConfirmationTokenService confirmationTokenService;
#GetMapping("/sign-in")
String signIn() {
return "sign-in";
}
#GetMapping("/sign-up")
String signUpPage(User user) {
return "sign-up";
}
#PostMapping("/sign-up")
String signUp(User user) {
userService.signUpUser(user);
return "redirect:/sign-in";
}
#GetMapping("/sign-up/confirm")
String confirmMail(#RequestParam("token") String token) {
Optional<ConfirmationToken> optionalConfirmationToken = confirmationTokenService.findConfirmationTokenByToken(token);
optionalConfirmationToken.ifPresent(userService::confirmUser);
return "redirect:/sign-in";
}
#RequestMapping(value = {"/index"}, method = RequestMethod.GET)
public String welcome(User user, Model model) {
model.addAttribute("Name", user.getName());
return "index";
}
I've been trying this for a while now and I don't know what I'm doing wrong. The websecurity config is configured so that the default succesuful URL is index.html
Try changing the request mapping to
#RequestMapping(value = {"/index", "/"}, method = RequestMethod.GET)
Also, try calling localhost:9090/index (without the .html) as Eleftheria Stein-Kousathana said.

Spring boot, JavaMailSender, Thymeleaf and Bootstrap: Recieved email is a plain HTML page

I'm trying to send a MimeMessage using Thymeleaf and Bootstrap 4 but when I check into my inbox, the email is only a plain HTML page. Here are code snippets:
#Configuration
public class ThymeleafConfig {
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.addTemplateResolver(htmlTemplateResolver());
return templateEngine;
}
private ITemplateResolver htmlTemplateResolver() {
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setPrefix("/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode(TemplateMode.HTML);
templateResolver.setCharacterEncoding(StandardCharsets.UTF_8.name());
return templateResolver;
}
}
#Service
#RequiredArgsConstructor
public class MailServiceImpl implements MailService {
private static final String SUBJECT = "Library App - Email Verification";
private static final String URL = "http://localhost:8081/library-app/account/emailVerification?token=";
private static final String HTML_TEMPLATE = "email_verification";
private final JavaMailSender mailSender;
private final TemplateEngine templateEngine;
#Override
public void sendHtmlMessage(UserDto userInfo, String token) throws MessagingException {
final Context context = new Context();
context.setVariable("user_name", userInfo.getFirstName() + " " + userInfo.getLastName());
context.setVariable("email", userInfo.getEmail());
context.setVariable("verification_url", URL + token);
final MimeMessage mimeMessage = this.mailSender.createMimeMessage();
final MimeMessageHelper mailMessage = new MimeMessageHelper(mimeMessage, true, "UTF-8");
mailMessage.setTo(userInfo.getEmail());
mailMessage.setSubject(SUBJECT);
final String htmlContent = this.templateEngine.process(HTML_TEMPLATE, context);
mailMessage.setText(htmlContent, true);
this.mailSender.send(mimeMessage);
}
}
And here's the Thymeleaf HTML page:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="../static/css/bootstrap.css" th:href="#{css/bootstrap.css}" type="text/css"/>
<title>Library App: Email Verification</title>
</head>
<body>
<section class="container h-100 d-flex justify-content-center" style="width: 50%;">
<div style="margin-top: 5%;">
<p>Dear <bold><span th:text="${user_name}"></span></bold></p>
<p>To complete the registration process, please click the button below: </p>
<button type="button" class="btn btn-primary btn-sm"><a th:href="#{${verification_url}}" style="text-decoration: none;">Complete Registration</a></button>
<br>
<br>
<hr>
<p>In case you have not tried to create an account in our website, just ignore this email.</p>
</div>
</section>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script href="../static/js/bootstrap.js" th:href="#{js/bootstrap.js}"></script>
</body>
</html>
When I send the Thymeleaf page to my Yahoo mail and check it out there, it's just a plain HTML page.
PS: I've downloaded Bootstrap CSS and JS files to the resources/static directory.
I think you must use cdn links for the css and js instead of static call and the Thymeleaf is a template engine that should be compiled in spring application i think the email frame cannot do it.
so i suggest to create a html css and bootstrap only for the email mime message.

Getting Error while bootstraping the Spring-boot Application

Well i am developing a spring boot application by choosing view technology as jsp.But when am trying to bootstraping the spring-boot application i am getting white level error page.
Model Class
public class Person {
private String p_first_name;
private String p_last_name;
private int age;
private String city;
private String state;
private String country;
public Person(String p_first_name, String p_last_name, int age, String city, String state, String country) {
super();
this.p_first_name = p_first_name;
this.p_last_name = p_last_name;
this.age = age;
this.city = city;
this.state = state;
this.country = country;
}
public Person() {
super();
// TODO Auto-generated constructor stub
}
public String getP_first_name() {
return p_first_name;
}
public void setP_first_name(String p_first_name) {
this.p_first_name = p_first_name;
}
public String getP_last_name() {
return p_last_name;
}
public void setP_last_name(String p_last_name) {
this.p_last_name = p_last_name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
Controller Class
#Controller
public class PersonController {
private static ArrayList<Person> persons = new ArrayList<Person>();
static {
persons.add(new Person("kumar", "bikash", 28, "bangalore", "karnataka", "india"));
persons.add(new Person("kumar", "pratap", 24, "delhi", "delhi", "india"));
persons.add(new Person("kumar", "ravi", 29, "delhi", "delhi", "india"));
persons.add(new Person("kumar", "mangalam", 65, "delhi", "delhi", "india"));
}
#RequestMapping(value = { "/", "/index" }, method = RequestMethod.GET)
public String index(Model model) {
String message = "Hello" + "Spring Boot implementation with jsp Page";
model.addAttribute("message", message);
return "index";
}
#RequestMapping(value = "/personList", method = RequestMethod.GET)
public String getPersonList(Model model) {
model.addAttribute("persons", persons);
return "personList";
}
}
application.properties
# VIEW RESOLVER CONFIGURATION
spring.mvc.view.prefix=/WEB-INF/jsp
spring.mvc.view.suffix=.jsp
jsp file
index.jsp
=========
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Integration of Spring Boot with jsp page</title>
</head>
<body>
<h1>Welcome to Spring boot</h1>
<p>This project is an Example of how to integrate Spring Boot with
jsp page.</p>
<h2>${message} </h2>
</body>
</html>
personList.jsp
==============
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Person List content Present here</title>
</head>
<body>
<h1>Person List</h1>
<div>
<table border="1">
<tr>
<th>FirstName:</th>
<th>LasttName:</th>
<th>Age:</th>
<th>city:</th>
<th>State:</th>
<th>Country:</th>
</tr>
<c:forEach items="${persons}" var=person>
<tr>
<td>${person.firstname}</td>
<td>${person.lastname}</td>
<td>${person.age }</td>
<td>${person.city }</td>
<td>${person.state }</td>
<td>${person.country }</td>
</tr>
</c:forEach>
</table>
</div>
</body>
</html>
Error page
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Fri Jun 07 23:41:57 IST 2019
There was an unexpected error (type=Not Found, status=404).
No message available
well please review the below code.Help me to resolve thing where i am
getting wrong?
Are you looking to enable your own errorpage disabling the white level error page? May be this can help you.
If you do not specify any custom implementation in the configuration,
BasicErrorController bean is automatically registered in Spring Boot. You can add your implementation of ErrorController.
#Controller
public class MyErrorController implements ErrorController {
#RequestMapping("/error")
public String handleError() {
//do something like logging
return "error";
}
#Override
public String getErrorPath() {
return "/error";
}
}
1) I would suggest trying the #RestController annotation to make sure that you get at least the JSON response. (Only for Debugging)
2) After the first part is figured out, you can go back to your #Controller annotation and make sure that the string you return in the request mapping method is available as a jsp file. I would recommend trying with a single endpoint initially ("/") and having the appropriate jsp page for it.
3) If it still produces the same issue, you can refer to this post
Spring Boot JSP 404.Whitelabel Error Page
4) You can also disable and customize the default error page by following this link https://www.baeldung.com/spring-boot-custom-error-page

Spring Social with Spring Boot not getting user email id

I am new as developer, trying hands on Spring social facebook integration. Followed this link
I am getting data like user's name', 'gender', 'locale'. Which can be given as constructor value to User class(see took help).
But I want to get user "email-id", somehow that's not possible the way i am getting data for 'name', 'locale' and 'gender.
We need to use method getEmail() as per docs. But I am not able to do it.
("A simple app with OAuth security implemented")
Here is the snippet....
My controller class code is
#Controller
#RequestMapping("/")
public class HelloController {
private Facebook facebook;
private ConnectionRepository connectionRepository;
public HelloController(Facebook facebook, ConnectionRepository connectionRepository) {
this.facebook = facebook;
this.connectionRepository = connectionRepository;
}
#GetMapping
public String helloFacebook(Model model) {
if (connectionRepository.findPrimaryConnection(Facebook.class) == null) {
return "redirect:/connect/facebook";
}
String [] fields = {"name", "gender", "locale"};
User userProfile = facebook.fetchObject("me", User.class, fields);
model.addAttribute("feed", userProfile);
//String email = facebook.getEmail();
/*this above one "facebook.getEmail()" gives Internal server error 500 */
return "hello";
}
}
Model class is ...
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
</head>
<body>
<h3>Hello, <span th:text="${feed.name}">Some User</span>!</h3>
<h4>Your gender is : <span th:text="${feed.gender}"></span></h4>
<h4>Your locale is : <span th:text="${feed.locale}"></span></h4>
<h4>Your email is : <span th:text="${feed.getEmail()}"></span></h4>
</body>
</html>
Main class is as...
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Any help is appreciated. Thanks.

Please help me out from this i am new to spring MVC :how to display images from Db using Spring mvc

my problem is how to render the images in jsp from db,
image upload was sucessfull but i am getting problem in rendering the images from DB i am using MySql Db
my Model class is
#Entity
#Table(name="photo")
public class Photo {
private int id;
private String name;
private MultipartFile file;
private byte[] imageContent;
private int imageId;
#Column(name="forId")
public int getImageId() {
return imageId;
}
public void setImageId(int imageId) {
this.imageId = imageId;
}
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Column(name="photoName")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Transient
public MultipartFile getFile() {
return file;
}
public void setFile(MultipartFile file) {
this.file = file;
}
#Lob
#Column(name="image",columnDefinition="blob")
public byte[] getImageContent() {
return imageContent;
}
public void setImageContent(byte[] imageContent) {
this.imageContent = imageContent;
}
}
LIst of Images jsp page (in this page only i have to display images from DB)
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%# taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!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>
<c:out value="${message }"></c:out>
<img src='<c:url value="/image?imageId=${imageId }"/>'/>
</body>
</html>
controller is
#Controller
public class HomeController {
#Autowired
private PhotoService photoService;
public PhotoService getPhotoService() {
return photoService;
}
public void setPhotoService(PhotoService photoService) {
this.photoService = photoService;
}
public static Logger getLogger() {
return logger;
}
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
/**
* Simply selects the home view to render by returning its name.
*/
#RequestMapping(value = "/", method = RequestMethod.GET)
public String home(#ModelAttribute("photo")Photo photo,Locale locale, Model model) {
logger.info("Welcome home! The client locale is {}.", locale);
return "home";
}
#RequestMapping(value="/uploadPhoto",method=RequestMethod.POST)
public String uploadImage(#ModelAttribute("photo")Photo photo,#RequestParam("file")MultipartFile multipartFile,Model model) {
byte[] imageContent=null;
try {
imageContent =photo.getFile().getBytes();
}
catch(Exception e) {
e.printStackTrace();
}
System.out.println(imageContent);
photo.setImageContent(imageContent);
this.photoService.storePhoto(photo);
model.addAttribute("message", photo.getName());
model.addAttribute("imageId", photo.getImageId());
return"listOfImages";
}
#RequestMapping("/image")
public String getImages(#RequestParam("imageId")int imageId,HttpServletResponse response,Model model) {
byte[] image=null;
try {
image=this.photoService.getPhotoByPhotoId(imageId).getImageContent();
response.setContentType("image/jpg");
response.getOutputStream().write(image);
response.getOutputStream().flush();
response.getOutputStream().close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return"listOfImages";
}
}
Dao implementation for this is
#Repository("photoDao")
public class PhotoDaoImpl implements PhotoDao {
#Autowired
private SessionFactory SessionFactory;
public SessionFactory getSessionFactory() {
return SessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
SessionFactory = sessionFactory;
}
/**
* This method is used to store the photo attributes to DB
*/
#Override
public Photo storePhoto(Photo photo) {
Session session =this.SessionFactory.getCurrentSession();
session.save(photo);
return photo;
}
#Override
public Photo getPhotoByPhotoId(int id) {
Session session =this.SessionFactory.getCurrentSession();
Photo photo =null;
photo = (Photo)session.get(Photo.class, id);
return photo;
}
}
Service implementation for this is
#Service("photoSertvice")
public class PhotoServiceImpl implements PhotoService {
#Autowired
private PhotoDao photoDao;
public PhotoDao getPhotoDao() {
return photoDao;
}
public void setPhotoDao(PhotoDao photoDao) {
this.photoDao = photoDao;
}
#Override
#Transactional
public Photo storePhoto(Photo photo) {
return this.photoDao.storePhoto(photo);
}
#Override
#Transactional
public Photo getPhotoByPhotoId(int id) {
return this.photoDao.getPhotoByPhotoId(id);
}
}
You should use either #ResponseBody or ResponseEntity to return the byte array from the 'getImages()' methid.
See this: Spring MVC: How to return image in #ResponseBody?
For example:
ResponseEntity<byte[]> getImages(#RequestParam("imageId") int imageId) {
byte[] image = ...;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_PNG);
return new ResponseEntity<byte[]>(image, headers, HttpStatus.CREATED);
}
If this results in an error of kind "no converter for byte array" you'll have to register the ByteArrayHttpMessageConverter (see the above link for details). But normally it should be registered by default.

Resources