Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

Sorry, you do not have permission to ask a question, You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please type your username.

Please type your E-Mail.

Please choose an appropriate title for the post.

Please choose the appropriate section so your post can be easily searched.

Please choose suitable Keywords Ex: post, video.

Browse

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Navigation

  • Home
  • About Us
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • About Us
  • Contact Us
Home/ Questions/Q 8561

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Latest Questions

Author
  • 60k
Author
Asked: November 28, 20242024-11-28T02:17:10+00:00 2024-11-28T02:17:10+00:00

MVC Web Application with ActiveJ

  • 60k

Intro

In this tutorial we will create an asynchronous servlet that adds contacts to a list, parses requests and processes form validation with the help of ActiveJ framework. You can find the source code of this tutorial on GitHub.

Setting up the project

We'll need the following dependencies:

<dependencies>   <dependency>     <groupId>io.activej</groupId>     <artifactId>activej-launchers-http</artifactId>     <version>3.0</version>   </dependency>   <dependency>     <groupId>com.github.spullara.mustache.java</groupId>     <artifactId>compiler</artifactId>     <version>0.9.4</version>   </dependency>   <dependency>     <groupId>ch.qos.logback</groupId>     <artifactId>logback-classic</artifactId>     <version>1.2.3</version>   </dependency> </dependencies> 
Enter fullscreen mode Exit fullscreen mode

We'll use the following ActiveJ technologies:

  • ActiveInject – lightweight and powerful dependency injection library with great performance and no third-party dependencies.
  • ActiveJ HTTP – high-performance asynchronous HTTP clients and servers.
  • ActiveJ Launcher – takes care of full application lifecycle, service management, and logging. Perfectly compatible with ActiveInject.

Time to code!

This tutorial represents the MVC pattern:

  • To model a Contact representation, we will create a plain Java class with fields (name, age, address), constructor, and accessors to the fields:
class Contact {     private final String name;     private final Integer age;     private final Address address;      public Contact(String name, Integer age, Address address) {         this.name = name;         this.age = age;         this.address = address;     }      public String getName() {         return name;     }      public int getAge() {         return age;     }      public Address getAddress() {         return address;     }      @Override     public String toString() {         return "Contact{name='" + name + ''' + ", age=" + age + ", address=" + address + '}';     } } 
Enter fullscreen mode Exit fullscreen mode

The Address class is pretty simple:

class Address {     private final String title;      public Address(String title) {         this.title = title;     }      public String getTitle() {         return title;     }      @Override     public String toString() {         return "Address{title='" + title + ''' + '}';     } }  
Enter fullscreen mode Exit fullscreen mode

To simplify the tutorial, we will use an ArrayList to store the Contact objects. ContactDAO interface and its implementation are used for this purpose:

interface ContactDAO {     List<Contact> list();      void add(Contact user); } 
Enter fullscreen mode Exit fullscreen mode

class ContactDAOImpl implements ContactDAO {     private final List<Contact> userList = new ArrayList<>();      @Override     public List<Contact> list() {         return userList;     }      @Override     public void add(Contact user) {         userList.add(user);     } } 
Enter fullscreen mode Exit fullscreen mode

  • To build a view we will use a single HTML file, compiled with the help of the Mustache template engine:
<!DOCTYPE html> <html lang="en"> <head>   <meta charset="UTF-8">   <title>Decoder example</title>   <style>     table {       font-family: arial, sans-serif;       border-collapse: collapse;       width: 100%;     }      td, th {       border: 1px solid #dddddd;       text-align: left;       padding: 8px;     }      tr:nth-child(even) {       background-color: #dddddd;     }      div {       text-align: center;     }      span {       color: red;     }    </style> </head> <body> <div>   <form action="/add" method="post">     <table>       <tr>         <th>Name: <input type="text" name="name"> <span>{{errors.name}}</span></th>         <th>Age: <input type="text" name="age"> <span>{{errors.age}}</span></th>         <th>Address: <input type="text" name="title"> <span>{{errors.contact-address-title}}</span>         </th>       </tr>     </table>     <input type="submit" value="Submit">   </form> </div> <br> <table>   <tr>     <th>Name</th>     <th>Age</th>     <th>Address</th>   </tr>   {{#contacts}}   <tr>     <th>{{name}}</th>     <th>{{age}}</th>     <th>{{address.title}}</th>   </tr>   {{/contacts}} </table> </body> </html> 
Enter fullscreen mode Exit fullscreen mode

  • An AsyncServlet will be used as a controller. We will also add RoutingServlet for routing requests to the needed endpoints. We'll get to this in a moment.

Let’s create HttpDecoderExample class which extends HttpServerLauncher. By extending HttpServerLauncher we will take care of the server’s lifecycle and service management. Next, we provide two custom parsers based on Decoder– ADDRESS_DECODER and CONTACT_DECODER – which will be used for validation. Decoder class provides you with tools for parsing requests.

public final class HttpDecoderExample extends HttpServerLauncher {     private static final String SEPARATOR = "-";      private static final Decoder<Address> ADDRESS_DECODER = Decoder.of(Address::new,             ofPost("title", "")                     .validate(param -> !param.isEmpty(), "Title cannot be empty")     );      private static final Decoder<Contact> CONTACT_DECODER = Decoder.of(Contact::new,             ofPost("name")                     .validate(name -> !name.isEmpty(), "Name cannot be empty"),             ofPost("age")                     .map(Integer::valueOf, "Cannot parse age")                     .validate(age -> age >= 18, "Age must not be less than 18"),             ADDRESS_DECODER.withId("contact-address")     ); 
Enter fullscreen mode Exit fullscreen mode

Also, we need to create applyTemplate(Mustache mustache, Map<String, Object> scopes) method to fill the provided Mustache template with the given data:

private static ByteBuf applyTemplate(Mustache mustache, Map<String, Object> scopes) {     ByteBufWriter writer = new ByteBufWriter();     mustache.execute(writer, scopes);     return writer.getBuf(); } 
Enter fullscreen mode Exit fullscreen mode

Next, let’s provide a ContactDAOImpl factory method:

@Provides ContactDAO dao() {     return new ContactDAOImpl(); } 
Enter fullscreen mode Exit fullscreen mode

Now we have everything needed to create the controller AsyncServlet to handle requests:

@Provides AsyncServlet mainServlet(ContactDAO contactDAO) {     Mustache contactListView = new DefaultMustacheFactory().compile("static/contactList.html");     return RoutingServlet.create()             .map("/", request ->                     HttpResponse.ok200()                             .withBody(applyTemplate(contactListView, map("contacts", contactDAO.list()))))             .map(POST, "/add", AsyncServletDecorator.loadBody()                     .serve(request -> {                         Either<Contact, DecodeErrors> decodedUser = CONTACT_DECODER.decode(request);                          if (decodedUser.isLeft()) {                             contactDAO.add(decodedUser.getLeft());                         }                         Map<String, Object> scopes = map("contacts", contactDAO.list());                         if (decodedUser.isRight()) {                             scopes.put("errors", decodedUser.getRight().toMap(SEPARATOR));                         }                         return HttpResponse.ok200()                                 .withBody(applyTemplate(contactListView, scopes));                     })); } 
Enter fullscreen mode Exit fullscreen mode

Here we provide an AsyncServlet, which receives HttpRequests from clients, creates HttpResponses depending on the route path and sends it.

Inside the RoutingServlet two route paths are defined. The first one matches requests to the root route / – it simply displays a contact list. The second one, /add – is an HTTP POST method that adds or declines adding new users. We will process this request parsing with the help of the aforementioned Decoder by using decode method:

Either<Contact, DecodeErrors> decodedUser = CONTACT_DECODER.decode(request); 
Enter fullscreen mode Exit fullscreen mode

Either represents a value of two possible data types which are either Left(Contact) or Right(DecodeErrors). In order to determine whether a parse was successful or not, we check it’s value by using the isLeft() and isRight() methods.
Finally, write down the main method which will launch our application:

public static void main(String[] args) throws Exception {     Launcher launcher = new HttpDecoderExample();     launcher.launch(args); } 
Enter fullscreen mode Exit fullscreen mode

Time to test!

You've just created and launched an MVC web application with asynchronous and high-performance server! Now you can test the app by visiting localhost:8080.

javatutorialwebdev
  • 0 0 Answers
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

Sidebar

Ask A Question

Stats

  • Questions 4k
  • Answers 0
  • Best Answers 0
  • Users 1k
  • Popular
  • Answers
  • Author

    How to ensure that all the routes on my Symfony ...

    • 0 Answers
  • Author

    Insights into Forms in Flask

    • 0 Answers
  • Author

    Kick Start Your Next Project With Holo Theme

    • 0 Answers

Top Members

Samantha Carter

Samantha Carter

  • 0 Questions
  • 20 Points
Begginer
Ella Lewis

Ella Lewis

  • 0 Questions
  • 20 Points
Begginer
Isaac Anderson

Isaac Anderson

  • 0 Questions
  • 20 Points
Begginer

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help

Footer

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore, ask, and connect. Join our vibrant Q&A community today!

About Us

  • About Us
  • Contact Us
  • All Users

Legal Stuff

  • Terms of Use
  • Privacy Policy
  • Cookie Policy

Help

  • Knowledge Base
  • Support

Follow

© 2022 Querify Question. All Rights Reserved

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.