JAX-RS rest services working fine. How to add JSP

2019-08-16 08:21发布

问题:

I have some rest services running already, using cxf-rt-frontend-jaxrs 2.7.7

/myservice/customers
/myservice/items

My rest service provides 2 endpoints:

@Component
public class CustomerService {
    @GET
    @Path("customers")
    @Produces({MediaType.APPLICATION_JSON})
    public ... getCustomers() { ... }

    @GET
    @Path("items")
    @Produces({MediaType.APPLICATION_JSON})
    public ... getItems() { ... }
}

This works great, and now I would like to add some jsp pages.

I've read about Redirecting requests and serving static content, but I can't get it to work and I am confused about the configuration in the web.xml and applicationContext.xml.

Here's what I have so far:

web.xml

<servlet>
    <servlet-name>CXFServlet</servlet-name>
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>CXFServlet</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

applicationContext.xml

<jaxrs:server id="rest" address="/">
    <jaxrs:serviceBeans>
        <ref bean="customerWebService" />
    </jaxrs:serviceBeans>
    <jaxrs:providers>
        <bean class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider"/>
        <ref bean="dispatchProvider"/>
    </jaxrs:providers>
</jaxrs:server>

<bean id="dispatchProvider" class="org.apache.cxf.jaxrs.provider.RequestDispatcherProvider">
    <property name="dispatcherName" value="jsp"/>
    <property name="resourcePath" value="/admin/item.jsp"/>
    <property name="beanNames">
        <map>
            <entry key="com.company.domain.Item" value="item"/>
        </map>
    </property>
</bean>

jsp page

I have put a jsp web page named item.jsp into webapp/WEB-INF.

<%@ page import="com.company.domain.Item" %>
<%
    Item item = (Item) request.getAttribute("item");
%>
<html>
  <head></head>
  <body>
    Item: <%= item.getEnglishName() %>.
  </body>
</html>

Errors

If I open /customerservice/items I receive a valid JSON response from the rest service.

However if I open /customerservice/admin/item.jsp I receive this:

[10:34:45.791] [qtp104543434-33] WARN JAXRSUtils - No operation matching request path "/customerservice/admin/item.jsp" is found, Relative Path: /admin/item.jsp, HTTP Method: GET, ContentType: /, Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8,. Please enable FINE/TRACE log level for more details. [10:34:45.796] [qtp104543434-33] ERROR DefaultExceptionMapper - DefaultExceptionMapper returned response: Internal Server Error javax.ws.rs.ClientErrorException: null at org.apache.cxf.jaxrs.utils.JAXRSUtils.findTargetMethod(JAXRSUtils.java:503) ~[cxf-rt-frontend-jaxrs-2.7.7.jar:2.7.7] at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:227) ~[cxf-rt-frontend-jaxrs-2.7.7.jar:2.7.7] at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:103) ~[cxf-rt-frontend-jaxrs-2.7.7.jar:2.7.7] at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272) [cxf-api-2.7.7.jar:2.7.7] at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) [cxf-api-2.7.7.jar:2.7.7] at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:239) [cxf-rt-transports-http-2.7.7.jar:2.7.7] at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:248) [cxf-rt-transports-http-2.7.7.jar:2.7.7] at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:222) [cxf-rt-transports-http-2.7.7.jar:2.7.7] at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:153) [cxf-rt-transports-http-2.7.7.jar:2.7.7]

What am I doing wrong?

Do I need separate servlets and url-mappings in my web.xml?

Does my request dispatcher require furhter configuration (e.g. dispatcherName property) ?

Many thanks for any guidance.

回答1:

I changed my CXFServlet url-pattern to /rest/*

<servlet-mapping>
    <servlet-name>CXFServlet</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

My rest urls are now /customerservice/rest/items and /customerservice/rest/customers.

And now I get a response for url /customerservice/admin/item.jsp, when my jsp pages are placed under webapp/admin (not webapp/WEB-INF/admin), which I presume is correct.

It appears that the request "falls through" to a default apache jasper JspServlet (which I have not configured in any way).

The response:

Hello World.

Great, thanks to Lutz for the initial comment!

Now I need to inject some beans into the jsp pages, perhaps there is there something like exposeContextBeansAsAttributes that I can use here.