上QQ阅读APP看书,第一时间看更新
How to do it...
- We are going to build a JAX-RS based application, so we will start by preparing the application to perform:
@ApplicationPath("webresources")
public class Application extends javax.ws.rs.core.Application {
}
- Then, we create a User application as our main object:
public class User implements Serializable {
private String name;
private String email;
//DO NOT FORGET TO ADD THE GETTERS AND SETTERS
}
Our User class doesn't have a default constructor, so CDI doesn't know how to construct the class when it tries to inject it. So, we create a factory class and use the @Produces annotation over its methods:
public class UserFactory implements Serializable{
@Produces
public User getUser() {
return new User("Elder Moraes", "elder@eldermoraes.com");
}
}
- Let's create an enumeration to list our profile types:
public enum ProfileType {
ADMIN, OPERATOR;
}
- Here, we create a custom annotation:
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
public @interface Profile {
ProfileType value();
}
- Add them to an interface to prototype the user profile behavior:
public interface UserProfile {
ProfileType type();
}
Now that we have defined the profile list and its behavior with respect to the user, we can give it a proper implementation for an admin profile:
@Profile(ProfileType.ADMIN)
public class ImplAdmin implements UserProfile{
@Override
public ProfileType type() {
System.out.println("User is admin");
return ProfileType.ADMIN;
}
}
And the same can be done for an operator profile:
@Profile(ProfileType.OPERATOR)
@Default
public class ImplOperator implements UserProfile{
@Override
public ProfileType type() {
System.out.println("User is operator");
return ProfileType.OPERATOR;
}
}
- Then, we create a REST endpoint by injecting all the objects that we are going to use into it:
@Path("userservice/")
@RequestScoped
public class UserService {
@Inject
private User user;
@Inject
@Profile(ProfileType.ADMIN)
private UserProfile userProfileAdmin;
@Inject
@Profile(ProfileType.OPERATOR)
private UserProfile userProfileOperator;
@Inject
private UserProfile userProfileDefault;
@Inject
private Event<User> userEvent;
...
- This method gets the user injected by CDI and sends it to the result page:
@GET
@Path("getUser")
public Response getUser(@Context HttpServletRequest request,
@Context HttpServletResponse response)
throws ServletException, IOException{
request.setAttribute("result", user);
request.getRequestDispatcher("/result.jsp")
.forward(request, response);
return Response.ok().build();
}
- This one does the same with an admin profile:
@GET
@Path("getProfileAdmin")
public Response getProfileAdmin(@Context HttpServletRequest request,
@Context HttpServletResponse response)
throws ServletException, IOException{
request.setAttribute("result",
fireUserEvents(userProfileAdmin.type()));
request.getRequestDispatcher("/result.jsp")
.forward(request, response);
return Response.ok().build();
}
- And this one does the same with an operator profile:
@GET
@Path("getProfileOperator")
public Response getProfileOperator(@Context HttpServletRequest request,
@Context HttpServletResponse response)
throws ServletException, IOException{
request.setAttribute("result",
fireUserEvents(userProfileOperator.type()));
request.getRequestDispatcher("/result.jsp")
.forward(request, response);
return Response.ok().build();
}
- Finally, we send the default profile to the result page:
@GET
@Path("getProfileDefault")
public Response getProfileDefault(@Context HttpServletRequest request,
@Context HttpServletResponse response)
throws ServletException, IOException{
request.setAttribute("result",
fireUserEvents(userProfileDefault.type()));
request.getRequestDispatcher("/result.jsp")
.forward(request, response);
return Response.ok().build();
}
- We use the fireUserEvents method to fire an event and async events over a previously injected User object:
private ProfileType fireUserEvents(ProfileType type){
userEvent.fire(user);
userEvent.fireAsync(user);
return type;
}
public void sendUserNotification(@Observes User user){
System.out.println("sendUserNotification: " + user);
}
public void sendUserNotificationAsync(@ObservesAsync User user){
System.out.println("sendUserNotificationAsync: " + user);
}
- So, we build a page to call each endpoint method:
<body>
<a href="http://localhost:8080/ch02-
cdi/webresources/userservice/getUser">getUser</a>
<br>
<a href="http://localhost:8080/ch02-
cdi/webresources/userservice/getProfileAdmin">getProfileAdmin</a>
<br>
<a href="http://localhost:8080/ch02-
cdi/webresources/userservice/getProfileOperator">getProfileOperator</a>
<br>
<a href="http://localhost:8080/ch02-
cdi/webresources/userservice/getProfileDefault">getProfileDefault</a>
</body>
- And finally, we use an expression language to print the result at the result page:
<body>
<h1>${result}</h1>
<a href="javascript:window.history.back();">Back</a>
</body>