I have code along the following lines in my Spring MVC webapp:
#RequestMapping("/{someVariable}/aPath/aPage.do")
public void serveAPage() {
doStuff();
}
We want "someVariable" to be in the URL, but we aren't interested in capturing and using the value of it. Is there any way of replacing it with a wildcard, e.g. /*/aPath/aPage.do?
Yes, #RequestMapping accepts Ant-style patterns as from http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/bind/annotation/RequestMapping.html#params()
So this works:
#RequestMapping(value="/*/test2.do")
public void getMeta5(HttpServletRequest request, HttpServletResponse response) throws IOException {
final PrintWriter writer = response.getWriter();
writer.print("requestURI:" + request.getRequestURI());
writer.flush();
}
This assumes that servlet-mapping in web.xml maps that URL path to the DispatcherServlet, e.g.
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
Related
I am trying to use Jersey to provide a simple web service for my struts application.
When I call the client action I get the following error
com.sun.jersey.api.client.UniformInterfaceException
Message: GET http://localhost:8080/shumer/rest/employee/get returned a response status of 404
servlet declaration in web.xml
<servlet>
<servlet-name>JAX-RS Servlet</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param>
<param-name>spring.autowire</param-name>
<param-value>byName</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JAX-RS Servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Server resource
#Path("employee")
public class EmployeeResource {
#Autowired
EmpDao empDao;
#GET
#Produces(MediaType.APPLICATION_JSON)
public List<Employee> get(#QueryParam("empCode") String empCode) throws Exception {
EmpCriteria criteria = new EmpCriteria();
criteria.setEmpCode(empCode);
return empDao.searchByCondition(criteria);
}
}
Client action
public class EmployeeClientTestAction extends Action {
#Override
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws Exception {
Client client = Client.create();
WebResource resource = client.resource("http://localhost:8080/shumer/rest/employee/get");
String employees= resource.accept(MediaType.APPLICATION_JSON)
.get(String.class);
System.out.println(employees);
request.setAttribute("employees", employees);
return mapping.findForward("successful");
}
}
I have tried this with and without the /get and the end of the resource url, and with and without a leading / in the EmployeeResource #Path annotation. My guess is that there is somewhere I have to declare where my resources are lcoated at in order for the Jersey servlet to handle them, but I can't figure it out. A point in the right direction would be much appreciated.
EDIT
I have added the following init-param to the servlet element and it is still not working (this package is where my resource class is)
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>shumer.rest.resource</param-value>
</init-param>
in get method write #Path("/get")
URLs like this http://localhost:8080/app/service/c345gf.html?serviceId=101
goes to my notFoundPage, but the sources in the HTML are wrong http://localhost:8080/app/service/css/panels/rightPanel.css
But this stuff css/panels/rightPanel.css has such proper URL
http://localhost:8080/app/css/panels/rightPanel.css and
PROJECT_URL is hardcoded. So, why I have between hardcoded http://localhost:8080/app/ and /css part this part: /service?
public class ErrorService extends HttpServlet implements ProjectProperties {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
//...
out.println("<html>\n" +
"<head><title></title>\n" +
" <script type=\"text/javascript\" src=\"" + PROJECT_URL
Mapping:
<servlet-mapping>
<servlet-name>springMvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>ErrorService</servlet-name>
<servlet-class>com.vse.uslugi.web.ErrorService</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ErrorService</servlet-name>
<url-pattern>/error</url-pattern>
</servlet-mapping>
<error-page>
<error-code>404</error-code>
<location>/error</location>
</error-page>
I'm trying to connect to a Jersey service using JQuery. But, it's not getting connected to the service, because I'm checking the logs whether it has hit the service or not. Is there anything missing?
$('#update').click(function() {
alert("updating the labelll");
$.ajax({
url:"/updatecontent",
type: 'POST',
dataType:"json",
data:$( "#labels option:selected" ).text(),
async:false,
success:function(contentdata) { // Success Call Back Function.
if(contentdata == "1") {
alert("successfully updated");
} else {
alert("sorry.. failed in updating");
}
},
error:function(){ // Error Call back function.
alert("sorry.. failed in updating in Error call back");
}
});
});
Service
---------
#Path("/updatecontent")
public class updatecontent {
private static final org.slf4j.Logger LOGGER=org.slf4j.LoggerFactory.getLogger(updatecontent.class);
#Context
HttpServletRequest request;
#Context
HttpServletResponse response;
#POST
#Consumes(MediaType.APPLICATION_JSON)
public String updateStatus(String packet) throws JSONException {
// Get the object from the UI.
LOGGER.info("In the API class of updating content for review.");
return "1";
}
}
Web.xml
---------
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>net.my.services</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>6</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Am I missing anything here? There should be a minor issue. Any ideas would be greatly appreciated.
Your web.xml has an url-pattern of
<url-pattern>/rest/*</url-pattern>
So jQuery must connect to
/rest/updatecontent
I've been trying to implement friendly url mapping in my first Java spring site. I've been following this tutorial. http://outbottle.com/spring-3-web-mvc-friendly-url-using-requestmapping-variable-uri/
My current mapping works well with id's as parameters. localhost:8080/user?id=1312321321
/*
* User
*/
#RequestMapping(method=RequestMethod.GET, value={"/user","/user/{id}"})
public ModelAndView profileDisplay(
HttpServletRequest request,
HttpServletResponse response,
#RequestParam(value="id", required=false) String id
) throws UnknownHostException, MongoException {
ServiceSerlvet.appendSesssion(request);
//get search ALL users
BasicDBObject searchQuery = new BasicDBObject();
searchQuery.put("_id", new ObjectId(id));
List<DBObject> searchResponse = PersonController.searchUsers(searchQuery);
//System.out.println("response from search user method: "+searchResponse);
return new ModelAndView("user", "people", searchResponse);
}
My web xml currently looks like this... its working but is it correct to write out various url mapping like this? I take it the * is a wild card to allow say /user/22222?
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>Spring3MVC</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.html</url-pattern>
<url-pattern>/gallery/*</url-pattern>
<url-pattern>/galleryupload/*</url-pattern>
<url-pattern>/delete/*</url-pattern>
<url-pattern>/edit/*</url-pattern>
<url-pattern>/search/*</url-pattern>
<url-pattern>/members/*</url-pattern>
<url-pattern>/profile/*</url-pattern>
<url-pattern>/messages/*</url-pattern>
<url-pattern>/index/*</url-pattern>
<url-pattern>/login/*</url-pattern>
<url-pattern>/logout/*</url-pattern>
<url-pattern>/register/*</url-pattern>
<url-pattern>/user/*</url-pattern>
<url-pattern>/jsoninterests/*</url-pattern>
<url-pattern>/jsonlocations/*</url-pattern>
<url-pattern>/jsonmembers/*</url-pattern>
<url-pattern>/jsonuniqueuser/*</url-pattern>
</servlet-mapping>
</web-app>
When I try and adapt my code to take just a name like this localhost:8080/user/john
it breaks - but I am unsure how to set the mapping in the web.xml, do I set the mapping like this in web.xml?
#RequestMapping(value="/user/{id}", method= RequestMethod.GET)
public ModelAndView profileDisplay(
#PathVariable(value="id") String id,
HttpServletRequest request,
HttpServletResponse response
) throws UnknownHostException, MongoException {
ServiceSerlvet.appendSesssion(request);
//get search ALL users
BasicDBObject searchQuery = new BasicDBObject();
searchQuery.put("_id", new ObjectId(id));
List<DBObject> searchResponse = PersonController.searchUsers(searchQuery);
//System.out.println("response from search user method: "+searchResponse);
return new ModelAndView("user", "people", searchResponse);
}
Normally I map every request to the dispatcher servlet in web.xml.
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
Then in your Controllers use #RequestMapping annotations to define the more granular mappings:
#RequestMapping("/user/{id}")
public ModelAndView profileDisplay(
HttpServletRequest request,
HttpServletResponse response,
#RequestParam(value="id", required=false) String id
) throws UnknownHostException, MongoException {
...
}
i'm new to JAX-RS. I'm trying to represent a List to a JSON array:
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("/getUsersResource/{userId}")
public List<AbstractResource> getUsersResources(#PathParam("userId") final String userId) {
if (userId == null) {
return null;
}
User user = null;
try {
user = userDao.getUserById(Integer.parseInt(userId));
} catch (NumberFormatException nfe) {
user = userDao.getUser(userId);
}
if (user == null) {
return null;
}
return abstractResourceDao.getUsersResources(null, user.userId);
}
When i execute this url i get:
{"exception": {"name": "WebApplicationException"}}
I annotated my AbstractResource class with the #XmlRootElement only and when i change the #Produces annotation parameter to
#Produces(MediaType.APPLICATION_XML)
I get the proper result. Here is my web.xml:
<servlet>
<servlet-name>REST Application</servlet-name>
<servlet-class>org.apache.wink.server.internal.servlet.RestServlet</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.balthaser.b3e.rest.RESTApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>REST Client</servlet-name>
<servlet-class>com.balthaser.b3e.rest.client.RESTClient</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>REST Client</servlet-name>
<url-pattern>/rest/index.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>REST Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Are there any additional requirements when producing JSON Arrays ?
Apache Wink is using json.org and jettison as a Json provider and they can't handle Java List properly.
So you need to configure Wink to use Jackson instead as a Json provider.
Here is the detail.
http://www.ibm.com/developerworks/java/library/wa-aj-jackson/index.html