How to trigger a CLIENT_ERROR or SERVER_ERROR with entity? - rest

I'm trying to debug an web application running on Glassfish and I want to cause the server to return a CLIENT_ERROR or SERVER_ERROR.
The returned javax.ws.rs.core.Response to the calling server should include an entity. What is the best way to do this?

Create a filter and make it return the required Response:
javax.ws.rs.container.ContainerRequestFilter
#Provider
public class RequestFilter implements ContainerRequestFilter {
/** {#inheritDoc} */
#Override
public void filter(final ContainerRequestContext req) throws IOException {
if (req.getUriInfo().getPath().toLowerCase().contains("pathToMatch")) {
final Response newResp = Response.status(500).entity("<test>test</test>").type(MediaType.valueOf(MediaType.TEXT_HTML)).build();
req.abortWith(newResp);
}
}
}

Related

How to send email from a servlet using threads or executor service?

Where executor service should be declared so it is available to other servlets and not new thread gets created for every new request
Can I do something like this and whenever need to send email, forward request to this servlet
Can you please suggest better design to use ExecutorService in servlet or any other way to send email from servlet?
public class EmailTestServlet extends HttpServlet
{
ExecutorService emailThreadPool = null;
public void init()
{
super.init();
emailThreadPool = Executors.newFixedThreadPool(3);
}
protected void doGet(HttpServletRequest request,HttpServletResponse response)
{
sendEmail(); //it will call emailThreadPool.execute();
}
public void destroy()
{
super.destroy();
}
}
Depends on whether CDI is available at your environment. It is available out the box in normal Jakarta EE servers, but in case of barebones servletcontainers such as Tomcat or Jetty you'd need to manually install and configure it. It's relatively trivial though and gives a lot of benefit: How to install and use CDI on Tomcat?
Then you can simply create an application scoped bean for the job like below:
#ApplicationScoped
public class EmailService {
private ExecutorService executor;
#PostConstruct
public void init() {
executor = Executors.newFixedThreadPool(3);
}
public void send(Email email) {
executor.submit(new EmailTask(email));
}
#PreDestroy
public void destroy() {
executor.shutdown();
}
}
In order to utilize it, simply inject it in whatever servlet or bean where you need it:
#WebServlet("/any")
public class AnyServlet extends HttpServlet {
#Inject
private EmailService emailService;
#Override
protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
Email email = new Email();
// ...
emailService.send(email);
}
}
In case you find yourself in the unfortunate situation that you cannot use CDI, then you'll have to remove the #ApplicationScoped annotation from the EmailService class and reinvent the wheel by simulating whatever CDI is doing under the covers by manually fiddling with ServletContext#get/setAttribute() to simulate an application scoped bean. It might look like this:
#WebListener
public class ApplicationScopedBeanManager implements ServletContextListener {
#Override
public void contextCreated(ServletContextEvent event) {
EmailService emailService = new EmailService();
emailService.init();
event.getServletContext().setAttribute(EMAIL_SERVICE, emailService);
}
#Override
public void contextDestroyed(ServletContextEvent event) {
EmailService emailService = (EmailService) event.getServletContext().getAttribute(EMAIL_SERVICE);
emailService.destroy();
}
}
In order to utilize it, rewrite the servlet as follows:
#WebServlet("/any")
public class AnyServlet extends HttpServlet {
private EmailService emailService;
#Override
public void init() {
emailService = (EmailService) getServletContext().getAttribute(EMAIL_SERVICE);
}
#Override
protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
Email email = new Email();
// ...
emailService.send(email);
}
}
See also:
What is recommended way for spawning threads from a servlet in Tomcat
How to run a background task in a servlet based web application?
Background process in Servlet

EJB not initializing in Wildfly 9.0.0 using #EJB

I'm trying to migrate from EJB2.x to EJB3.x and i'm using Wildfly 9.0.0.
The old EJB2.x is working in JBoss 4.2.2 and this is how it looks like:
public interface WUFFacadeRemote extends EJBObject {
public ClientData getItems(ClientData data);
public ClientData save(ClientData data);
}
public interface WUFFacadeHome extends EJBHome {
public WUFFacadeRemote create();
}
public class WUFFacade {
public ClientData getItems(ClientData data) {
//code here
}
public ClientData save(ClientData data) {
//code here
}
}
public class WUFAction extends HttpServlet implements IAction {
public void doPost(HttpServletRequest request, HttpServletResponse response) {
...
Object objRef = ic.lookup("java:comp/env/wUF");
com.wuf.WUFFacadeHome home = (com.wuf.WUFFacadeHome) PortableRemoteObject.narrow(objRef, com.wuf.WUFFacadeHome.class);
engine = home.create();
//engine gets the reference, and I can use it normally.
...
}
}
I also have the ejb-jar.xml and it's working. Now, the solution I was thinking to EJB3.x and Wildfly 9.0.0 is as below:
#WebServlet(urlPatterns = "windows/wUF.do", loadOnStartup = 1)
public class WUFAction extends HttpServlet implements IAction {
#EJB
private WUFFacadeRemote engine;
public void doPost(HttpServletRequest request, HttpServletResponse response) {
//Here I should be able to use my engine.
//Wildfly starts and I call the page, engine is not null at this moment,
//but after I call the page again, it becomes null and remains null.
}
}
#Stateless
#Remote(WUFFacadeRemote.class)
public class WUFFacade extends RootFacade implements WUFFacadeRemote, Serializable {
public WUFFacade() { }
#EJB
FUFHome home;
public ClientData getItems(ClientData data) {
//code here
}
public ClientData save(ClientData data) {
//code here
}
private Col load(ClientData data,InitialContext ic) {
//here i'm calling home.
// but home is always null. It was supposed to have the #EJB reference initialized.
//But instead I get a null pointer...
home.findByFilter(loader);
}
}
#Remote(FUFHome.class)
public interface FUFHome {
FUF create(FUFValue fUFValue);
FUF findByPrimaryKey(FUFPK pk);
Collection findByFilter(FacadeLoader loader);
}
public interface WUFFacadeRemote{
public ClientData getItems(ClientData data);
public ClientData save(ClientData data);
}
I don't have ejb-jar.xml anymore, the deploy is sucessfully done and Wildfly starts with no errors. Then the first time I call the page in question, it seems that #EJB is working (Debug is "Proxy for remote EJB StatelessEJBLocator for "bus-facade/WUFFacade", view is interface com.wuf.WUFFacadeRemote, affinity is None"), the value is not null, but for all subsequent calls, my variable is null and I got a NullPointerException.
I really don't know what i'm doing wrong (maybe i'm completely lost), but to me, #EJB should be working correctly like that. What am I missing? Thanks.
As i'm using EJB3.x i'm just using annotations now, (this seems to be ok).
JNDIs:
JNDI bindings for session bean named FUF in deployment
java:global/fumo/bus-entities-fumo/FUF!apyon.components.fumo.fuf.FUF
java:app/bus-entities-fumo/FUF!apyon.components.fumo.fuf.FUF
java:module/FUF!apyon.components.fumo.fuf.FUF
java:global/fumo/bus-entities-fumo/FUF
java:app/bus-entities-fumo/FUF
java:module/FUF
JNDI bindings for session bean named WUFFacade
java:global/fumo/bus-facade-fumo/WUFFacade!apyon.fumo.wuf.WUFFacadeRemote
java:app/bus-facade-fumo/WUFFacade!apyon.fumo.wuf.WUFFacadeRemote
java:module/WUFFacade!apyon.fumo.wuf.WUFFacadeRemote
java:jboss/exported/fumo/bus-facade-fumo/WUFFacade!apyon.fumo.wuf.WUFFacadeRemote
java:global/fumo/bus-facade-fumo/WUFFacade
java:app/bus-facade-fumo/WUFFacade
java:module/WUFFacade
I think I found a possible solution to the problem. I'll still try to find another one, but this is good so far.
After changing to a .war and keeping my other projects in .ears it's working. Maybe the problem was because I have a RootController servlet im my main.ear, which is the starting point of the aplication. The context starts there and then it redirects to fumo.ear (now fumo.war).
For some reason, I always was getting a null in my EJB after entering a page. It was always hapening when I first entered a JSP and tried to call the page again. My solution to this is:
#WebServlet(urlPatterns = "windows/wUF.do", loadOnStartup = 1)
public class WUFAction extends HttpServlet {
private WUFFacadeRemote engine;
public void doGet(HttpServletRequest req, HttpServletResponse resp) {
doPost(req, resp);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) {
if(engine == null) {
InitialContext ic;
try {
ic = new InitialContext();
engine = (WUFFacadeRemote) ic.lookup("java:global/fumo/WUFFacade!fumo.wuf.WUFFacadeRemote");
} catch (NamingException e) {
e.printStackTrace();
}
}
//here I always have the context now.
}
}
And as a .war my structure now looks like this:
So other annotations like #Inject and #EJB are now working. Always when i'm being redirect from a JSP calling a Servlet or some action, I first check if the context is not null, otherwise I lookup it. My #Stateless are working and the #PersistenceContext and #Remote are working too.
#Stateless
public class WUFFacade implements WUFFacadeRemote {
#Inject
private FUFRules rules;
#EJB
private FUFHome home;
private Col load(ClientData data, InitialContext ic) throws InterfaceException {
try {
// home here is nor null anymore.
Collection res = (Collection) home.findByFilter(loader);
...
} catch (InterfaceException e) {
e.printStackTrace();
}
...
return data;
}
}
So I'd like to thank everyone who helped in the thread. It was a good way to understand and see the problem or to find a workaround. As I said, I'll still try the .ear in the future, but as a simplified packaging it definitely works.

Spring Rest API interceptor add response header on each/every request

I am working with Spring 4 REST API annotation based configuration application. I want to add response header on each/every request once user is authenticate by JWT. I have created interceptor for that which looks as below:
public class AuthenticateInterceptor implements HandlerInterceptor {
#Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object, Exception arg3)
throws Exception {
response.addHeader("afterCompletion", "afterCompletion header");
response.setHeader("afterCompletion", "afterCompletion header");
System.out.println("************** afterCompletion **************");
}
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object,
ModelAndView modelAndView) throws Exception {
response.addHeader("postHandle", "postHandle header");
System.out.println("************** postHandle **************");
}
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
System.out.println("************** preHandle **************");
return true;
}
}
My interceptor configuration is as below:
#Configuration
public class AdapterConfig extends WebMvcConfigurerAdapter {
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthenticateInterceptor());
}
}
When I get JSON response I am not able the see the added header value which are added from interceptor. Any one help me what is the issue and how can I add header from interceptor for each/every request.
I didn't succeed in interceptors, Instead using Filters or WebFilter perfectly works:
#Component
public class ResponseHeaderWebFilter implements Filter {
#Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setHeader("CustomHeaderName", "SomeValue");
chain.doFilter(request, response);
}
}
In case you are using webflux reactive component, then :
#Component
public class ResponseHeaderWebFilter implements WebFilter {
#Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
exchange.getResponse()
.getHeaders()
.add("CustomHeaderName", "SomeValue");
return chain.filter(exchange);
}
}
If it can help you, I've managed it like this: https://stackoverflow.com/a/49431665/4939245
Look at second point
You can put the response header for each call in the application (this is for Spring annotation-based):
#Component
public class Filter extends OncePerRequestFilter {
....
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
//response.addHeader("Access-Control-Allow-Origin", "*");
//response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Cache-Control", "no-store"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setHeader("Expires", "0"); // Proxies.
filterChain.doFilter(request, response);
}
}
I hope I was helpful!
You are almost doing same but would like to give you consitant way of achieving same. Please do following changes.
1) Add #Component annotation on AuthenticateInterceptor class. And you package containing this class should be in packages scanned list.
#Component
public class AuthenticateInterceptor implements HandlerInterceptor {
...
}
2) Autowire and inject instance of AuthenticateInterceptor like below.
#Configuration
public class AdapterConfig extends WebMvcConfigurerAdapter {
#Autowired
private AuthenticateInterceptor authenticateInterceptor;
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authenticateInterceptor);
}
}

Multiple ContainerRequestFilter for Jersey

We are planning on using Jersey's reference implementation for our REST APIs. As a prototype effort, I was also playing around with the ContainerRequestFilters and I implemented multiple of them. Is there a way in which we can control the order in which these filters are executed?
The scenario that I am thinking over here is to ensure that the security filter must be the first one to run, and if required establish the SecurityContext and then execute other filters.
Yes you can control this with the javax.annotation.Priority attribute and the default javax.ws.rs.Priorities. For example if you wanted:
Logging filter always runs first
Authentication filter should run next
Authorization filter should run next
Custom filter should always run after others
You could do:
#Priority(Integer.MIN_VALUE)
public class CustomLoggingFilter implements ContainerRequestFilter
{
#Override
public void filter(ContainerRequestContext requestContext) throws IOException
{
// DO LOGGING HERE, THIS RUNS FIRST
}
}
#Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter
{
#Override
public void filter(ContainerRequestContext requestContext) throws IOException
{
String authHeader = requestContext.getHeaderString(HttpHeaders.WWW_AUTHENTICATE);
// DO AUTHENTICATION HERE, THIS RUNS SECOND
}
}
#Priority(Priorities.AUTHORIZATION)
public class AuthorizationFilter implements ContainerRequestFilter
{
#Override
public void filter(ContainerRequestContext requestContext) throws IOException
{
String authHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
// DO AUTHORIZATION HERE, THIS RUNS THIRD
}
}
#Priority(Priorities.USER)
public class MyAwesomeStuffFilter implements ContainerRequestFilter
{
#Override
public void filter(ContainerRequestContext requestContext) throws IOException
{
// DO AWESOME STUFF HERE, THIS RUNS LAST
}
}

Intercepting Async Proxy Service exceptions for GWT RPC

My app has many RPC calls, and they all have a .onFailure(Throwable caught) method. I have a class shared between the client and the server code NotLoggedInException. This is thrown by the server, if the user doesn't have the relevant permissions based on sessions/cookies/permissions etc.
Ideally I would like to handle this exception in one place BEFORE others are passed to the .onFailure() code, given how ubiquitous this handling is and needs to be for security. There is a GWT.setUncaughtExceptionHandler() but this appears to get called after the handling which isn't ideal (in case an .onFailure accidentally consumes too much).
Does anybody have an elegant solution to this? An ugly solution is to wrap the deferred binded .create() proxy in the same aggregated class implementing the async interface.
Sidenote: The server was issuing a redirect before, but I don't like this paradigm, and would prefer it to be handled by the eventbus of the app.
Update: ugly answer referred to above
public abstract class CustomAsyncCallback implements AsyncCallback{
#Override
public CustomAsyncCallback(AsyncCallback<T> callback)
{
this.wrap = callback ;
}
AsyncCallback<T> wrap ;
#Override
public void onFailure(Throwable caught) {
if (!handleException())
{
wrap.onFailure(caught) ;
}
}
#Override
public void onSuccess(T t) {
wrap.onSuccess(t) ;
}
}
public class WrapDeferredBinding implements RpcInterfaceAsync
{
RpcInterfaceAsync service = GWT.create(RpcInterface.class);
public void method1(int arg1, AsyncCallback<Boolean> callback)
{
service.method1(arg1, new CustomAsyncCallback<Boolean>(callback)) ;
}
public void method2 ....
public void method3 ....
}
In order to wrap every AsynCallback<T> that is passed to any RemoteService you need to override RemoteServiceProxy#doCreateRequestCallback() because every AsynCallback<T> is handed in here before an RPC call happens.
Here are the steps to do so:
To begin you need to define your own Proxy Generator to step in every time a RemoteService proxy gets generated. Start by extending ServiceInterfaceProxyGenerator and overriding #createProxyCreator().
/**
* This Generator extends the default GWT {#link ServiceInterfaceProxyGenerator} and replaces it in the
* co.company.MyModule GWT module for all types that are assignable to
* {#link com.google.gwt.user.client.rpc.RemoteService}. Instead of the default GWT {#link ProxyCreator} it provides the
* {#link MyProxyCreator}.
*/
public class MyServiceInterfaceProxyGenerator extends ServiceInterfaceProxyGenerator {
#Override
protected ProxyCreator createProxyCreator(JClassType remoteService) {
return new MyProxyCreator(remoteService);
}
}
In your MyModule.gwt.xml make use of deferred binding to instruct GWT to compile using your Proxy Generator whenever it generates something of the type RemoteService:
<generate-with
class="com.company.ourapp.rebind.rpc.MyServiceInterfaceProxyGenerator">
<when-type-assignable class="com.google.gwt.user.client.rpc.RemoteService"/>
</generate-with>
Extend ProxyCreator and override #getProxySupertype(). Use it in MyServiceInterfaceProxyGenerator#createProxyCreator() so that you can define the base class for all the generated RemoteServiceProxies.
/**
* This proxy creator extends the default GWT {#link ProxyCreator} and replaces {#link RemoteServiceProxy} as base class
* of proxies with {#link MyRemoteServiceProxy}.
*/
public class MyProxyCreator extends ProxyCreator {
public MyProxyCreator(JClassType serviceIntf) {
super(serviceIntf);
}
#Override
protected Class<? extends RemoteServiceProxy> getProxySupertype() {
return MyRemoteServiceProxy.class;
}
}
Make sure both your MyProxyCreator and your MyServiceInterfaceProxyGenerator are located in a package that will not get cross-compiled by GWT into javascript. Otherwise you will see an error like this:
[ERROR] Line XX: No source code is available for type com.google.gwt.user.rebind.rpc.ProxyCreator; did you forget to inherit a required module?
You are now ready to extend RemoteServiceProxy and override #doCreateRequestCallback()! Here you can do anything you like and apply it to every callback that goes to your server. Make sure that you add this class, and any other class you use here, in my case AsyncCallbackProxy, to your client package to be cross-compiled.
/**
* The remote service proxy extends default GWT {#link RemoteServiceProxy} and proxies the {#link AsyncCallback} with
* the {#link AsyncCallbackProxy}.
*/
public class MyRemoteServiceProxy extends RemoteServiceProxy {
public MyRemoteServiceProxy(String moduleBaseURL, String remoteServiceRelativePath, String serializationPolicyName,
Serializer serializer) {
super(moduleBaseURL, remoteServiceRelativePath, serializationPolicyName, serializer);
}
#Override
protected <T> RequestCallback doCreateRequestCallback(RequestCallbackAdapter.ResponseReader responseReader,
String methodName, RpcStatsContext statsContext,
AsyncCallback<T> callback) {
return super.doCreateRequestCallback(responseReader, methodName, statsContext, new AsyncCallbackProxy<T>(callback));
}
}
Now, your AsyncCallbackProxy can look something like this:
public class AsyncCallbackProxy<T> implements AsyncCallback<T> {
private AsyncCallback<T> delegate;
public AsyncCallbackProxy(AsyncCallback<T> delegate) {
this.delegate = delegate;
}
#Override
public final void onFailure(Throwable caught) {
GWT.log("AsyncCallbackProxy#onFailure() : " + caught.getMessage(), caught);
if (caught instanceof NotLoggedInException) {
// Handle it here
}
delegate.onFailure(proxy);
}
#Override
public final void onSuccess(T result) {
delegate.onSuccess(result);
}
}
References:
DevGuideCodingBasicsDeferred.html
An example applied to performance tracking
You can wrap AsyncCallback class with an abstract class:
public abstract class CustomAsyncCallback<T> implements AsyncCallback<T>{
#Override
public void onFailure(Throwable caught) {
GWT.log(caught.getMessage());
handleException();
this.customOnFailure(yourDesireParam);
}
/**
* this method is optional
*/
public abstract void customOnFailure(Param yourDesireParam);
}
And then send a CustomAsyncCallback object to your RPC asynch methods.